From patchwork Tue Sep 19 13:08:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonatan Schlag X-Patchwork-Id: 7215 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) client-signature ECDSA (secp384r1)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4RqhnN1RtPz3ws3 for ; Tue, 19 Sep 2023 13:08:56 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) client-signature ECDSA (secp384r1)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4RqhnJ1Nmcz26f; Tue, 19 Sep 2023 13:08:52 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4RqhnH4JXWz303c; Tue, 19 Sep 2023 13:08:51 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4RqhnG0vlyz2xCr for ; Tue, 19 Sep 2023 13:08:50 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4Rqhn9355Lz19Q; Tue, 19 Sep 2023 13:08:45 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1695128929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4cWIq7PTvQC5QISdiGKjgOXj9XFNaL+hIxtXnouyxy4=; b=SarQw4ZgRuEJcRVLIWHwxE7WiAEliEJ8SAxRU2/D9a9I/SZ1cmiPAwV7xdpBRK0LYkYA/2 ZZ20LtWRn2hxmIDw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1695128929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4cWIq7PTvQC5QISdiGKjgOXj9XFNaL+hIxtXnouyxy4=; b=QqG25hw5dorgqRQfqOqL80iiZSW38YwK7KrWmT+I9bMjdsSRQ75F/U44keIG//X0j4wuoR afpkmw9Yg0cfZe0sz/Fk1SUB44Oo6cHr6jIchVMNkCcMXnNExBwiM9exi1hP2N78la1z6e rkbVUDXd2MPOARXzoTsoXGq5L9qGyr5KQ1EZNH0nirLBn8BjMtEkls+6OMT6dVF6+NU+KO XGPjtO//WF1wDiK7zOZjO0k9iRoVeGet+xrzrA74KujJhoOeZajK2DusCHyJzn5vJ3YWWY KaE2MkjSL3ZBspRVlz8XKyPH4hhxRjO2+FnzAH9KM70euYFUlMp4Xe500TjpjQ== From: Jonatan Schlag To: development@lists.ipfire.org Subject: [PATCH] network: Update to latest upstream Date: Tue, 19 Sep 2023 13:08:19 +0000 Message-Id: <20230919130819.517404-1-jonatan.schlag@ipfire.org> MIME-Version: 1.0 X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" As there is not a new release we apply 300 something patches. Signed-off-by: Jonatan Schlag --- network/network.nm | 5 +- .../patches/0001-Bump-version-to-011.patch | 26 + ...Check-input-and-return-useful-errors.patch | 144 ++ .../0003-bridge-Fix-assertion-for-MTU.patch | 32 + ...rder-functions-into-the-common-order.patch | 127 ++ .../0005-bridge-Set-proper-defaults.patch | 78 + ...rder-arguments-in-alphabetical-order.patch | 46 + ...ge-Add-option-to-missing-stp-max-age.patch | 33 + .../patches/0008-Remove-unused-function.patch | 29 + ...ding-Validate-any-MAC-address-passed.patch | 33 + ...-ip-tunnel-Set-TTL-to-255-by-default.patch | 34 + ...-Add-some-generic-configuration-file.patch | 107 ++ ...c-routes-instead-of-doing-that-manua.patch | 146 ++ ...-configuration-when-network-is-initi.patch | 28 + .../0014-dns-Always-enable-EDNS0.patch | 32 + ...automatic-channel-selection-ACS-by-d.patch | 27 + ...llow-to-disable-DFS-in-configuration.patch | 102 ++ ...DFS-automatically-when-not-supported.patch | 99 + ...-ap-Add-CLI-to-set-channel-bandwidth.patch | 87 + ...ot-to-add-configuration-variables-to.patch | 29 + ...y-channel-bandwidth-to-configuration.patch | 109 ++ ...s-ap-Enable-ACS-only-for-ath-devices.patch | 117 ++ ...w-setting-the-wireless-environment-i.patch | 164 ++ ...3-hostapd-Remove-now-useless-comment.patch | 26 + ...Always-enable-Transmit-Power-Control.patch | 30 + ...025-hostapd-Set-default-WMM-settings.patch | 72 + ...-Kick-stations-that-are-too-far-away.patch | 27 + .../0027-hostapd-Always-qoute-SSID.patch | 34 + ...w-to-enable-disable-802.11w-Manageme.patch | 130 ++ ...network-Show-when-a-PHY-supports-ACS.patch | 26 + ...i_device_status_phy-to-functions.phy.patch | 112 ++ ...stapd-Dump-config-file-in-debug-mode.patch | 52 + ...matically-enable-all-supported-ciphe.patch | 519 ++++++ ...nable-WPA-authentication-with-SHA256.patch | 26 + ...ally-set-defaults-for-all-port-hooks.patch | 98 + ...oks-Import-zone-default-settings-too.patch | 176 ++ ...-Convert-HOOK_SETTINGS-into-an-array.patch | 628 +++++++ .../0037-settings-Some-code-refactoring.patch | 133 ++ ...38-ports-Drop-HOOK_SETTINGS-variable.patch | 239 +++ ...multiple-copies-of-the-same-function.patch | 162 ++ ...0-wireless-ap-Remove-support-for-WPA.patch | 58 + ...dd-support-for-WPA3-and-rewrite-WPA2.patch | 280 +++ ...-hotplug-rename-Drop-unused-variable.patch | 27 + ...WPA2-authentication-only-with-SHA256.patch | 29 + ...ireless-ap-Enable-802.11w-by-default.patch | 31 + ...t_bool-convenience-function-where-ev.patch | 100 + ...OOK_CONFIG_SETTINGS-to-HOOK_SETTINGS.patch | 196 ++ ...nabled-from-configuration-parameters.patch | 99 + ...dhcp-Fix-syntax-error-in-last-commit.patch | 30 + ...NIQUE-which-stops-us-from-creating-m.patch | 158 ++ ...k-that-secret-has-the-correct-length.patch | 105 ++ .../0051-Drop-old-locking-functions.patch | 235 +++ ...nnel-Enable-support-for-6in4-tunnels.patch | 26 + .../0053-lock-Cleanup-lock-files.patch | 37 + ...quire-MFP-for-SAE-when-it-is-enabled.patch | 45 + ...6-router-advertisement-configuration.patch | 117 ++ .../patches/0056-Drop-code-for-radvd.patch | 314 ++++ ...57-.gitignore-Ignore-vim-s-swp-files.patch | 25 + ...ke-sure-the-daemon-is-always-running.patch | 73 + .../0059-configure-Require-asciidoc.patch | 28 + .../0060-man-Add-test-page-for-asciidoc.patch | 94 + ...idoc-to-generate-HTML-pages-directly.patch | 86 + ...-man-Add-asciidoc-configuration-file.patch | 62 + ...t-network-8-from-docbook-to-asciidoc.patch | 503 +++++ ...-Convert-network-color-8-to-asciidoc.patch | 152 ++ network/patches/0065-man-Drop-test-page.patch | 44 + .../0066-man-network-color-Add-synopsis.patch | 32 + ...onvert-firewall-settings-to-asciidoc.patch | 409 +++++ ...rt-network-description-8-to-asciidoc.patch | 144 ++ ...Convert-network-device-8-to-asciidoc.patch | 254 +++ ...n-Convert-network-dhcp-8-to-asciidoc.patch | 217 +++ ...ert-network-dns-server-8-to-asciidoc.patch | 306 ++++ ...ork-performance-tuning-8-to-asciidoc.patch | 135 ++ ...n-Convert-network-port-8-to-asciidoc.patch | 370 ++++ ...ng-network-quick-start-8-to-asciidoc.patch | 275 +++ ...5-man-Use-include-for-color-commands.patch | 55 + ...an-Drop-old-network-color-8-man-page.patch | 72 + .../patches/0077-man-Fix-page-headers.patch | 38 + ...-Convert-network-route-8-to-asciidoc.patch | 157 ++ .../0079-.gitignore-Ignore-DS_Store.patch | 26 + ...t-network-route-static-8-to-asciidoc.patch | 280 +++ ...nvert-network-settings-8-to-asciidoc.patch | 190 ++ ...an-Convert-network-vpn-8-to-asciidoc.patch | 135 ++ ...ork-vpn-security-policies-8-to-ascii.patch | 453 +++++ ...n-Convert-network-zone-8-to-asciidoc.patch | 375 ++++ ...rt-network-zone-bridge-8-to-asciidoc.patch | 255 +++ ...ork-zone-config-pppoe-server-8-to-as.patch | 222 +++ ...network-zone-ip-tunnel-8-to-asciidoc.patch | 184 ++ ...ert-network-zone-modem-8-to-asciidoc.patch | 329 ++++ ...ert-network-zone-pppoe-8-to-asciidoc.patch | 266 +++ ...-network-zone-wireless-8-to-asciidoc.patch | 167 ++ .../patches/0091-man-Cleanup-XML-files.patch | 43 + .../0092-man-Make-distcheck-happy.patch | 54 + ...man-Include-include-files-in-tarball.patch | 28 + ...94-man-network-route-static-Fix-name.patch | 26 + ...-Add-target-to-upload-HTML-man-pages.patch | 28 + ...ate-HTML-documentation-in-normal-bui.patch | 29 + .../0097-man-Fix-authorship-warnings.patch | 205 +++ ...tax-format-more-similar-across-files.patch | 583 ++++++ ...itable-function-to-determine-the-por.patch | 53 + ...t-hook-to-use-parse_cmdline-function.patch | 76 + ...-Validate-and-always-set-MAC-address.patch | 42 + ...nknown-command-line-parameters-are-b.patch | 29 + ...-Rename-PARENT_DEVICE-to-PARENT_PORT.patch | 102 ++ ...rent-device-exists-before-bringing-i.patch | 35 + .../0105-vlan-Simplify-vlan_remove.patch | 32 + .../0106-vlan-Refactor-vlan_create.patch | 146 ++ ...lan-Create-partent-port-if-necessary.patch | 30 + .../0108-vlan-Drop-ebtables-stuff.patch | 49 + .../patches/0109-vlan-Rename-tag-to-id.patch | 159 ++ network/patches/0110-vlan-Validate-ID.patch | 110 ++ ...hich-will-stop-the-program-immediate.patch | 48 + ...12-vlan-Add-support-for-802.1ad-QinQ.patch | 139 ++ ...ry-to-start-Bird-during-boot-process.patch | 57 + ...-Break-when-asciidoc-cannot-be-found.patch | 27 + .../0115-Fix-creating-new-configs.patch | 29 + .../0116-inetcalc-Fix-compiler-warnings.patch | 30 + ...p-separate-scripts-for-IPv6-and-IPv4.patch | 70 + ...stemd-Remove-double-firewall-scripts.patch | 76 + ...ewall-Add-init-action-to-main-script.patch | 54 + ...ll-Drop-initialisation-helper-script.patch | 79 + ...ert-firewall-Disable-PMTU-by-default.patch | 28 + ...irewall-Fix-reading-writing-settings.patch | 147 ++ ...rewall-config-command-in-favour-of-f.patch | 80 + ...attempt-DFS-when-reg-domain-is-set-t.patch | 30 + ...ce-when-needed-and-not-already-runni.patch | 42 + ...unnel-Support-setting-MTU-on-tunnels.patch | 60 + ...firewall-Fix-generating-systemd-file.patch | 33 + ...8-Make-generating-man-pages-optional.patch | 69 + ...-Add-documentation-for-the-IPsec-VPN.patch | 135 ++ ...130-Makefile-Add-network-vpn-ipsec-8.patch | 25 + ...icies-performance-Remove-CBC-ciphers.patch | 23 + .../0132-IPsec-Add-support-for-Curve448.patch | 65 + network/patches/0133-Disable-copybreak.patch | 112 ++ .../0134-configure-Check-for-libsystemd.patch | 25 + ...akefile-Add-scaffolding-for-networkd.patch | 93 + .../0136-networkd-Link-against-systemd.patch | 34 + ...Tell-systemd-about-the-daemon-status.patch | 47 + ...etworkd-Create-a-simple-daemon-class.patch | 170 ++ .../0139-networkd-Create-an-event-loop.patch | 147 ++ ...networkd-Enable-the-service-watchdog.patch | 31 + ...etworkd-Add-some-very-simple-logging.patch | 104 ++ ...workd-Register-SIGTERM-SIGINT-SIGHUP.patch | 90 + ...Add-scaffolding-to-reload-the-daemon.patch | 93 + ...-system-extensions-to-define-_GNU_SO.patch | 27 + ...d-Add-scaffolding-to-connect-to-dbus.patch | 255 +++ ...d-Add-scaffolding-for-config-objects.patch | 131 ++ ...ffolding-to-read-configuration-files.patch | 94 + ...plement-setting-configuration-values.patch | 283 +++ ...plement-reading-configuration-values.patch | 55 + ...mplement-writing-configuration-files.patch | 79 + ...etworkd-Read-main-configuration-file.patch | 54 + ...onfiguration-path-from-build-scripts.patch | 41 + ...3-networkd-Add-scaffolding-for-zones.patch | 192 ++ ...networkd-Install-a-dbus-service-file.patch | 82 + .../0155-networkd-Install-a-dbus-policy.patch | 87 + ...onfigure-Tidy-up-dbus-path-detection.patch | 53 + ...on-sensical-CFLAGS-and-add-more-warn.patch | 77 + ...ork-Fix-prototype-of-network_version.patch | 26 + ...stemd-notifications-into-daemon-obje.patch | 104 ++ ...Fix-incorrect-name-on-IPsec-man-page.patch | 45 + ...Install-some-simple-PolicyKit-policy.patch | 94 + ...nction-when-we-are-connected-to-dbus.patch | 51 + ...workd-Install-a-systemd-service-file.patch | 116 ++ ...lly-implement-bus-handler-for-Reload.patch | 32 + ...d-Asynchronously-register-to-the-bus.patch | 28 + ...Split-flushing-all-entries-into-a-fu.patch | 71 + ...config-read-functions-to-not-create-.patch | 70 + ...he-path-with-the-configuration-objec.patch | 200 ++ ...ry-to-read-configuration-automatical.patch | 137 ++ ...kd-Read-all-zones-from-configuration.patch | 201 ++ ...ate-a-unified-function-to-register-a.patch | 128 ++ ...a-dummy-bus-implementation-for-zones.patch | 99 + ...emon-to-all-functions-called-by-the-.patch | 66 + ...kd-Move-zone-list-into-an-own-object.patch | 493 +++++ ...plement-enumerating-zones-on-the-bus.patch | 238 +++ ...zone-when-it-is-being-accessed-by-it.patch | 159 ++ ...aemon-bus-implementation-into-a-sepa.patch | 175 ++ ...d-a-test-bus-property-to-set-the-MTU.patch | 201 ++ .../0179-networkd-Connect-to-udev.patch | 203 +++ ...-to-a-non-privileged-user-right-away.patch | 105 ++ ...l-capabilities-except-a-few-we-would.patch | 195 ++ ...ct-to-the-kernel-s-netlink-interface.patch | 95 + ...183-networkd-Link-against-libnetwork.patch | 25 + .../0184-networkd-Add-a-link-object.patch | 145 ++ ...5-networkd-Add-a-container-for-links.patch | 303 +++ ...workd-Enumerate-all-links-on-startup.patch | 172 ++ ...ate-a-link-object-for-each-interface.patch | 362 ++++ ...workd-Only-add-link-if-we-created-it.patch | 38 + .../0189-networkd-Import-interface-name.patch | 106 ++ .../patches/0190-networkd-Read-link-MTU.patch | 96 + ...Actually-return-entry-instead-of-fre.patch | 27 + ...Implement-reading-configuration-file.patch | 139 ++ ...3-networkd-Add-scaffolding-for-ports.patch | 159 ++ .../0194-networkd-Add-port-container.patch | 240 +++ ...-networkd-Enumerate-ports-on-startup.patch | 247 +++ ...erform-port-setup-from-configuration.patch | 147 ++ ...-Ethernet-address-from-configuration.patch | 145 ++ ...e-a-random-Ethernet-address-for-port.patch | 93 + ...ce-address-flags-for-better-readabil.patch | 43 + ...f-Ethernet-addresses-from-config-are.patch | 46 + ...0201-networkd-Export-ports-over-dbus.patch | 347 ++++ ...-Fix-buffer-to-Ethernet-address-stri.patch | 27 + ...ts-Export-Ethernet-address-over-dbus.patch | 102 ++ ...hod-to-fetch-corresponding-link-to-p.patch | 201 ++ ...e-typedef-to-keep-type-names-shorter.patch | 1617 +++++++++++++++++ ...re-a-reference-to-the-daemon-in-zone.patch | 180 ++ ...-networkd-Refactor-enumerating-zones.patch | 231 +++ ...-configuration-when-the-daemon-exits.patch | 239 +++ .../0209-networkd-Store-any-flags.patch | 69 + .../0210-networkd-Store-operstate-too.patch | 59 + ...ction-to-check-whether-a-link-has-a-.patch | 96 + ...hods-to-check-zones-ports-for-carrie.patch | 92 + .../0213-networkd-Log-to-journald.patch | 137 ++ ...-networkd-Install-in-usr-lib-network.patch | 49 + ...5-networkctl-Create-some-scaffolding.patch | 94 + ...networkctl-Connect-to-the-system-bus.patch | 45 + ...-Add-some-help-and-version-arguments.patch | 94 + ...Implement-a-basic-command-dispatcher.patch | 172 ++ ...orkd-Implement-ListZones-bus-command.patch | 169 ++ ...tworkctl-Implement-zone-list-command.patch | 188 ++ ...1-networkd-Fix-finding-links-by-name.patch | 56 + ...-Keep-a-permanent-reference-to-links.patch | 81 + ...-Keep-a-permanent-reference-to-links.patch | 89 + ...Add-functions-to-handle-boolean-valu.patch | 63 + ...reconfigure-all-ports-and-zones-on-s.patch | 210 +++ ...26-networkd-Implement-deleting-links.patch | 147 ++ ...ically-reference-dereference-links-t.patch | 368 ++++ ...reate-dummy-function-to-create-links.patch | 46 + ...mon-Correctly-store-reference-to-bus.patch | 157 ++ ...-stats-regulary-and-emit-them-on-dbu.patch | 667 +++++++ ...ut-buffer-size-when-formatting-MAC-a.patch | 27 + ...-if-there-is-garbage-after-intergers.patch | 42 + ...oid-adding-empty-line-after-integers.patch | 26 + ...-Require-type-to-be-set-at-all-times.patch | 133 ++ ...lement-reading-writing-VLAN-settings.patch | 287 +++ ...36-ports-Implement-destroying-a-port.patch | 193 ++ ...te-scaffolding-for-operations-struct.patch | 156 ++ ...ts-Move-VLAN-stuff-into-its-own-file.patch | 591 ++++++ ...-Implement-creating-links-from-ports.patch | 294 +++ ...-ops-struct-as-we-will-need-to-store.patch | 219 +++ ...ts-Implement-listing-ports-over-DBus.patch | 256 +++ ...n-code-handling-when-listing-ports-z.patch | 56 + ...ect-to-come-back-after-creating-link.patch | 32 + ...nfigure-MAC-address-when-creating-li.patch | 34 + ...rts-Show-message-when-creating-ports.patch | 26 + .../0246-ports-Constify-info-struct.patch | 80 + ...we-created-a-random-Ethernet-address.patch | 50 + ...-the-most-basic-supports-for-bonding.patch | 309 ++++ ...AN-settings-into-its-own-header-file.patch | 64 + ...tworkctl-Fix-typo-in-bus-method-name.patch | 26 + ...a-function-the-generally-fetches-the.patch | 163 ++ ...ompare-truthiness-case-insensitively.patch | 26 + .../0253-configure-Depend-on-JSON-C.patch | 46 + ...thod-to-export-port-information-as-J.patch | 302 +++ ...0255-networkctl-Fix-parsing-commands.patch | 52 + ...ment-dump-command-for-ports-which-sh.patch | 94 + ...s-to-easily-define-string-table-look.patch | 70 + ...s-VLAN-Implement-choosing-a-protocol.patch | 156 ++ ...e-parser-to-easier-read-write-config.patch | 716 ++++++++ ...bonding-Convert-mode-to-string-table.patch | 93 + ...ta-to-value-as-it-holds-a-reference-.patch | 221 +++ ...config-Add-data-pointer-to-callbacks.patch | 255 +++ ...Define-an-own-type-for-string-tables.patch | 75 + ...t-option-that-looks-up-string-tables.patch | 184 ++ .../0265-ports-Store-the-parent-name.patch | 32 + ...ts-VLAN-Make-all-constants-uppercase.patch | 49 + network/patches/0267-ports-Unify-type.patch | 440 +++++ ...s-Move-VLAN-constants-to-VLAN-header.patch | 46 + .../0269-ports-Drop-UNKNOWN-type.patch | 48 + ...lement-scaffolding-for-configuration.patch | 74 + ...71-ports-VLAN-Validate-configuration.patch | 53 + ...rash-when-a-port-could-not-be-loaded.patch | 40 + ...functions-return-negative-values-on-.patch | 33 + ...etworkd-Parse-command-line-arguments.patch | 132 ++ ...nfig-directory-and-keep-a-handle-to-.patch | 163 ++ ...old-a-file-descriptor-instead-of-DIR.patch | 99 + ...tworkd-Add-a-simple-test-environment.patch | 197 ++ ...nk-to-show-the-status-of-the-environ.patch | 48 + ...minate-after-showing-help-or-version.patch | 64 + ...ient-if-networkd-does-not-want-to-te.patch | 84 + ...etworkd-as-root-in-its-own-namespace.patch | 26 + ...282-ports-Refactor-enumerating-ports.patch | 636 +++++++ ...st-that-creates-two-dummy-interfaces.patch | 67 + ...84-tests-Always-dump-the-environment.patch | 47 + ...re-information-from-test-environment.patch | 26 + ...ts-bonding-Use-correct-enum-for-mode.patch | 38 + .../0287-networkd-json-Include-string.h.patch | 25 + .../0288-ports-Add-support-for-VETH.patch | 228 +++ .../0289-config-Add-string-buffer-type.patch | 264 +++ .../0290-networkctl-Add-color-functions.patch | 176 ++ ...l-Move-describe-into-an-own-function.patch | 106 ++ ...-Implement-scaffolding-to-show-ports.patch | 145 ++ ...-ports-Add-link-stuff-to-JSON-output.patch | 82 + ...link-Add-device-stuff-to-JSON-output.patch | 185 ++ ...lding-for-physical-Ethernet-interfac.patch | 246 +++ .../0296-logging-Add-WARNING-log-level.patch | 25 + ...etworkd-Handle-any-uevents-for-links.patch | 148 ++ ...e-udev-device-when-links-are-created.patch | 83 + ...p-uevent-when-the-device-is-renaming.patch | 60 + ...nt-smarter-handling-of-the-configura.patch | 951 ++++++++++ ...ones-Move-struct-nw_zone-into-header.patch | 115 ++ ...Drop-unused-configuration-file-paths.patch | 40 + network/patches/0303-util-Drop-nw_ftw.patch | 77 + ...4-Makefile-Fix-typo-in-localstatedir.patch | 26 + network/patches/network-fix-logdir-path.patch | 23 - 306 files changed, 40819 insertions(+), 24 deletions(-) create mode 100644 network/patches/0001-Bump-version-to-011.patch create mode 100644 network/patches/0002-bridge-Check-input-and-return-useful-errors.patch create mode 100644 network/patches/0003-bridge-Fix-assertion-for-MTU.patch create mode 100644 network/patches/0004-bridge-Reorder-functions-into-the-common-order.patch create mode 100644 network/patches/0005-bridge-Set-proper-defaults.patch create mode 100644 network/patches/0006-bridge-Order-arguments-in-alphabetical-order.patch create mode 100644 network/patches/0007-bridge-Add-option-to-missing-stp-max-age.patch create mode 100644 network/patches/0008-Remove-unused-function.patch create mode 100644 network/patches/0009-bonding-Validate-any-MAC-address-passed.patch create mode 100644 network/patches/0010-ip-tunnel-Set-TTL-to-255-by-default.patch create mode 100644 network/patches/0011-bird-Add-some-generic-configuration-file.patch create mode 100644 network/patches/0012-bird-Apply-static-routes-instead-of-doing-that-manua.patch create mode 100644 network/patches/0013-bird-Re-generate-configuration-when-network-is-initi.patch create mode 100644 network/patches/0014-dns-Always-enable-EDNS0.patch create mode 100644 network/patches/0015-wireless-ap-Use-automatic-channel-selection-ACS-by-d.patch create mode 100644 network/patches/0016-wireless-ap-Allow-to-disable-DFS-in-configuration.patch create mode 100644 network/patches/0017-hostapd-Disable-DFS-automatically-when-not-supported.patch create mode 100644 network/patches/0018-wireless-ap-Add-CLI-to-set-channel-bandwidth.patch create mode 100644 network/patches/0019-wireless-ap-Forgot-to-add-configuration-variables-to.patch create mode 100644 network/patches/0020-hostapd-Apply-channel-bandwidth-to-configuration.patch create mode 100644 network/patches/0021-wireless-ap-Enable-ACS-only-for-ath-devices.patch create mode 100644 network/patches/0022-wireless-ap-Allow-setting-the-wireless-environment-i.patch create mode 100644 network/patches/0023-hostapd-Remove-now-useless-comment.patch create mode 100644 network/patches/0024-hostapd-Always-enable-Transmit-Power-Control.patch create mode 100644 network/patches/0025-hostapd-Set-default-WMM-settings.patch create mode 100644 network/patches/0026-hostapd-Kick-stations-that-are-too-far-away.patch create mode 100644 network/patches/0027-hostapd-Always-qoute-SSID.patch create mode 100644 network/patches/0028-wireless-ap-Allow-to-enable-disable-802.11w-Manageme.patch create mode 100644 network/patches/0029-network-Show-when-a-PHY-supports-ACS.patch create mode 100644 network/patches/0030-Move-cli_device_status_phy-to-functions.phy.patch create mode 100644 network/patches/0031-hostapd-Dump-config-file-in-debug-mode.patch create mode 100644 network/patches/0032-wireless-ap-Automatically-enable-all-supported-ciphe.patch create mode 100644 network/patches/0033-hostapd-Enable-WPA-authentication-with-SHA256.patch create mode 100644 network/patches/0034-hooks-Automatically-set-defaults-for-all-port-hooks.patch create mode 100644 network/patches/0035-hooks-Import-zone-default-settings-too.patch create mode 100644 network/patches/0036-Convert-HOOK_SETTINGS-into-an-array.patch create mode 100644 network/patches/0037-settings-Some-code-refactoring.patch create mode 100644 network/patches/0038-ports-Drop-HOOK_SETTINGS-variable.patch create mode 100644 network/patches/0039-hotplug-Remove-multiple-copies-of-the-same-function.patch create mode 100644 network/patches/0040-wireless-ap-Remove-support-for-WPA.patch create mode 100644 network/patches/0041-wireless-ap-Add-support-for-WPA3-and-rewrite-WPA2.patch create mode 100644 network/patches/0042-hotplug-rename-Drop-unused-variable.patch create mode 100644 network/patches/0043-hostapd-Allow-WPA2-authentication-only-with-SHA256.patch create mode 100644 network/patches/0044-wireless-ap-Enable-802.11w-by-default.patch create mode 100644 network/patches/0045-hooks-Use-cli_get_bool-convenience-function-where-ev.patch create mode 100644 network/patches/0046-hook-Rename-HOOK_CONFIG_SETTINGS-to-HOOK_SETTINGS.patch create mode 100644 network/patches/0047-dhcp-Rename-enabled-from-configuration-parameters.patch create mode 100644 network/patches/0048-dhcp-Fix-syntax-error-in-last-commit.patch create mode 100644 network/patches/0049-hooks-Add-HOOK_UNIQUE-which-stops-us-from-creating-m.patch create mode 100644 network/patches/0050-wireless-ap-Check-that-secret-has-the-correct-length.patch create mode 100644 network/patches/0051-Drop-old-locking-functions.patch create mode 100644 network/patches/0052-ip-tunnel-Enable-support-for-6in4-tunnels.patch create mode 100644 network/patches/0053-lock-Cleanup-lock-files.patch create mode 100644 network/patches/0054-hostapd-Require-MFP-for-SAE-when-it-is-enabled.patch create mode 100644 network/patches/0055-bird-Write-IPv6-router-advertisement-configuration.patch create mode 100644 network/patches/0056-Drop-code-for-radvd.patch create mode 100644 network/patches/0057-.gitignore-Ignore-vim-s-swp-files.patch create mode 100644 network/patches/0058-bird-Make-sure-the-daemon-is-always-running.patch create mode 100644 network/patches/0059-configure-Require-asciidoc.patch create mode 100644 network/patches/0060-man-Add-test-page-for-asciidoc.patch create mode 100644 network/patches/0061-man-Use-asciidoc-to-generate-HTML-pages-directly.patch create mode 100644 network/patches/0062-man-Add-asciidoc-configuration-file.patch create mode 100644 network/patches/0063-man-Convert-network-8-from-docbook-to-asciidoc.patch create mode 100644 network/patches/0064-man-Convert-network-color-8-to-asciidoc.patch create mode 100644 network/patches/0065-man-Drop-test-page.patch create mode 100644 network/patches/0066-man-network-color-Add-synopsis.patch create mode 100644 network/patches/0067-man-Convert-firewall-settings-to-asciidoc.patch create mode 100644 network/patches/0068-man-Convert-network-description-8-to-asciidoc.patch create mode 100644 network/patches/0069-man-Convert-network-device-8-to-asciidoc.patch create mode 100644 network/patches/0070-man-Convert-network-dhcp-8-to-asciidoc.patch create mode 100644 network/patches/0071-man-Convert-network-dns-server-8-to-asciidoc.patch create mode 100644 network/patches/0072-man-Convert-network-performance-tuning-8-to-asciidoc.patch create mode 100644 network/patches/0073-man-Convert-network-port-8-to-asciidoc.patch create mode 100644 network/patches/0074-man-Converting-network-quick-start-8-to-asciidoc.patch create mode 100644 network/patches/0075-man-Use-include-for-color-commands.patch create mode 100644 network/patches/0076-man-Drop-old-network-color-8-man-page.patch create mode 100644 network/patches/0077-man-Fix-page-headers.patch create mode 100644 network/patches/0078-man-Convert-network-route-8-to-asciidoc.patch create mode 100644 network/patches/0079-.gitignore-Ignore-DS_Store.patch create mode 100644 network/patches/0080-man-Convert-network-route-static-8-to-asciidoc.patch create mode 100644 network/patches/0081-man-Convert-network-settings-8-to-asciidoc.patch create mode 100644 network/patches/0082-man-Convert-network-vpn-8-to-asciidoc.patch create mode 100644 network/patches/0083-man-Convert-network-vpn-security-policies-8-to-ascii.patch create mode 100644 network/patches/0084-man-Convert-network-zone-8-to-asciidoc.patch create mode 100644 network/patches/0085-man-Convert-network-zone-bridge-8-to-asciidoc.patch create mode 100644 network/patches/0086-man-Convert-network-zone-config-pppoe-server-8-to-as.patch create mode 100644 network/patches/0087-man-Convert-network-zone-ip-tunnel-8-to-asciidoc.patch create mode 100644 network/patches/0088-man-Convert-network-zone-modem-8-to-asciidoc.patch create mode 100644 network/patches/0089-man-Convert-network-zone-pppoe-8-to-asciidoc.patch create mode 100644 network/patches/0090-man-Convert-network-zone-wireless-8-to-asciidoc.patch create mode 100644 network/patches/0091-man-Cleanup-XML-files.patch create mode 100644 network/patches/0092-man-Make-distcheck-happy.patch create mode 100644 network/patches/0093-man-Include-include-files-in-tarball.patch create mode 100644 network/patches/0094-man-network-route-static-Fix-name.patch create mode 100644 network/patches/0095-Makefile-Add-target-to-upload-HTML-man-pages.patch create mode 100644 network/patches/0096-man-Do-not-generate-HTML-documentation-in-normal-bui.patch create mode 100644 network/patches/0097-man-Fix-authorship-warnings.patch create mode 100644 network/patches/0098-man-Make-syntax-format-more-similar-across-files.patch create mode 100644 network/patches/0099-hooks-Add-overwritable-function-to-determine-the-por.patch create mode 100644 network/patches/0100-vlan-Convert-hook-to-use-parse_cmdline-function.patch create mode 100644 network/patches/0101-vlan-Validate-and-always-set-MAC-address.patch create mode 100644 network/patches/0102-vlan-Fail-when-unknown-command-line-parameters-are-b.patch create mode 100644 network/patches/0103-vlan-Rename-PARENT_DEVICE-to-PARENT_PORT.patch create mode 100644 network/patches/0104-vlan-Check-if-parent-device-exists-before-bringing-i.patch create mode 100644 network/patches/0105-vlan-Simplify-vlan_remove.patch create mode 100644 network/patches/0106-vlan-Refactor-vlan_create.patch create mode 100644 network/patches/0107-vlan-Create-partent-port-if-necessary.patch create mode 100644 network/patches/0108-vlan-Drop-ebtables-stuff.patch create mode 100644 network/patches/0109-vlan-Rename-tag-to-id.patch create mode 100644 network/patches/0110-vlan-Validate-ID.patch create mode 100644 network/patches/0111-util-Add-abort-which-will-stop-the-program-immediate.patch create mode 100644 network/patches/0112-vlan-Add-support-for-802.1ad-QinQ.patch create mode 100644 network/patches/0113-Do-not-try-to-start-Bird-during-boot-process.patch create mode 100644 network/patches/0114-configure-Break-when-asciidoc-cannot-be-found.patch create mode 100644 network/patches/0115-Fix-creating-new-configs.patch create mode 100644 network/patches/0116-inetcalc-Fix-compiler-warnings.patch create mode 100644 network/patches/0117-firewall-Drop-separate-scripts-for-IPv6-and-IPv4.patch create mode 100644 network/patches/0118-systemd-Remove-double-firewall-scripts.patch create mode 100644 network/patches/0119-firewall-Add-init-action-to-main-script.patch create mode 100644 network/patches/0120-firewall-Drop-initialisation-helper-script.patch create mode 100644 network/patches/0121-Revert-firewall-Disable-PMTU-by-default.patch create mode 100644 network/patches/0122-firewall-Fix-reading-writing-settings.patch create mode 100644 network/patches/0123-firewall-Drop-firewall-config-command-in-favour-of-f.patch create mode 100644 network/patches/0124-wireless-Do-not-attempt-DFS-when-reg-domain-is-set-t.patch create mode 100644 network/patches/0125-bird-Start-service-when-needed-and-not-already-runni.patch create mode 100644 network/patches/0126-ip-tunnel-Support-setting-MTU-on-tunnels.patch create mode 100644 network/patches/0127-firewall-Fix-generating-systemd-file.patch create mode 100644 network/patches/0128-Make-generating-man-pages-optional.patch create mode 100644 network/patches/0129-Add-documentation-for-the-IPsec-VPN.patch create mode 100644 network/patches/0130-Makefile-Add-network-vpn-ipsec-8.patch create mode 100644 network/patches/0131-security-policies-performance-Remove-CBC-ciphers.patch create mode 100644 network/patches/0132-IPsec-Add-support-for-Curve448.patch create mode 100644 network/patches/0133-Disable-copybreak.patch create mode 100644 network/patches/0134-configure-Check-for-libsystemd.patch create mode 100644 network/patches/0135-Makefile-Add-scaffolding-for-networkd.patch create mode 100644 network/patches/0136-networkd-Link-against-systemd.patch create mode 100644 network/patches/0137-networkd-Tell-systemd-about-the-daemon-status.patch create mode 100644 network/patches/0138-networkd-Create-a-simple-daemon-class.patch create mode 100644 network/patches/0139-networkd-Create-an-event-loop.patch create mode 100644 network/patches/0140-networkd-Enable-the-service-watchdog.patch create mode 100644 network/patches/0141-networkd-Add-some-very-simple-logging.patch create mode 100644 network/patches/0142-networkd-Register-SIGTERM-SIGINT-SIGHUP.patch create mode 100644 network/patches/0143-networkd-Add-scaffolding-to-reload-the-daemon.patch create mode 100644 network/patches/0144-configure-Enable-system-extensions-to-define-_GNU_SO.patch create mode 100644 network/patches/0145-networkd-Add-scaffolding-to-connect-to-dbus.patch create mode 100644 network/patches/0146-networkd-Add-scaffolding-for-config-objects.patch create mode 100644 network/patches/0147-networkd-Add-scaffolding-to-read-configuration-files.patch create mode 100644 network/patches/0148-networkd-Implement-setting-configuration-values.patch create mode 100644 network/patches/0149-networkd-Implement-reading-configuration-values.patch create mode 100644 network/patches/0150-networkd-Implement-writing-configuration-files.patch create mode 100644 network/patches/0151-networkd-Read-main-configuration-file.patch create mode 100644 network/patches/0152-networkd-Set-configuration-path-from-build-scripts.patch create mode 100644 network/patches/0153-networkd-Add-scaffolding-for-zones.patch create mode 100644 network/patches/0154-networkd-Install-a-dbus-service-file.patch create mode 100644 network/patches/0155-networkd-Install-a-dbus-policy.patch create mode 100644 network/patches/0156-configure-Tidy-up-dbus-path-detection.patch create mode 100644 network/patches/0157-configure-Drop-non-sensical-CFLAGS-and-add-more-warn.patch create mode 100644 network/patches/0158-libnetwork-Fix-prototype-of-network_version.patch create mode 100644 network/patches/0159-networkd-Move-systemd-notifications-into-daemon-obje.patch create mode 100644 network/patches/0160-man-Fix-incorrect-name-on-IPsec-man-page.patch create mode 100644 network/patches/0161-networkd-Install-some-simple-PolicyKit-policy.patch create mode 100644 network/patches/0162-networkd-Call-function-when-we-are-connected-to-dbus.patch create mode 100644 network/patches/0163-networkd-Install-a-systemd-service-file.patch create mode 100644 network/patches/0164-networkd-Fully-implement-bus-handler-for-Reload.patch create mode 100644 network/patches/0165-networkd-Asynchronously-register-to-the-bus.patch create mode 100644 network/patches/0166-networkd-config-Split-flushing-all-entries-into-a-fu.patch create mode 100644 network/patches/0167-networkd-Change-config-read-functions-to-not-create-.patch create mode 100644 network/patches/0168-networkd-Store-the-path-with-the-configuration-objec.patch create mode 100644 network/patches/0169-networkd-zones-Try-to-read-configuration-automatical.patch create mode 100644 network/patches/0170-networkd-Read-all-zones-from-configuration.patch create mode 100644 network/patches/0171-networkd-bus-Create-a-unified-function-to-register-a.patch create mode 100644 network/patches/0172-networkd-Add-a-dummy-bus-implementation-for-zones.patch create mode 100644 network/patches/0173-networkd-Pass-daemon-to-all-functions-called-by-the-.patch create mode 100644 network/patches/0174-networkd-Move-zone-list-into-an-own-object.patch create mode 100644 network/patches/0175-networkd-Implement-enumerating-zones-on-the-bus.patch create mode 100644 network/patches/0176-networkd-Return-zone-when-it-is-being-accessed-by-it.patch create mode 100644 network/patches/0177-networkd-Split-daemon-bus-implementation-into-a-sepa.patch create mode 100644 network/patches/0178-networkd-Add-a-test-bus-property-to-set-the-MTU.patch create mode 100644 network/patches/0179-networkd-Connect-to-udev.patch create mode 100644 network/patches/0180-networkd-Change-to-a-non-privileged-user-right-away.patch create mode 100644 network/patches/0181-networkd-Drop-all-capabilities-except-a-few-we-would.patch create mode 100644 network/patches/0182-networkd-Connect-to-the-kernel-s-netlink-interface.patch create mode 100644 network/patches/0183-networkd-Link-against-libnetwork.patch create mode 100644 network/patches/0184-networkd-Add-a-link-object.patch create mode 100644 network/patches/0185-networkd-Add-a-container-for-links.patch create mode 100644 network/patches/0186-networkd-Enumerate-all-links-on-startup.patch create mode 100644 network/patches/0187-networkd-Create-a-link-object-for-each-interface.patch create mode 100644 network/patches/0188-networkd-Only-add-link-if-we-created-it.patch create mode 100644 network/patches/0189-networkd-Import-interface-name.patch create mode 100644 network/patches/0190-networkd-Read-link-MTU.patch create mode 100644 network/patches/0191-networkd-config-Actually-return-entry-instead-of-fre.patch create mode 100644 network/patches/0192-networkd-config-Implement-reading-configuration-file.patch create mode 100644 network/patches/0193-networkd-Add-scaffolding-for-ports.patch create mode 100644 network/patches/0194-networkd-Add-port-container.patch create mode 100644 network/patches/0195-networkd-Enumerate-ports-on-startup.patch create mode 100644 network/patches/0196-networkd-Perform-port-setup-from-configuration.patch create mode 100644 network/patches/0197-networkd-Read-Ethernet-address-from-configuration.patch create mode 100644 network/patches/0198-networkd-Generate-a-random-Ethernet-address-for-port.patch create mode 100644 network/patches/0199-networkd-Introduce-address-flags-for-better-readabil.patch create mode 100644 network/patches/0200-networkd-Check-if-Ethernet-addresses-from-config-are.patch create mode 100644 network/patches/0201-networkd-Export-ports-over-dbus.patch create mode 100644 network/patches/0202-networkd-address-Fix-buffer-to-Ethernet-address-stri.patch create mode 100644 network/patches/0203-networkd-ports-Export-Ethernet-address-over-dbus.patch create mode 100644 network/patches/0204-networkd-Add-method-to-fetch-corresponding-link-to-p.patch create mode 100644 network/patches/0205-networkd-Use-typedef-to-keep-type-names-shorter.patch create mode 100644 network/patches/0206-networkd-Store-a-reference-to-the-daemon-in-zone.patch create mode 100644 network/patches/0207-networkd-Refactor-enumerating-zones.patch create mode 100644 network/patches/0208-networkd-Save-configuration-when-the-daemon-exits.patch create mode 100644 network/patches/0209-networkd-Store-any-flags.patch create mode 100644 network/patches/0210-networkd-Store-operstate-too.patch create mode 100644 network/patches/0211-networkd-Add-function-to-check-whether-a-link-has-a-.patch create mode 100644 network/patches/0212-networkd-Add-methods-to-check-zones-ports-for-carrie.patch create mode 100644 network/patches/0213-networkd-Log-to-journald.patch create mode 100644 network/patches/0214-networkd-Install-in-usr-lib-network.patch create mode 100644 network/patches/0215-networkctl-Create-some-scaffolding.patch create mode 100644 network/patches/0216-networkctl-Connect-to-the-system-bus.patch create mode 100644 network/patches/0217-networkctl-Add-some-help-and-version-arguments.patch create mode 100644 network/patches/0218-networkctl-Implement-a-basic-command-dispatcher.patch create mode 100644 network/patches/0219-networkd-Implement-ListZones-bus-command.patch create mode 100644 network/patches/0220-networkctl-Implement-zone-list-command.patch create mode 100644 network/patches/0221-networkd-Fix-finding-links-by-name.patch create mode 100644 network/patches/0222-networkd-ports-Keep-a-permanent-reference-to-links.patch create mode 100644 network/patches/0223-networkd-zones-Keep-a-permanent-reference-to-links.patch create mode 100644 network/patches/0224-networkd-config-Add-functions-to-handle-boolean-valu.patch create mode 100644 network/patches/0225-networkd-Try-to-reconfigure-all-ports-and-zones-on-s.patch create mode 100644 network/patches/0226-networkd-Implement-deleting-links.patch create mode 100644 network/patches/0227-networkd-Automatically-reference-dereference-links-t.patch create mode 100644 network/patches/0228-networkd-ports-Create-dummy-function-to-create-links.patch create mode 100644 network/patches/0229-networkd-daemon-Correctly-store-reference-to-bus.patch create mode 100644 network/patches/0230-networkd-Collect-stats-regulary-and-emit-them-on-dbu.patch create mode 100644 network/patches/0231-address-Fix-output-buffer-size-when-formatting-MAC-a.patch create mode 100644 network/patches/0232-config-Fail-if-there-is-garbage-after-intergers.patch create mode 100644 network/patches/0233-config-Avoid-adding-empty-line-after-integers.patch create mode 100644 network/patches/0234-ports-Require-type-to-be-set-at-all-times.patch create mode 100644 network/patches/0235-port-Implement-reading-writing-VLAN-settings.patch create mode 100644 network/patches/0236-ports-Implement-destroying-a-port.patch create mode 100644 network/patches/0237-ports-Create-scaffolding-for-operations-struct.patch create mode 100644 network/patches/0238-ports-Move-VLAN-stuff-into-its-own-file.patch create mode 100644 network/patches/0239-ports-Implement-creating-links-from-ports.patch create mode 100644 network/patches/0240-ports-Rename-the-ops-struct-as-we-will-need-to-store.patch create mode 100644 network/patches/0241-ports-Implement-listing-ports-over-DBus.patch create mode 100644 network/patches/0242-daemon-Fix-return-code-handling-when-listing-ports-z.patch create mode 100644 network/patches/0243-ports-Do-not-expect-to-come-back-after-creating-link.patch create mode 100644 network/patches/0244-ports-Set-the-configure-MAC-address-when-creating-li.patch create mode 100644 network/patches/0245-ports-Show-message-when-creating-ports.patch create mode 100644 network/patches/0246-ports-Constify-info-struct.patch create mode 100644 network/patches/0247-ports-Log-when-we-created-a-random-Ethernet-address.patch create mode 100644 network/patches/0248-ports-Add-the-most-basic-supports-for-bonding.patch create mode 100644 network/patches/0249-ports-Move-VLAN-settings-into-its-own-header-file.patch create mode 100644 network/patches/0250-networkctl-Fix-typo-in-bus-method-name.patch create mode 100644 network/patches/0251-ports-Implement-a-function-the-generally-fetches-the.patch create mode 100644 network/patches/0252-config-Compare-truthiness-case-insensitively.patch create mode 100644 network/patches/0253-configure-Depend-on-JSON-C.patch create mode 100644 network/patches/0254-ports-Add-bus-method-to-export-port-information-as-J.patch create mode 100644 network/patches/0255-networkctl-Fix-parsing-commands.patch create mode 100644 network/patches/0256-networkctl-Implement-dump-command-for-ports-which-sh.patch create mode 100644 network/patches/0257-string-Add-macros-to-easily-define-string-table-look.patch create mode 100644 network/patches/0258-ports-VLAN-Implement-choosing-a-protocol.patch create mode 100644 network/patches/0259-config-Extend-the-parser-to-easier-read-write-config.patch create mode 100644 network/patches/0260-ports-bonding-Convert-mode-to-string-table.patch create mode 100644 network/patches/0261-config-Rename-data-to-value-as-it-holds-a-reference-.patch create mode 100644 network/patches/0262-config-Add-data-pointer-to-callbacks.patch create mode 100644 network/patches/0263-string-Define-an-own-type-for-string-tables.patch create mode 100644 network/patches/0264-config-Implement-option-that-looks-up-string-tables.patch create mode 100644 network/patches/0265-ports-Store-the-parent-name.patch create mode 100644 network/patches/0266-ports-VLAN-Make-all-constants-uppercase.patch create mode 100644 network/patches/0267-ports-Unify-type.patch create mode 100644 network/patches/0268-ports-Move-VLAN-constants-to-VLAN-header.patch create mode 100644 network/patches/0269-ports-Drop-UNKNOWN-type.patch create mode 100644 network/patches/0270-ports-Implement-scaffolding-for-configuration.patch create mode 100644 network/patches/0271-ports-VLAN-Validate-configuration.patch create mode 100644 network/patches/0272-daemon-Don-t-crash-when-a-port-could-not-be-loaded.patch create mode 100644 network/patches/0273-string-Have-all-functions-return-negative-values-on-.patch create mode 100644 network/patches/0274-networkd-Parse-command-line-arguments.patch create mode 100644 network/patches/0275-networkd-Open-config-directory-and-keep-a-handle-to-.patch create mode 100644 network/patches/0276-networkd-Hold-a-file-descriptor-instead-of-DIR.patch create mode 100644 network/patches/0277-networkd-Add-a-simple-test-environment.patch create mode 100644 network/patches/0278-test-Run-ip-d-link-to-show-the-status-of-the-environ.patch create mode 100644 network/patches/0279-networkctl-Terminate-after-showing-help-or-version.patch create mode 100644 network/patches/0280-test-Be-less-patient-if-networkd-does-not-want-to-te.patch create mode 100644 network/patches/0281-test-Run-networkd-as-root-in-its-own-namespace.patch create mode 100644 network/patches/0282-ports-Refactor-enumerating-ports.patch create mode 100644 network/patches/0283-tests-Add-new-test-that-creates-two-dummy-interfaces.patch create mode 100644 network/patches/0284-tests-Always-dump-the-environment.patch create mode 100644 network/patches/0285-test-Collect-more-information-from-test-environment.patch create mode 100644 network/patches/0286-ports-bonding-Use-correct-enum-for-mode.patch create mode 100644 network/patches/0287-networkd-json-Include-string.h.patch create mode 100644 network/patches/0288-ports-Add-support-for-VETH.patch create mode 100644 network/patches/0289-config-Add-string-buffer-type.patch create mode 100644 network/patches/0290-networkctl-Add-color-functions.patch create mode 100644 network/patches/0291-networkctl-Move-describe-into-an-own-function.patch create mode 100644 network/patches/0292-networkctl-Implement-scaffolding-to-show-ports.patch create mode 100644 network/patches/0293-ports-Add-link-stuff-to-JSON-output.patch create mode 100644 network/patches/0294-link-Add-device-stuff-to-JSON-output.patch create mode 100644 network/patches/0295-ports-Add-scaffolding-for-physical-Ethernet-interfac.patch create mode 100644 network/patches/0296-logging-Add-WARNING-log-level.patch create mode 100644 network/patches/0297-networkd-Handle-any-uevents-for-links.patch create mode 100644 network/patches/0298-links-Initialize-udev-device-when-links-are-created.patch create mode 100644 network/patches/0299-link-Skip-uevent-when-the-device-is-renaming.patch create mode 100644 network/patches/0300-networkd-Implement-smarter-handling-of-the-configura.patch create mode 100644 network/patches/0301-zones-Move-struct-nw_zone-into-header.patch create mode 100644 network/patches/0302-Drop-unused-configuration-file-paths.patch create mode 100644 network/patches/0303-util-Drop-nw_ftw.patch create mode 100644 network/patches/0304-Makefile-Fix-typo-in-localstatedir.patch delete mode 100644 network/patches/network-fix-logdir-path.patch diff --git a/network/network.nm b/network/network.nm index 85a9d15b3..2df8135b2 100644 --- a/network/network.nm +++ b/network/network.nm @@ -5,7 +5,7 @@ name = network version = 010 -release = 5 +release = 6 maintainer = Michael Tremer groups = Base Networking/Tools @@ -24,9 +24,12 @@ source_dl = https://source.ipfire.org/releases/network/ build requires + asciidoc autoconf automake docbook-xsl + json-c-devel + libcap-devel libnl3-devel libxslt systemd-devel diff --git a/network/patches/0001-Bump-version-to-011.patch b/network/patches/0001-Bump-version-to-011.patch new file mode 100644 index 000000000..2b9422662 --- /dev/null +++ b/network/patches/0001-Bump-version-to-011.patch @@ -0,0 +1,26 @@ +From af91a344198a1f3c47dc18905870818a0758d427 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 21:55:51 +0100 +Subject: [PATCH 001/304] Bump version to 011 + +Signed-off-by: Michael Tremer +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 9baab31..08e9089 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -21,7 +21,7 @@ + AC_PREREQ([2.64]) + + AC_INIT([network], +- [010], ++ [011], + [info@ipfire.org], + [network], + [http://www.ipfire.org/]) +-- +2.39.2 + diff --git a/network/patches/0002-bridge-Check-input-and-return-useful-errors.patch b/network/patches/0002-bridge-Check-input-and-return-useful-errors.patch new file mode 100644 index 000000000..91cbdec60 --- /dev/null +++ b/network/patches/0002-bridge-Check-input-and-return-useful-errors.patch @@ -0,0 +1,144 @@ +From b99bbd83b94d380bd07dcace8fb0e95b76b01e9f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:13:22 +0200 +Subject: [PATCH 002/304] bridge: Check input and return useful errors + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/bridge | 80 +++++++++++++++++++++++++++++++++--------- + 1 file changed, 63 insertions(+), 17 deletions(-) + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 38b2b5f..838a513 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -23,13 +23,12 @@ + + HOOK_MANPAGE="network-zone-bridge" + +-HOOK_SETTINGS="HOOK STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE" +-HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MAC MTU" ++HOOK_SETTINGS="HOOK ADDRESS STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE" ++HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MTU" + + HOOK_PORT_SETTINGS="COST PRIORITY" + + # Default values +-MAC="" + MTU=1500 + STP="on" + STP_FORWARD_DELAY=0 +@@ -38,7 +37,9 @@ STP_MAXAGE=20 + STP_PRIORITY=512 + + hook_check_settings() { +- assert ismac MAC ++ assert ismac ADDRESS ++ ++ # Spanning Tree Protocol + assert isbool STP + assert isinteger STP_HELLO + assert isinteger STP_FORWARD_DELAY +@@ -49,33 +50,78 @@ hook_check_settings() { + hook_parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in ++ --address=*) ++ ADDRESS="$(cli_get_val "${1}")" ++ ++ if ! mac_is_valid "${ADDRESS}"; then ++ error "Invalid MAC address: ${ADDRESS}" ++ return ${EXIT_ERROR} ++ fi ++ ;; ++ ++ --mtu=*) ++ MTU="$(cli_get_val "${1}")" ++ ++ if ! mtu_is_valid "ethernet" "${MTU}"; then ++ error "Invalid MTU: ${MTU}" ++ return ${EXIT_ERROR} ++ fi ++ ;; ++ + --stp=*) +- STP=${1#--stp=} ++ STP="$(cli_get_val "${1}")" ++ ++ if enabled STP; then ++ STP="on" ++ elif disabled STP; then ++ STP="off" ++ else ++ error "Invalid value for STP: ${STP}" ++ return ${EXIT_ERROR} ++ fi + ;; ++ + --stp-hello=*) +- STP_HELLO=${1#--stp-hello=} ++ STP_HELLO="$(cli_get_val "${1}")" ++ ++ if ! isinteger STP_HELLO; then ++ error "Invalid STP hello time: ${STP_HELLO}" ++ return ${EXIT_ERROR} ++ fi + ;; ++ + --stp-forward-delay=*) +- STP_FORWARD_DELAY=${1#--stp-forward-delay=} ++ STP_FORWARD_DELAY="$(cli_get_val "${1}")" ++ ++ if ! isinteger STP_FORWARD_DELAY; then ++ error "Invalid STP forwarding delay: ${STP_FORWARD_DELAY}" ++ return ${EXIT_ERROR} ++ fi + ;; ++ + --stp-priority=*) +- STP_PRIORITY=${1#--stp-priority=} +- ;; +- --mtu=*) +- MTU=${1#--mtu=} +- ;; +- --mac=*) +- MAC=${1#--mac=} ++ STP_PRIORITY="$(cli_get_val "${1}")" ++ ++ if ! isinteger STP_PRIORITY; then ++ error "Invalid STP priority: ${STP_PRIORITY}" ++ return ${EXIT_ERROR} ++ fi + ;; ++ + *) +- warning "Ignoring unknown option '${1}'" ++ error "Unknown argument: ${1}" ++ return ${EXIT_ERROR} + ;; + esac + shift + done + + # Generate a random MAC address if the user passed no one +- isset MAC || MAC="$(mac_generate)" ++ if isset ADDRESS; then ++ ADDRESS="$(mac_generate)" ++ fi ++ ++ return ${EXIT_OK} + } + + hook_up() { +@@ -87,7 +133,7 @@ hook_up() { + # Create the bridge if it does not already exist. + if ! device_exists "${zone}"; then + bridge_create "${zone}" \ +- --address="${MAC}" \ ++ --address="${ADDRESS}" \ + --mtu="${MTU}" + fi + +-- +2.39.2 + diff --git a/network/patches/0003-bridge-Fix-assertion-for-MTU.patch b/network/patches/0003-bridge-Fix-assertion-for-MTU.patch new file mode 100644 index 000000000..ce712991d --- /dev/null +++ b/network/patches/0003-bridge-Fix-assertion-for-MTU.patch @@ -0,0 +1,32 @@ +From d95e2fdc65aeeca72ef326102f26727199b27b95 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:15:26 +0200 +Subject: [PATCH 003/304] bridge: Fix assertion for MTU + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/bridge | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 838a513..d610814 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -38,13 +38,13 @@ STP_PRIORITY=512 + + hook_check_settings() { + assert ismac ADDRESS ++ assert isset MTU && assert mtu_is_valid "ethernet" "${MTU}" + + # Spanning Tree Protocol + assert isbool STP + assert isinteger STP_HELLO + assert isinteger STP_FORWARD_DELAY + assert isinteger STP_PRIORITY +- assert isinteger MTU + } + + hook_parse_cmdline() { +-- +2.39.2 + diff --git a/network/patches/0004-bridge-Reorder-functions-into-the-common-order.patch b/network/patches/0004-bridge-Reorder-functions-into-the-common-order.patch new file mode 100644 index 000000000..d2a3d3810 --- /dev/null +++ b/network/patches/0004-bridge-Reorder-functions-into-the-common-order.patch @@ -0,0 +1,127 @@ +From 1fc4b3cac15c709b3a6f4a3171265a5cff793f47 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:17:30 +0200 +Subject: [PATCH 004/304] bridge: Reorder functions into the common order + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/bridge | 96 +++++++++++++++++++++--------------------- + 1 file changed, 49 insertions(+), 47 deletions(-) + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index d610814..fb81673 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -172,53 +172,6 @@ hook_up() { + exit ${EXIT_OK} + } + +-hook_hotplug() { +- local zone="${1}" +- assert isset zone +- +- case "$(hotplug_action)" in +- add) +- # Attach all ports when zone is coming up +- if hotplug_event_interface_is_zone "${zone}"; then +- # Bring up all ports +- local port +- for port in $(zone_get_ports "${zone}"); do +- log DEBUG "Trying to attach port ${port} to ${zone}" +- +- hook_port_up "${zone}" "${port}" +- done +- +- # Handle ports of this zone that have just been added +- elif hotplug_event_interface_is_port_of_zone "${zone}"; then +- # Attach the device if the parent bridge is up +- if zone_is_active "${zone}"; then +- hook_port_up "${zone}" "${INTERFACE}" +- fi +- fi +- ;; +- remove) +- if hotplug_event_interface_is_zone "${zone}"; then +- # Bring down/destroy all ports +- local port +- for port in $(zone_get_ports "${zone}"); do +- log DEBUG "Trying to detach port ${port} from ${zone}" +- +- hook_port_down "${zone}" "${port}" +- done +- +- # Handle ports of this zone that have just been removed +- elif hotplug_event_interface_is_port_of_zone "${zone}"; then +- hook_port_down "${zone}" "${INTERFACE}" +- fi +- ;; +- *) +- exit ${EXIT_NOT_HANDLED} +- ;; +- esac +- +- exit ${EXIT_OK} +-} +- + hook_down() { + local zone="${1}" + assert isset zone +@@ -294,6 +247,55 @@ hook_status() { + exit ${EXIT_OK} + } + ++hook_hotplug() { ++ local zone="${1}" ++ assert isset zone ++ ++ case "$(hotplug_action)" in ++ add) ++ # Attach all ports when zone is coming up ++ if hotplug_event_interface_is_zone "${zone}"; then ++ # Bring up all ports ++ local port ++ for port in $(zone_get_ports "${zone}"); do ++ log DEBUG "Trying to attach port ${port} to ${zone}" ++ ++ hook_port_up "${zone}" "${port}" ++ done ++ ++ # Handle ports of this zone that have just been added ++ elif hotplug_event_interface_is_port_of_zone "${zone}"; then ++ # Attach the device if the parent bridge is up ++ if zone_is_active "${zone}"; then ++ hook_port_up "${zone}" "${INTERFACE}" ++ fi ++ fi ++ ;; ++ ++ remove) ++ if hotplug_event_interface_is_zone "${zone}"; then ++ # Bring down/destroy all ports ++ local port ++ for port in $(zone_get_ports "${zone}"); do ++ log DEBUG "Trying to detach port ${port} from ${zone}" ++ ++ hook_port_down "${zone}" "${port}" ++ done ++ ++ # Handle ports of this zone that have just been removed ++ elif hotplug_event_interface_is_port_of_zone "${zone}"; then ++ hook_port_down "${zone}" "${INTERFACE}" ++ fi ++ ;; ++ ++ *) ++ exit ${EXIT_NOT_HANDLED} ++ ;; ++ esac ++ ++ exit ${EXIT_OK} ++} ++ + hook_check_port_settings() { + if isset COST; then + assert isinteger COST +-- +2.39.2 + diff --git a/network/patches/0005-bridge-Set-proper-defaults.patch b/network/patches/0005-bridge-Set-proper-defaults.patch new file mode 100644 index 000000000..adbe32bea --- /dev/null +++ b/network/patches/0005-bridge-Set-proper-defaults.patch @@ -0,0 +1,78 @@ +From c259c985bc98ad89350f81b68db58925163a43eb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:29:25 +0200 +Subject: [PATCH 005/304] bridge: Set proper defaults + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hook | 12 ++++++++++++ + src/hooks/zones/bridge | 20 +++++++++++++------- + 2 files changed, 25 insertions(+), 7 deletions(-) + +diff --git a/src/functions/functions.hook b/src/functions/functions.hook +index ad51ad5..2f3ced0 100644 +--- a/src/functions/functions.hook ++++ b/src/functions/functions.hook +@@ -124,6 +124,18 @@ hook_help() { + exit $? + } + ++# Sets all settings in HOOK_SETTINGS to their DEFAULT_* values ++hook_set_defaults() { ++ local setting ++ for setting in ${HOOK_SETTINGS}; do ++ local default="DEFAULT_${setting}" ++ ++ if isset ${default}; then ++ assign "${setting}" "${!default}" ++ fi ++ done ++} ++ + config_get_hook() { + local config=${1} + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index fb81673..1144ba0 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -29,12 +29,10 @@ HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MTU" + HOOK_PORT_SETTINGS="COST PRIORITY" + + # Default values +-MTU=1500 +-STP="on" +-STP_FORWARD_DELAY=0 +-STP_HELLO=2 +-STP_MAXAGE=20 +-STP_PRIORITY=512 ++DEFAULT_STP_FORWARD_DELAY=0 ++DEFAULT_STP_HELLO=2 ++DEFAULT_STP_MAXAGE=20 ++DEFAULT_STP_PRIORITY=512 + + hook_check_settings() { + assert ismac ADDRESS +@@ -117,10 +115,18 @@ hook_parse_cmdline() { + done + + # Generate a random MAC address if the user passed no one +- if isset ADDRESS; then ++ if ! isset ADDRESS; then + ADDRESS="$(mac_generate)" + fi + ++ # Enable Spanning Tree Protocol by default ++ if ! isset STP; then ++ STP="on" ++ fi ++ ++ # Set all other defaults ++ hook_set_defaults ++ + return ${EXIT_OK} + } + +-- +2.39.2 + diff --git a/network/patches/0006-bridge-Order-arguments-in-alphabetical-order.patch b/network/patches/0006-bridge-Order-arguments-in-alphabetical-order.patch new file mode 100644 index 000000000..95f14cad5 --- /dev/null +++ b/network/patches/0006-bridge-Order-arguments-in-alphabetical-order.patch @@ -0,0 +1,46 @@ +From b76b7d88a5fc7271e9a16d4acb531cdfe45f3957 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:31:43 +0200 +Subject: [PATCH 006/304] bridge: Order arguments in alphabetical order + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/bridge | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 1144ba0..98aaef8 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -79,20 +79,20 @@ hook_parse_cmdline() { + fi + ;; + +- --stp-hello=*) +- STP_HELLO="$(cli_get_val "${1}")" ++ --stp-forward-delay=*) ++ STP_FORWARD_DELAY="$(cli_get_val "${1}")" + +- if ! isinteger STP_HELLO; then +- error "Invalid STP hello time: ${STP_HELLO}" ++ if ! isinteger STP_FORWARD_DELAY; then ++ error "Invalid STP forwarding delay: ${STP_FORWARD_DELAY}" + return ${EXIT_ERROR} + fi + ;; + +- --stp-forward-delay=*) +- STP_FORWARD_DELAY="$(cli_get_val "${1}")" ++ --stp-hello=*) ++ STP_HELLO="$(cli_get_val "${1}")" + +- if ! isinteger STP_FORWARD_DELAY; then +- error "Invalid STP forwarding delay: ${STP_FORWARD_DELAY}" ++ if ! isinteger STP_HELLO; then ++ error "Invalid STP hello time: ${STP_HELLO}" + return ${EXIT_ERROR} + fi + ;; +-- +2.39.2 + diff --git a/network/patches/0007-bridge-Add-option-to-missing-stp-max-age.patch b/network/patches/0007-bridge-Add-option-to-missing-stp-max-age.patch new file mode 100644 index 000000000..0a48d11c1 --- /dev/null +++ b/network/patches/0007-bridge-Add-option-to-missing-stp-max-age.patch @@ -0,0 +1,33 @@ +From 0f8d47058e6dedc5f20caf367a5296647ec950d1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Sep 2018 23:32:40 +0200 +Subject: [PATCH 007/304] bridge: Add option to missing --stp-max-age= + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/bridge | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 98aaef8..93a3a31 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -97,6 +97,15 @@ hook_parse_cmdline() { + fi + ;; + ++ --stp-max-age=*) ++ STP_MAXAGE="$(cli_get_val "${1}")" ++ ++ if ! isinteger STP_MAXAGE; then ++ error "Invalid STP max age: ${STP_MAXAGE}" ++ return ${EXIT_ERROR} ++ fi ++ ;; ++ + --stp-priority=*) + STP_PRIORITY="$(cli_get_val "${1}")" + +-- +2.39.2 + diff --git a/network/patches/0008-Remove-unused-function.patch b/network/patches/0008-Remove-unused-function.patch new file mode 100644 index 000000000..90cdc0976 --- /dev/null +++ b/network/patches/0008-Remove-unused-function.patch @@ -0,0 +1,29 @@ +From 5b29153cd4527392d6ca4bf8d3cba491db8d490e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Oct 2018 00:07:37 +0200 +Subject: [PATCH 008/304] Remove unused function + +Fixes: #11423 +Signed-off-by: Michael Tremer +--- + src/functions/functions.zone | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/functions/functions.zone b/src/functions/functions.zone +index b9d475f..57e0b71 100644 +--- a/src/functions/functions.zone ++++ b/src/functions/functions.zone +@@ -619,10 +619,6 @@ zone_config_list() { + done + } + +-zone_config_show() { +- zone_config_cmd "show" "$@" +-} +- + # Returns a list of all used ids for a zone + zone_config_list_ids() { + assert [ $# -eq 1 ] +-- +2.39.2 + diff --git a/network/patches/0009-bonding-Validate-any-MAC-address-passed.patch b/network/patches/0009-bonding-Validate-any-MAC-address-passed.patch new file mode 100644 index 000000000..91c45617c --- /dev/null +++ b/network/patches/0009-bonding-Validate-any-MAC-address-passed.patch @@ -0,0 +1,33 @@ +From 7b9557028a381206c573e42a7f5294d20aa0609b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Oct 2018 01:02:27 +0200 +Subject: [PATCH 009/304] bonding; Validate any MAC address passed + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/bonding | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding +index 2880a78..40d849f 100644 +--- a/src/hooks/ports/bonding ++++ b/src/hooks/ports/bonding +@@ -39,8 +39,14 @@ hook_parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in + --address=*) +- ADDRESS=$(cli_get_val "${1}") ++ ADDRESS="$(cli_get_val "${1}")" ++ ++ if ! mac_is_valid "${ADDRESS}"; then ++ error "Invalid MAC address: ${ADDRESS}" ++ return ${EXIT_ERROR} ++ fi + ;; ++ + --miimon=*) + MIIMON=$(cli_get_val "${1}") + ;; +-- +2.39.2 + diff --git a/network/patches/0010-ip-tunnel-Set-TTL-to-255-by-default.patch b/network/patches/0010-ip-tunnel-Set-TTL-to-255-by-default.patch new file mode 100644 index 000000000..6f8a943c4 --- /dev/null +++ b/network/patches/0010-ip-tunnel-Set-TTL-to-255-by-default.patch @@ -0,0 +1,34 @@ +From ae2c5b2b954bfc5282f0ef359d0960a2cd610e14 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Dec 2018 13:38:13 +0100 +Subject: [PATCH 010/304] ip-tunnel: Set TTL to 255 by default + +By default, the Linux kernel inherits the TTL of the transported +packet. Usually with BGP, the TTL is deliberately set to 1 or very +low numbers which causes the packet to be dropped after the first +hop. + +Since the tunnel should be routed, we set this to a default value +of 255 and ignore the TTL of the encapsulated packet. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.ip-tunnel | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/functions/functions.ip-tunnel b/src/functions/functions.ip-tunnel +index 1184a84..11eb3c7 100644 +--- a/src/functions/functions.ip-tunnel ++++ b/src/functions/functions.ip-tunnel +@@ -77,7 +77,7 @@ ip_tunnel_add() { + shift + + local mode +- local ttl ++ local ttl=255 + + local address + local remote_address +-- +2.39.2 + diff --git a/network/patches/0011-bird-Add-some-generic-configuration-file.patch b/network/patches/0011-bird-Add-some-generic-configuration-file.patch new file mode 100644 index 000000000..d89917387 --- /dev/null +++ b/network/patches/0011-bird-Add-some-generic-configuration-file.patch @@ -0,0 +1,107 @@ +From 6a1b0fb170c7d66559935a6a4f8ee0e2bfdbf485 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 16 Dec 2018 17:10:47 +0000 +Subject: [PATCH 011/304] bird: Add some generic configuration file + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + src/functions/functions.bird | 74 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 75 insertions(+) + create mode 100644 src/functions/functions.bird + +diff --git a/Makefile.am b/Makefile.am +index 399652e..0139f95 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -127,6 +127,7 @@ EXTRA_DIST += \ + dist_network_DATA = \ + src/functions/functions.at \ + src/functions/functions.auth \ ++ src/functions/functions.bird \ + src/functions/functions.bonding \ + src/functions/functions.bridge \ + src/functions/functions.cli \ +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +new file mode 100644 +index 0000000..9c8b006 +--- /dev/null ++++ b/src/functions/functions.bird +@@ -0,0 +1,74 @@ ++#!/bin/bash ++############################################################################### ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2018 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++############################################################################### ++ ++BIRD_CONF="/etc/bird.conf" ++ ++bird_start() { ++ service_start "bird.service" ++} ++ ++bird_stop() { ++ service_stop "bird.service" ++} ++ ++bird_reload() { ++ service_reload "bird.service" ++} ++ ++bird_generate_config() { ++ log DEBUG "Write BIRD configuration file" ++ ++ # Write header ++ config_header "bird" > ${BIRD_CONF} ++ ++ # Write some basic settings ++ local proto ++ ( ++ print "# Log everything to syslog" ++ print "log syslog all;" ++ print ++ ++ print "# Turn on internal watchdog" ++ print "watchdog warning 5s;" ++ print "watchdog timeout 30s;" ++ print ++ ++ print "# Define default route tables" ++ print "ipv6 table master6;" ++ print "ipv4 table master4;" ++ ++ print "# Enable device configuration" ++ print "protocol device {}" ++ print ++ ++ print "# Export all routes to kernel" ++ for proto in ipv6 ipv4; do ++ print "protocol kernel {" ++ print " ${proto} {" ++ print " table ${proto/ipv/master};" ++ print " export all;" ++ print " };" ++ print " learn;" ++ print "}" ++ print ++ done ++ ) >> ${BIRD_CONF} ++} +-- +2.39.2 + diff --git a/network/patches/0012-bird-Apply-static-routes-instead-of-doing-that-manua.patch b/network/patches/0012-bird-Apply-static-routes-instead-of-doing-that-manua.patch new file mode 100644 index 000000000..887df6386 --- /dev/null +++ b/network/patches/0012-bird-Apply-static-routes-instead-of-doing-that-manua.patch @@ -0,0 +1,146 @@ +From 0a5787976dd85db212fc5046c85d2aad6c64da5c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 16 Dec 2018 17:47:57 +0000 +Subject: [PATCH 012/304] bird: Apply static routes instead of doing that + manually with ip + +Signed-off-by: Michael Tremer +--- + src/functions/functions.bird | 52 ++++++++++++++++++++++++++++++++- + src/functions/functions.route | 38 +++--------------------- + src/functions/functions.routing | 3 -- + 3 files changed, 55 insertions(+), 38 deletions(-) + +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index 9c8b006..c6fea32 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -60,7 +60,7 @@ bird_generate_config() { + print + + print "# Export all routes to kernel" +- for proto in ipv6 ipv4; do ++ for proto in ${IP_SUPPORTED_PROTOCOLS}; do + print "protocol kernel {" + print " ${proto} {" + print " table ${proto/ipv/master};" +@@ -71,4 +71,54 @@ bird_generate_config() { + print + done + ) >> ${BIRD_CONF} ++ ++ # Static routes ++ for proto in ${IP_SUPPORTED_PROTOCOLS}; do ++ print "protocol static {" ++ print " ${proto};" ++ print ++ ++ # Read routes for this protocol from configuration ++ __bird_static_routes "${proto}" ++ ++ print "}" ++ print ++ done >> ${BIRD_CONF} ++} ++ ++__bird_static_routes() { ++ local proto="${1}" ++ assert isset proto ++ ++ local ${NETWORK_CONFIG_ROUTES_PARAMS} ++ local line ++ while read line; do ++ route_parse_line "${line}" ++ [ $? -eq ${EXIT_OK} ] || continue ++ ++ local type ++ local arg ++ for arg in unreachable prohibit blackhole; do ++ if enabled "${arg}"; then ++ type="${arg}" ++ break ++ fi ++ done ++ ++ # Skip all routes of another protocol ++ local _proto="$(ip_detect_protocol "${network}")" ++ if [ "${proto}" != "${_proto}" ]; then ++ continue ++ fi ++ ++ case "${type}" in ++ unreachable|prohibit|blackhole) ++ print " route ${network} ${type};" ++ ;; ++ ++ *) ++ print " route ${network} via ${gateway};" ++ ;; ++ esac ++ done < ${NETWORK_CONFIG_ROUTES} + } +diff --git a/src/functions/functions.route b/src/functions/functions.route +index 7ca4f59..e6ea244 100644 +--- a/src/functions/functions.route ++++ b/src/functions/functions.route +@@ -393,41 +393,11 @@ route_parse_line() { + } + + route_apply() { +- local table="static" +- local type ++ # Re-generate BIRD configuration ++ bird_generate_config + +- log DEBUG "Applying static routes..." +- +- # Flush the routing table. +- route_table_flush ${table} +- +- local ${NETWORK_CONFIG_ROUTES_PARAMS} +- local line +- while read line; do +- route_parse_line ${line} +- [ $? -eq ${EXIT_OK} ] || continue +- +- type="unicast" +- local arg +- for arg in unreachable prohibit blackhole; do +- if enabled ${arg}; then +- type="${arg}" +- break +- fi +- done +- +- # Add the route. +- route_entry_add ${network} --table="static" --proto="static" \ +- --type="${type}" --gateway="${gateway}" --mtu="${mtu}" +- local ret=$? +- +- if [ ${ret} -ne ${EXIT_OK} ]; then +- log WARNING "Could not set route '${network}'." +- fi +- done < ${NETWORK_CONFIG_ROUTES} +- +- # Create a lookup rule for the static routing table. +- route_rule_add --lookup="static" --priority=1000 ++ # Reload the daemon ++ bird_reload + } + + route_entry_add() { +diff --git a/src/functions/functions.routing b/src/functions/functions.routing +index 2436585..c7aac09 100644 +--- a/src/functions/functions.routing ++++ b/src/functions/functions.routing +@@ -181,7 +181,4 @@ routing_update() { + cmd ${routing_cmd} + + cmd ${ip_cmd} rule add from ${local_ip_address} lookup ${table} +- +- # Apply all static routes +- route_apply + } +-- +2.39.2 + diff --git a/network/patches/0013-bird-Re-generate-configuration-when-network-is-initi.patch b/network/patches/0013-bird-Re-generate-configuration-when-network-is-initi.patch new file mode 100644 index 000000000..1c3458ec4 --- /dev/null +++ b/network/patches/0013-bird-Re-generate-configuration-when-network-is-initi.patch @@ -0,0 +1,28 @@ +From eb6b47dcc7d5d541064ad90787ae55df3c3a8453 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 16 Dec 2018 17:55:25 +0000 +Subject: [PATCH 013/304] bird: (Re-)generate configuration when network is + initialised + +Signed-off-by: Michael Tremer +--- + src/network | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/network b/src/network +index 69d77d5..b8f734e 100644 +--- a/src/network ++++ b/src/network +@@ -1410,6 +1410,9 @@ case "${action}" in + # Update resolv.conf(5) when initializing the network + dns_generate_resolvconf + ++ # Update bird configuration ++ bird_generate_config ++ + # Also execute all triggers + triggers_execute_all "init" + ;; +-- +2.39.2 + diff --git a/network/patches/0014-dns-Always-enable-EDNS0.patch b/network/patches/0014-dns-Always-enable-EDNS0.patch new file mode 100644 index 000000000..bd8ce2427 --- /dev/null +++ b/network/patches/0014-dns-Always-enable-EDNS0.patch @@ -0,0 +1,32 @@ +From c27b38b437fa82a2227d554f4855c116395995ce Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 13 Feb 2019 17:45:05 +0000 +Subject: [PATCH 014/304] dns: Always enable EDNS0 + +This is for all DNS queries originating from the firewall. + +Since we have had DNS Flag Day, we are expecting all DNS servers +to support this now. If not, then you are very unlucky. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.dns | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/functions/functions.dns b/src/functions/functions.dns +index 4cd5cb4..890f1ac 100644 +--- a/src/functions/functions.dns ++++ b/src/functions/functions.dns +@@ -245,6 +245,9 @@ dns_generate_resolvconf() { + + config_header "resolver configutation file" > ${file} + ++ # Always enable EDNS0 ++ print "option edns0\n" >> "${file}" ++ + if enabled DNS_RANDOMIZE; then + print "option rotate\n" >> ${file} + fi +-- +2.39.2 + diff --git a/network/patches/0015-wireless-ap-Use-automatic-channel-selection-ACS-by-d.patch b/network/patches/0015-wireless-ap-Use-automatic-channel-selection-ACS-by-d.patch new file mode 100644 index 000000000..9b6099b56 --- /dev/null +++ b/network/patches/0015-wireless-ap-Use-automatic-channel-selection-ACS-by-d.patch @@ -0,0 +1,27 @@ +From 469bc87f91538d668a32f9c38a3d8b1b4679c7ae Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 19:46:06 +0100 +Subject: [PATCH 015/304] wireless-ap: Use automatic channel selection (ACS) by + default + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/wireless-ap | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 32d1a5a..52ca238 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -28,7 +28,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY" + + ADDRESS=$(mac_generate) + BROADCAST_SSID=on +-CHANNEL=1 ++CHANNEL=0 + ENCRYPTION="" + KEY="" + SSID= +-- +2.39.2 + diff --git a/network/patches/0016-wireless-ap-Allow-to-disable-DFS-in-configuration.patch b/network/patches/0016-wireless-ap-Allow-to-disable-DFS-in-configuration.patch new file mode 100644 index 000000000..717b30550 --- /dev/null +++ b/network/patches/0016-wireless-ap-Allow-to-disable-DFS-in-configuration.patch @@ -0,0 +1,102 @@ +From 7b297fb22fb16db920d68224b232e5acc652688a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 19:58:25 +0100 +Subject: [PATCH 016/304] wireless-ap: Allow to disable DFS in configuration + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 10 +++++++++- + src/helpers/hostapd-config-helper | 1 + + src/hooks/ports/wireless-ap | 16 ++++++++++++++++ + 3 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 3f64e79..e19f9b3 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -36,6 +36,7 @@ hostapd_config_write() { + local broadcast_ssid + local channel + local country_code="$(wireless_get_reg_domain)" ++ local dfs="on" + local encryption + local key + local mode +@@ -50,6 +51,9 @@ hostapd_config_write() { + --channel=*) + channel=$(cli_get_val "${1}") + ;; ++ --dfs=*) ++ dfs="$(cli_get_val "${1}")" ++ ;; + --encryption=*) + encryption=$(cli_get_val "${1}") + ;; +@@ -177,7 +181,11 @@ hostapd_config_write() { + print "ieee80211d=1" + + # Enable Radar Detection +- print "ieee80211h=1" ++ if enabled dfs; then ++ print "ieee80211h=1" ++ else ++ print "ieee80211h=0" ++ fi + + print # empty line + +diff --git a/src/helpers/hostapd-config-helper b/src/helpers/hostapd-config-helper +index cb12af0..30d3456 100644 +--- a/src/helpers/hostapd-config-helper ++++ b/src/helpers/hostapd-config-helper +@@ -40,6 +40,7 @@ case "${action}" in + hostapd_config_write ${port} ${config_file} \ + --broadcast-ssid="${BROADCAST_SSID}" \ + --channel="${CHANNEL}" \ ++ --dfs="${DFS}" \ + --encryption="${ENCRYPTION}" \ + --key="${KEY}" \ + --mode="${MODE}" \ +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 52ca238..49c0a84 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -33,12 +33,16 @@ ENCRYPTION="" + KEY="" + SSID= + ++# Perform radar detection by default when possible ++DFS="on" ++ + hook_check_settings() { + assert isset ADDRESS + assert ismac ADDRESS + assert isset BROADCAST_SSID + assert isbool BROADCAST_SSID + assert isset CHANNEL ++ assert isbool DFS + assert isset MODE + assert isoneof MODE ${HOSTAPD_SUPPORTED_MODES} + assert isset PHY +@@ -63,6 +67,18 @@ hook_parse_cmdline() { + --channel=*) + CHANNEL=$(cli_get_val "${1}") + ;; ++ --dfs=*) ++ DFS="$(cli_get_val "${1}")" ++ ++ if enabled DFS; then ++ DFS="on" ++ elif disabled DFS; then ++ DFS="off" ++ else ++ error "Invalid value for DFS: ${DFS}" ++ return ${EXIT_ERROR} ++ fi ++ ;; + --encryption=*) + ENCRYPTION=$(cli_get_val "${1}") + ;; +-- +2.39.2 + diff --git a/network/patches/0017-hostapd-Disable-DFS-automatically-when-not-supported.patch b/network/patches/0017-hostapd-Disable-DFS-automatically-when-not-supported.patch new file mode 100644 index 000000000..a087dc1a1 --- /dev/null +++ b/network/patches/0017-hostapd-Disable-DFS-automatically-when-not-supported.patch @@ -0,0 +1,99 @@ +From dc6d97fbf2064365f5b84496a77227b4e3ca03d6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 20:10:56 +0100 +Subject: [PATCH 017/304] hostapd: Disable DFS automatically when not supported + by hardware + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 2 +- + src/functions/functions.phy | 22 ++++++++++++++++++++++ + src/functions/functions.wireless | 13 +++++++++++++ + src/network | 7 +++++++ + 4 files changed, 43 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index e19f9b3..b855994 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -181,7 +181,7 @@ hostapd_config_write() { + print "ieee80211d=1" + + # Enable Radar Detection +- if enabled dfs; then ++ if enabled dfs && wireless_supports_dfs "${device}"; then + print "ieee80211h=1" + else + print "ieee80211h=0" +diff --git a/src/functions/functions.phy b/src/functions/functions.phy +index 96287a5..064ca7b 100644 +--- a/src/functions/functions.phy ++++ b/src/functions/functions.phy +@@ -188,3 +188,25 @@ phy_supports_ht_capability() { + + list_match "${capability}" $(__phy_list_ht_capabilities "${phy}") + } ++ ++# Returns TRUE if the PHY supports DFS ++phy_supports_dfs() { ++ local phy="${1}" ++ assert isset phy ++ ++ local driver="$(phy_get_driver "${phy}")" ++ if ! isset driver; then ++ return ${EXIT_ERROR} ++ fi ++ ++ # This is basically a whilelist of drivers which support this ++ # There is no better detection ++ case "${driver}" in ++ ath10k_*|ath9k|ath5k) ++ return ${EXIT_TRUE} ++ ;; ++ *) ++ return ${EXIT_FALSE} ++ ;; ++ esac ++} +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 3608e11..221866e 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -515,3 +515,16 @@ wireless_get_vht_caps() { + + network-phy-list-vht-caps "${phy}" + } ++ ++wireless_supports_dfs() { ++ local device="${1}" ++ assert isset device ++ ++ local phy="$(device_get_phy "${device}")" ++ if ! isset phy; then ++ log ERROR "Could not determine PHY for ${device}" ++ return ${EXIT_ERROR} ++ fi ++ ++ phy_supports_dfs "${phy}" ++} +diff --git a/src/network b/src/network +index b8f734e..de2e663 100644 +--- a/src/network ++++ b/src/network +@@ -277,6 +277,13 @@ cli_device_status_phy() { + cli_space + fi + ++ cli_headline 2 "Features" ++ ++ cli_print_fmt1 2 "DFS" \ ++ "$(phy_supports_dfs "${phy}" && print "Supported" || print "Not Supported")" ++ ++ cli_space ++ + return ${EXIT_OK} + } + +-- +2.39.2 + diff --git a/network/patches/0018-wireless-ap-Add-CLI-to-set-channel-bandwidth.patch b/network/patches/0018-wireless-ap-Add-CLI-to-set-channel-bandwidth.patch new file mode 100644 index 000000000..ef53e6273 --- /dev/null +++ b/network/patches/0018-wireless-ap-Add-CLI-to-set-channel-bandwidth.patch @@ -0,0 +1,87 @@ +From 54094fc7ae1bc17e8d8361f7758d9404f1eeff02 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 20:50:44 +0100 +Subject: [PATCH 018/304] wireless-ap: Add CLI to set channel bandwidth + +Signed-off-by: Michael Tremer +--- + src/functions/functions.wireless | 20 ++++++++++++++++++++ + src/hooks/ports/wireless-ap | 10 ++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 221866e..0437d27 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -29,6 +29,14 @@ WIRELESS_DEFAULT_ENCRYPTION_MODE="NONE" + WIRELESS_VALID_ENCRYPTION_MODES="WPA2-PSK-SHA256 WPA2-PSK \ + WPA-PSK-SHA256 WPA-PSK NONE" + ++declare -A WIRELESS_CHANNEL_BANDWIDTHS=( ++ ["802.11ac"]="20 40 80 160 80+80" ++ ["802.11a/n"]="20 40" ++ ["802.11a"]="20 40" ++ ["802.11g/n"]="20 40" ++ ["802.11g"]="20 40" ++) ++ + cli_wireless() { + local action=${1} + shift 1 +@@ -309,6 +317,18 @@ wireless_channel_is_valid() { + return ${EXIT_FALSE} + } + ++wireless_channel_bandwidth_is_valid() { ++ local mode="${1}" ++ assert isset mode ++ ++ local bandwidth="${2}" ++ assert isset bandwidth ++ ++ local bandwidths="${WIRELESS_CHANNEL_BANDWIDTHS["${mode}"]}" ++ ++ list_match "${bandwidth}" ${bandwidths} ++} ++ + wireless_channel_is_ht40_plus() { + local channel="${1}" + assert isinteger channel +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 49c0a84..8b626bf 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -29,6 +29,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY" + ADDRESS=$(mac_generate) + BROADCAST_SSID=on + CHANNEL=0 ++CHANNEL_BANDWIDTH= + ENCRYPTION="" + KEY="" + SSID= +@@ -67,6 +68,9 @@ hook_parse_cmdline() { + --channel=*) + CHANNEL=$(cli_get_val "${1}") + ;; ++ --channel-bandwidth=*) ++ CHANNEL_BANDWIDTH="$(cli_get_val "${1}")" ++ ;; + --dfs=*) + DFS="$(cli_get_val "${1}")" + +@@ -121,6 +125,12 @@ hook_parse_cmdline() { + return ${EXIT_ERROR} + fi + ++ # Channel bandwidth must match the mode ++ if isset CHANNEL_BANDWIDTH && ! wireless_channel_bandwidth_is_valid "${MODE}" "${CHANNEL_BANDWIDTH}"; then ++ error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported" ++ return ${EXIT_ERROR} ++ fi ++ + # Save address of phy do identify it again + PHY=$(phy_get ${PHY}) + PHY=$(phy_get_address ${PHY}) +-- +2.39.2 + diff --git a/network/patches/0019-wireless-ap-Forgot-to-add-configuration-variables-to.patch b/network/patches/0019-wireless-ap-Forgot-to-add-configuration-variables-to.patch new file mode 100644 index 000000000..d6a92619a --- /dev/null +++ b/network/patches/0019-wireless-ap-Forgot-to-add-configuration-variables-to.patch @@ -0,0 +1,29 @@ +From 40c95a6b261e8fdadca97f21ff7cd2a11af3bfb3 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 21:21:37 +0100 +Subject: [PATCH 019/304] wireless-ap: Forgot to add configuration variables to + file + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/wireless-ap | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 8b626bf..5e00014 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -23,8 +23,8 @@ + + HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}" + +-HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL MODE PHY SSID" +-HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY" ++HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL CHANNEL_BANDWIDTH DFS MODE PHY" ++HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY SSID" + + ADDRESS=$(mac_generate) + BROADCAST_SSID=on +-- +2.39.2 + diff --git a/network/patches/0020-hostapd-Apply-channel-bandwidth-to-configuration.patch b/network/patches/0020-hostapd-Apply-channel-bandwidth-to-configuration.patch new file mode 100644 index 000000000..cf9962ddb --- /dev/null +++ b/network/patches/0020-hostapd-Apply-channel-bandwidth-to-configuration.patch @@ -0,0 +1,109 @@ +From f9e980d91e081613e5dcc7899c28fbdfc7a4c172 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 18 Mar 2019 21:24:02 +0100 +Subject: [PATCH 020/304] hostapd: Apply channel bandwidth to configuration + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 26 ++++++++++++++++++++++++++ + src/helpers/hostapd-config-helper | 1 + + src/hooks/ports/wireless-ap | 2 +- + 3 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index b855994..57f8c1e 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -35,6 +35,7 @@ hostapd_config_write() { + + local broadcast_ssid + local channel ++ local channel_bandwidth + local country_code="$(wireless_get_reg_domain)" + local dfs="on" + local encryption +@@ -51,6 +52,9 @@ hostapd_config_write() { + --channel=*) + channel=$(cli_get_val "${1}") + ;; ++ --channel-bandwidth=*) ++ channel_bandwidth="$(cli_get_val "${1}")" ++ ;; + --dfs=*) + dfs="$(cli_get_val "${1}")" + ;; +@@ -107,10 +111,17 @@ hostapd_config_write() { + assert isset key + fi + ++ # Check channel bandwidth for validity ++ if isset channel_bandwidth && ! wireless_channel_bandwidth_is_valid "${mode}" "${channel_bandwidth}"; then ++ error "Invalid channel bandwidth for ${mode}: ${channel_bandwidth}" ++ return ${EXIT_ERROR} ++ fi ++ + # 802.11ac/n flags + local ieee80211ac + local ieee80211n + local vht_caps ++ local vht_oper_chwidth="0" + local ht_caps + + local hw_mode +@@ -149,6 +160,18 @@ hostapd_config_write() { + + # Fetch HT caps + ht_caps="$(wireless_get_ht_caps "${device}")" ++ ++ case "${channel_bandwidth}" in ++ 80) ++ vht_oper_chwidth="1" ++ ;; ++ 160) ++ vht_oper_chwidth="2" ++ ;; ++ 80+80) ++ vht_oper_chwidth="3" ++ ;; ++ esac + ;; + esac + +@@ -221,6 +244,9 @@ hostapd_config_write() { + # Enable HT caps + print "ht_capab=${ht_caps}" + ++ # Wider Channels ++ print "vht_oper_chwidth=${vht_oper_chwidth}" ++ + print + ) >> ${file} + +diff --git a/src/helpers/hostapd-config-helper b/src/helpers/hostapd-config-helper +index 30d3456..8af3097 100644 +--- a/src/helpers/hostapd-config-helper ++++ b/src/helpers/hostapd-config-helper +@@ -40,6 +40,7 @@ case "${action}" in + hostapd_config_write ${port} ${config_file} \ + --broadcast-ssid="${BROADCAST_SSID}" \ + --channel="${CHANNEL}" \ ++ --channel-bandwidth="${CHANNEL_BANDWIDTH}" \ + --dfs="${DFS}" \ + --encryption="${ENCRYPTION}" \ + --key="${KEY}" \ +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 5e00014..983f0f9 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -127,7 +127,7 @@ hook_parse_cmdline() { + + # Channel bandwidth must match the mode + if isset CHANNEL_BANDWIDTH && ! wireless_channel_bandwidth_is_valid "${MODE}" "${CHANNEL_BANDWIDTH}"; then +- error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported" ++ error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported for ${MODE}" + return ${EXIT_ERROR} + fi + +-- +2.39.2 + diff --git a/network/patches/0021-wireless-ap-Enable-ACS-only-for-ath-devices.patch b/network/patches/0021-wireless-ap-Enable-ACS-only-for-ath-devices.patch new file mode 100644 index 000000000..2bd7a17f7 --- /dev/null +++ b/network/patches/0021-wireless-ap-Enable-ACS-only-for-ath-devices.patch @@ -0,0 +1,117 @@ +From 1b4aa2ca01c5d0bd45213187e6a58b4cc0f57547 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 21 Mar 2019 20:22:56 +0100 +Subject: [PATCH 021/304] wireless-ap: Enable ACS only for ath* devices + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 6 ++++++ + src/functions/functions.phy | 22 ++++++++++++++++++++++ + src/functions/functions.wireless | 13 +++++++++++++ + src/hooks/ports/wireless-ap | 9 ++++++++- + 4 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 57f8c1e..9024ab2 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -111,6 +111,12 @@ hostapd_config_write() { + assert isset key + fi + ++ # With channel 0, ACS must be supported ++ if [ ${channel} -eq 0 ] && ! wireless_supports_acs "${device}"; then ++ error "ACS requested, but not supported by ${device}" ++ return ${EXIT_ERROR} ++ fi ++ + # Check channel bandwidth for validity + if isset channel_bandwidth && ! wireless_channel_bandwidth_is_valid "${mode}" "${channel_bandwidth}"; then + error "Invalid channel bandwidth for ${mode}: ${channel_bandwidth}" +diff --git a/src/functions/functions.phy b/src/functions/functions.phy +index 064ca7b..ee0f2a2 100644 +--- a/src/functions/functions.phy ++++ b/src/functions/functions.phy +@@ -189,6 +189,28 @@ phy_supports_ht_capability() { + list_match "${capability}" $(__phy_list_ht_capabilities "${phy}") + } + ++# Returns TRUE if the PHY supports ACS ++phy_supports_acs() { ++ local phy="${1}" ++ assert isset phy ++ ++ local driver="$(phy_get_driver "${phy}")" ++ if ! isset driver; then ++ return ${EXIT_ERROR} ++ fi ++ ++ # This is basically a whilelist of drivers which support this ++ # There is no better detection ++ case "${driver}" in ++ ath10k_*|ath9k|ath5k) ++ return ${EXIT_TRUE} ++ ;; ++ *) ++ return ${EXIT_FALSE} ++ ;; ++ esac ++} ++ + # Returns TRUE if the PHY supports DFS + phy_supports_dfs() { + local phy="${1}" +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 0437d27..9e72fe0 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -536,6 +536,19 @@ wireless_get_vht_caps() { + network-phy-list-vht-caps "${phy}" + } + ++wireless_supports_acs() { ++ local device="${1}" ++ assert isset device ++ ++ local phy="$(device_get_phy "${device}")" ++ if ! isset phy; then ++ log ERROR "Could not determine PHY for ${device}" ++ return ${EXIT_ERROR} ++ fi ++ ++ phy_supports_acs "${phy}" ++} ++ + wireless_supports_dfs() { + local device="${1}" + assert isset device +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 983f0f9..0c42b61 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -28,7 +28,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY SSID" + + ADDRESS=$(mac_generate) + BROADCAST_SSID=on +-CHANNEL=0 ++CHANNEL= + CHANNEL_BANDWIDTH= + ENCRYPTION="" + KEY="" +@@ -125,6 +125,13 @@ hook_parse_cmdline() { + return ${EXIT_ERROR} + fi + ++ # Automatically enable ACS if no channel is set and ACS is available ++ if ! isset CHANNEL && phy_supports_acs "${PHY}"; then ++ CHANNEL="0" ++ ++ log INFO "Automatic Channel Selection (ACS) enabled" ++ fi ++ + # Channel bandwidth must match the mode + if isset CHANNEL_BANDWIDTH && ! wireless_channel_bandwidth_is_valid "${MODE}" "${CHANNEL_BANDWIDTH}"; then + error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported for ${MODE}" +-- +2.39.2 + diff --git a/network/patches/0022-wireless-ap-Allow-setting-the-wireless-environment-i.patch b/network/patches/0022-wireless-ap-Allow-setting-the-wireless-environment-i.patch new file mode 100644 index 000000000..57c2a889c --- /dev/null +++ b/network/patches/0022-wireless-ap-Allow-setting-the-wireless-environment-i.patch @@ -0,0 +1,164 @@ +From 7842c2ce43d1f185e65bb9f2beead96376e2bd34 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 21 Mar 2019 22:14:43 +0100 +Subject: [PATCH 022/304] wireless-ap: Allow setting the wireless environment + (indoor/outdoor) + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 26 +++++++++++++++++++++++++- + src/functions/functions.wireless | 9 +++++++++ + src/helpers/hostapd-config-helper | 1 + + src/hooks/ports/wireless-ap | 14 +++++++++++++- + 4 files changed, 48 insertions(+), 2 deletions(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 9024ab2..94b06db 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -39,6 +39,7 @@ hostapd_config_write() { + local country_code="$(wireless_get_reg_domain)" + local dfs="on" + local encryption ++ local environment="${WIRELESS_DEFAULT_ENVIRONMENT}" + local key + local mode + local ssid +@@ -61,6 +62,9 @@ hostapd_config_write() { + --encryption=*) + encryption=$(cli_get_val "${1}") + ;; ++ --environment=*) ++ environment="$(cli_get_val "${1}")" ++ ;; + --key=*) + key=$(cli_get_val "${1}") + ;; +@@ -111,6 +115,12 @@ hostapd_config_write() { + assert isset key + fi + ++ # Check wireless environment ++ if ! wireless_environment_is_valid "${environment}"; then ++ error "Invalid wireless environment: ${environment}" ++ return ${EXIT_ERROR} ++ fi ++ + # With channel 0, ACS must be supported + if [ ${channel} -eq 0 ] && ! wireless_supports_acs "${device}"; then + error "ACS requested, but not supported by ${device}" +@@ -208,6 +218,21 @@ hostapd_config_write() { + + # Advertise country code and maximum transmission power + print "ieee80211d=1" ++ print "country_code=${country_code}" ++ ++ # Wireless Environment ++ case "${environment}" in ++ indoor) ++ print "country3=0x49" ++ country3 ++ ;; ++ outdoor) ++ print "country3=0x4f" ++ ;; ++ indoor+outdoor) ++ print "country3=0x20" ++ ;; ++ esac + + # Enable Radar Detection + if enabled dfs && wireless_supports_dfs "${device}"; then +@@ -230,7 +255,6 @@ hostapd_config_write() { + fi + + print "channel=${channel}" +- print "country_code=${country_code}" + print "ignore_broadcast_ssid=${ignore_broadcast_ssid}" + + if contains_spaces "${ssid}"; then +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 9e72fe0..12204c0 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -37,6 +37,9 @@ declare -A WIRELESS_CHANNEL_BANDWIDTHS=( + ["802.11g"]="20 40" + ) + ++WIRELESS_ENVIRONMENTS=( "indoor+outdoor" "indoor" "outdoor" ) ++WIRELESS_DEFAULT_ENVIRONMENT="${WIRELESS_ENVIRONMENTS[0]}" ++ + cli_wireless() { + local action=${1} + shift 1 +@@ -561,3 +564,9 @@ wireless_supports_dfs() { + + phy_supports_dfs "${phy}" + } ++ ++wireless_environment_is_valid() { ++ local environment="${1}" ++ ++ list_match "${environment}" "${WIRELESS_ENVIRONMENTS[@]}" ++} +diff --git a/src/helpers/hostapd-config-helper b/src/helpers/hostapd-config-helper +index 8af3097..d3292c3 100644 +--- a/src/helpers/hostapd-config-helper ++++ b/src/helpers/hostapd-config-helper +@@ -43,6 +43,7 @@ case "${action}" in + --channel-bandwidth="${CHANNEL_BANDWIDTH}" \ + --dfs="${DFS}" \ + --encryption="${ENCRYPTION}" \ ++ --environment="${ENVIRONMENT}" \ + --key="${KEY}" \ + --mode="${MODE}" \ + --ssid="${SSID}" \ +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 0c42b61..6db39b8 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -24,7 +24,7 @@ + HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}" + + HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL CHANNEL_BANDWIDTH DFS MODE PHY" +-HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY SSID" ++HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION ENVIRONMENT KEY SSID" + + ADDRESS=$(mac_generate) + BROADCAST_SSID=on +@@ -37,6 +37,8 @@ SSID= + # Perform radar detection by default when possible + DFS="on" + ++ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" ++ + hook_check_settings() { + assert isset ADDRESS + assert ismac ADDRESS +@@ -57,6 +59,8 @@ hook_check_settings() { + assert [ ${#KEY} -ge 8 ] + assert [ ${#KEY} -le 63 ] + fi ++ ++ assert wireless_environment_is_valid "${ENVIRONMENT}" + } + + hook_parse_cmdline() { +@@ -86,6 +90,14 @@ hook_parse_cmdline() { + --encryption=*) + ENCRYPTION=$(cli_get_val "${1}") + ;; ++ --environment=*) ++ ENVIRONMENT="$(cli_get_val "${1}")" ++ ++ if ! wireless_environment_is_valid "${ENVIRONMENT}"; then ++ error "Invalid wireless environment: ${ENVIRONMENT}" ++ return ${EXIT_ERROR} ++ fi ++ ;; + --key=*) + KEY=$(cli_get_val "${1}") + ;; +-- +2.39.2 + diff --git a/network/patches/0023-hostapd-Remove-now-useless-comment.patch b/network/patches/0023-hostapd-Remove-now-useless-comment.patch new file mode 100644 index 000000000..0e224a2c9 --- /dev/null +++ b/network/patches/0023-hostapd-Remove-now-useless-comment.patch @@ -0,0 +1,26 @@ +From 09f00f0df436a3280b93b7570c6b9ae3152cf21e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 11:40:32 +0100 +Subject: [PATCH 023/304] hostapd: Remove now useless comment + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 94b06db..eb177fe 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -214,8 +214,6 @@ hostapd_config_write() { + fi + + ( +- print "# Default settings" +- + # Advertise country code and maximum transmission power + print "ieee80211d=1" + print "country_code=${country_code}" +-- +2.39.2 + diff --git a/network/patches/0024-hostapd-Always-enable-Transmit-Power-Control.patch b/network/patches/0024-hostapd-Always-enable-Transmit-Power-Control.patch new file mode 100644 index 000000000..bac1030a2 --- /dev/null +++ b/network/patches/0024-hostapd-Always-enable-Transmit-Power-Control.patch @@ -0,0 +1,30 @@ +From 9602617288e200c0935d5888746f58c23b2f7af7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 11:45:03 +0100 +Subject: [PATCH 024/304] hostapd: Always enable Transmit Power Control + +Also advertise this to clients + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index eb177fe..dd52e56 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -232,6 +232,10 @@ hostapd_config_write() { + ;; + esac + ++ # Always advertise TPC ++ print "local_pwr_constraint=3" ++ print "spectrum_mgmt_required=1" ++ + # Enable Radar Detection + if enabled dfs && wireless_supports_dfs "${device}"; then + print "ieee80211h=1" +-- +2.39.2 + diff --git a/network/patches/0025-hostapd-Set-default-WMM-settings.patch b/network/patches/0025-hostapd-Set-default-WMM-settings.patch new file mode 100644 index 000000000..7e8e2dab1 --- /dev/null +++ b/network/patches/0025-hostapd-Set-default-WMM-settings.patch @@ -0,0 +1,72 @@ +From fcdbed86e00c02550682c110d768ff9a557ba8d7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 12:02:25 +0100 +Subject: [PATCH 025/304] hostapd: Set default WMM settings + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 47 ++++++++++++++++++++++++++++++++- + 1 file changed, 46 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index dd52e56..911a141 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -265,8 +265,53 @@ hostapd_config_write() { + print "ssid=${ssid}" + fi + +- # WMM ++ # WMM & WMM-PS Unscheduled Automatic Power Save Delivery + print "wmm_enabled=${wmm}" ++ print "uapsd_advertisement_enabled=1" ++ ++ # Low Priority / AC_BK = Background ++ print "wmm_ac_bk_cwmin=4" ++ print "wmm_ac_bk_cwmax=10" ++ print "wmm_ac_bk_aifs=7" ++ print "wmm_ac_bk_txop_limit=0" ++ print "wmm_ac_bk_acm=0" ++ print "tx_queue_data3_aifs=7" ++ print "tx_queue_data3_cwmin=15" ++ print "tx_queue_data3_cwmax=1023" ++ print "tx_queue_data3_burst=0" ++ ++ # Normal Priority / AC_BE = Best Effort ++ print "wmm_ac_be_aifs=3" ++ print "wmm_ac_be_cwmin=4" ++ print "wmm_ac_be_cwmax=10" ++ print "wmm_ac_be_txop_limit=0" ++ print "wmm_ac_be_acm=0" ++ print "tx_queue_data2_aifs=3" ++ print "tx_queue_data2_cwmin=15" ++ print "tx_queue_data2_cwmax=63" ++ print "tx_queue_data2_burst=0" ++ ++ # High Priority / AC_VI = Video ++ print "wmm_ac_vi_aifs=2" ++ print "wmm_ac_vi_cwmin=3" ++ print "wmm_ac_vi_cwmax=4" ++ print "wmm_ac_vi_txop_limit=94" ++ print "wmm_ac_vi_acm=0" ++ print "tx_queue_data1_aifs=1" ++ print "tx_queue_data1_cwmin=7" ++ print "tx_queue_data1_cwmax=15" ++ print "tx_queue_data1_burst=3.0" ++ ++ # Highest Priority / AC_VO = Voice ++ print "wmm_ac_vo_aifs=2" ++ print "wmm_ac_vo_cwmin=2" ++ print "wmm_ac_vo_cwmax=3" ++ print "wmm_ac_vo_txop_limit=47" ++ print "wmm_ac_vo_acm=0" ++ print "tx_queue_data0_aifs=1" ++ print "tx_queue_data0_cwmin=3" ++ print "tx_queue_data0_cwmax=7" ++ print "tx_queue_data0_burst=1.5" + + # Enable VHT caps + if isset vht_caps; then +-- +2.39.2 + diff --git a/network/patches/0026-hostapd-Kick-stations-that-are-too-far-away.patch b/network/patches/0026-hostapd-Kick-stations-that-are-too-far-away.patch new file mode 100644 index 000000000..09f16b114 --- /dev/null +++ b/network/patches/0026-hostapd-Kick-stations-that-are-too-far-away.patch @@ -0,0 +1,27 @@ +From 4d4bca7eec3d036e1cbed28fc823d06d08008d78 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 12:02:46 +0100 +Subject: [PATCH 026/304] hostapd: Kick stations that are too far away + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 911a141..8b281cc 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -265,6 +265,9 @@ hostapd_config_write() { + print "ssid=${ssid}" + fi + ++ # Kick stations that are too far away ++ print "disassoc_low_ack=1" ++ + # WMM & WMM-PS Unscheduled Automatic Power Save Delivery + print "wmm_enabled=${wmm}" + print "uapsd_advertisement_enabled=1" +-- +2.39.2 + diff --git a/network/patches/0027-hostapd-Always-qoute-SSID.patch b/network/patches/0027-hostapd-Always-qoute-SSID.patch new file mode 100644 index 000000000..9e65758fa --- /dev/null +++ b/network/patches/0027-hostapd-Always-qoute-SSID.patch @@ -0,0 +1,34 @@ +From 4873f3299807fb0fde7c7f71736dd9318c708ca1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 12:08:08 +0100 +Subject: [PATCH 027/304] hostapd: Always qoute SSID + +hostapd has a new parameter that always allows us to set +the SSID as a quoted UTF8 string + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 8b281cc..245b4cf 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -259,11 +259,8 @@ hostapd_config_write() { + print "channel=${channel}" + print "ignore_broadcast_ssid=${ignore_broadcast_ssid}" + +- if contains_spaces "${ssid}"; then +- print "ssid=\"${ssid}\"" +- else +- print "ssid=${ssid}" +- fi ++ print "ssid2=\"${ssid}\"" ++ print "utf8_ssid=1" + + # Kick stations that are too far away + print "disassoc_low_ack=1" +-- +2.39.2 + diff --git a/network/patches/0028-wireless-ap-Allow-to-enable-disable-802.11w-Manageme.patch b/network/patches/0028-wireless-ap-Allow-to-enable-disable-802.11w-Manageme.patch new file mode 100644 index 000000000..dc0872607 --- /dev/null +++ b/network/patches/0028-wireless-ap-Allow-to-enable-disable-802.11w-Manageme.patch @@ -0,0 +1,130 @@ +From 34ca39360410ab03c7909494e6291bbb65622e3d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 22 Mar 2019 12:27:38 +0100 +Subject: [PATCH 028/304] wireless-ap: Allow to enable/disable 802.11w + Management Frame Protection + +This is disabled by default, because loads of stations have issues +associating with an AP that has 802.11w enabled. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 17 +++++++++++++++++ + src/helpers/hostapd-config-helper | 1 + + src/hooks/ports/wireless-ap | 18 ++++++++++++++++++ + 3 files changed, 36 insertions(+) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 245b4cf..bf0c5fc 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -41,6 +41,7 @@ hostapd_config_write() { + local encryption + local environment="${WIRELESS_DEFAULT_ENVIRONMENT}" + local key ++ local mfp="off" + local mode + local ssid + local wmm="1" +@@ -68,6 +69,9 @@ hostapd_config_write() { + --key=*) + key=$(cli_get_val "${1}") + ;; ++ --mfp=*) ++ mfp="$(cli_get_val "${1}")" ++ ;; + --mode=*) + mode=$(cli_get_val "${1}") + +@@ -133,6 +137,12 @@ hostapd_config_write() { + return ${EXIT_ERROR} + fi + ++ # Management Frame Proection ++ if ! isbool mfp; then ++ error "Invalid value for --mfp: ${mfp}" ++ return ${EXIT_ERROR} ++ fi ++ + # 802.11ac/n flags + local ieee80211ac + local ieee80211n +@@ -325,6 +335,13 @@ hostapd_config_write() { + print "vht_oper_chwidth=${vht_oper_chwidth}" + + print ++ ++ # 802.11w - Management Frame Protection (MFP) ++ if enabled mfp; then ++ print "ieee80211w=2" # required ++ else ++ print "ieee80211w=0" ++ fi + ) >> ${file} + + # Control interface. +diff --git a/src/helpers/hostapd-config-helper b/src/helpers/hostapd-config-helper +index d3292c3..7af723d 100644 +--- a/src/helpers/hostapd-config-helper ++++ b/src/helpers/hostapd-config-helper +@@ -45,6 +45,7 @@ case "${action}" in + --encryption="${ENCRYPTION}" \ + --environment="${ENVIRONMENT}" \ + --key="${KEY}" \ ++ --mfp="${MFP}" \ + --mode="${MODE}" \ + --ssid="${SSID}" \ + || exit $? +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 6db39b8..7073cbc 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -25,6 +25,7 @@ HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}" + + HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL CHANNEL_BANDWIDTH DFS MODE PHY" + HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION ENVIRONMENT KEY SSID" ++HOOK_SETTINGS="${HOOK_SETTINGS} MFP" + + ADDRESS=$(mac_generate) + BROADCAST_SSID=on +@@ -37,6 +38,10 @@ SSID= + # Perform radar detection by default when possible + DFS="on" + ++# 802.11w - Management Frame Protection ++# Disable by default because many clients cannot connect when enabled ++MFP="off" ++ + ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" + + hook_check_settings() { +@@ -46,6 +51,7 @@ hook_check_settings() { + assert isbool BROADCAST_SSID + assert isset CHANNEL + assert isbool DFS ++ assert isbool MFP + assert isset MODE + assert isoneof MODE ${HOSTAPD_SUPPORTED_MODES} + assert isset PHY +@@ -104,6 +110,18 @@ hook_parse_cmdline() { + --mac=*) + ADDRESS=$(cli_get_val "${1}") + ;; ++ --mfp=*) ++ MFP="$(cli_get_val "${1}")" ++ ++ if enabled MFP; then ++ MFP="on" ++ elif disabled MFP; then ++ MFP="off" ++ else ++ error "Invalid value for --mfp: ${MFP}" ++ return ${EXIT_ERROR} ++ fi ++ ;; + --mode=*) + MODE=$(cli_get_val "${1}") + +-- +2.39.2 + diff --git a/network/patches/0029-network-Show-when-a-PHY-supports-ACS.patch b/network/patches/0029-network-Show-when-a-PHY-supports-ACS.patch new file mode 100644 index 000000000..f18008404 --- /dev/null +++ b/network/patches/0029-network-Show-when-a-PHY-supports-ACS.patch @@ -0,0 +1,26 @@ +From 304b20a828e0987943ccda6f1c4321682195a67a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 29 Mar 2019 18:46:25 +0100 +Subject: [PATCH 029/304] network: Show when a PHY supports ACS + +Signed-off-by: Michael Tremer +--- + src/network | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/network b/src/network +index de2e663..3535133 100644 +--- a/src/network ++++ b/src/network +@@ -279,6 +279,8 @@ cli_device_status_phy() { + + cli_headline 2 "Features" + ++ cli_print_fmt1 2 "Automatic Channel Selection" \ ++ "$(phy_supports_acs "${phy}" && print "Supported" || print "Not Supported")" + cli_print_fmt1 2 "DFS" \ + "$(phy_supports_dfs "${phy}" && print "Supported" || print "Not Supported")" + +-- +2.39.2 + diff --git a/network/patches/0030-Move-cli_device_status_phy-to-functions.phy.patch b/network/patches/0030-Move-cli_device_status_phy-to-functions.phy.patch new file mode 100644 index 000000000..eaf70d3fd --- /dev/null +++ b/network/patches/0030-Move-cli_device_status_phy-to-functions.phy.patch @@ -0,0 +1,112 @@ +From 01648ba604f9d0c922193553cfcb36dae0bfddaf Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 29 Mar 2019 18:47:47 +0100 +Subject: [PATCH 030/304] Move cli_device_status_phy() to functions.phy + +Signed-off-by: Michael Tremer +--- + src/functions/functions.phy | 38 +++++++++++++++++++++++++++++++++++++ + src/network | 38 ------------------------------------- + 2 files changed, 38 insertions(+), 38 deletions(-) + +diff --git a/src/functions/functions.phy b/src/functions/functions.phy +index ee0f2a2..120117c 100644 +--- a/src/functions/functions.phy ++++ b/src/functions/functions.phy +@@ -21,6 +21,44 @@ + + PHY_DIR="/sys/class/ieee80211" + ++cli_device_status_phy() { ++ local phy="${1}" ++ assert phy_exists "${phy}" ++ ++ local address="$(phy_get_address "${phy}")" ++ cli_print_fmt1 1 "Address" "${address}" ++ ++ # Show kernel module ++ local driver="$(phy_get_driver "${phy}")" ++ if isset driver; then ++ cli_print_fmt1 1 "Driver" "${driver}" ++ fi ++ ++ cli_space ++ ++ local devices="$(phy_get_devices "${phy}")" ++ if isset devices; then ++ cli_headline 2 "Soft interfaces" ++ ++ local device ++ for device in ${devices}; do ++ cli_print 2 "* %s" "${device}" ++ done ++ cli_space ++ fi ++ ++ cli_headline 2 "Features" ++ ++ cli_print_fmt1 2 "Automatic Channel Selection" \ ++ "$(phy_supports_acs "${phy}" && print "Supported" || print "Not Supported")" ++ cli_print_fmt1 2 "DFS" \ ++ "$(phy_supports_dfs "${phy}" && print "Supported" || print "Not Supported")" ++ ++ cli_space ++ ++ return ${EXIT_OK} ++} ++ + phy_dir() { + local phy=${1} + +diff --git a/src/network b/src/network +index 3535133..300ba94 100644 +--- a/src/network ++++ b/src/network +@@ -251,44 +251,6 @@ cli_device_status_serial() { + fi + } + +-cli_device_status_phy() { +- local phy="${1}" +- assert phy_exists "${phy}" +- +- local address="$(phy_get_address "${phy}")" +- cli_print_fmt1 1 "Address" "${address}" +- +- # Show kernel module +- local driver="$(phy_get_driver "${phy}")" +- if isset driver; then +- cli_print_fmt1 1 "Driver" "${driver}" +- fi +- +- cli_space +- +- local devices="$(phy_get_devices "${phy}")" +- if isset devices; then +- cli_headline 2 "Soft interfaces" +- +- local device +- for device in ${devices}; do +- cli_print 2 "* %s" "${device}" +- done +- cli_space +- fi +- +- cli_headline 2 "Features" +- +- cli_print_fmt1 2 "Automatic Channel Selection" \ +- "$(phy_supports_acs "${phy}" && print "Supported" || print "Not Supported")" +- cli_print_fmt1 2 "DFS" \ +- "$(phy_supports_dfs "${phy}" && print "Supported" || print "Not Supported")" +- +- cli_space +- +- return ${EXIT_OK} +-} +- + cli_device_discover() { + local device=${1} + shift +-- +2.39.2 + diff --git a/network/patches/0031-hostapd-Dump-config-file-in-debug-mode.patch b/network/patches/0031-hostapd-Dump-config-file-in-debug-mode.patch new file mode 100644 index 000000000..26e05b097 --- /dev/null +++ b/network/patches/0031-hostapd-Dump-config-file-in-debug-mode.patch @@ -0,0 +1,52 @@ +From 7c91c167d10cbe3d390f0dc8c426eed0abf243b4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 11:26:38 +0100 +Subject: [PATCH 031/304] hostapd: Dump config file in debug mode + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 3 +++ + src/functions/functions.util | 13 +++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index bf0c5fc..737bd1a 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -378,6 +378,9 @@ hostapd_config_write() { + ) >> ${file} + fi + ++ # Log configuration file ++ file_to_log DEBUG "${file}" ++ + return ${EXIT_OK} + } + +diff --git a/src/functions/functions.util b/src/functions/functions.util +index b767423..4c1dbb4 100644 +--- a/src/functions/functions.util ++++ b/src/functions/functions.util +@@ -248,6 +248,19 @@ file_get_age() { + return ${EXIT_ERROR} + } + ++file_to_log() { ++ local level="${1}" ++ assert isset level ++ ++ local file="${2}" ++ assert file_exists "${file}" ++ ++ local line ++ while read line; do ++ log "${level}" "${line}" ++ done < "${file}" ++} ++ + make_directory() { + local path="${1}" + +-- +2.39.2 + diff --git a/network/patches/0032-wireless-ap-Automatically-enable-all-supported-ciphe.patch b/network/patches/0032-wireless-ap-Automatically-enable-all-supported-ciphe.patch new file mode 100644 index 000000000..7277180b2 --- /dev/null +++ b/network/patches/0032-wireless-ap-Automatically-enable-all-supported-ciphe.patch @@ -0,0 +1,519 @@ +From 2e4e3c88ba2543e5bf4bf3f92977990c281a00bb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 11:27:50 +0100 +Subject: [PATCH 032/304] wireless-ap: Automatically enable all supported + ciphers + +Signed-off-by: Michael Tremer +--- + Makefile.am | 7 ++ + src/functions/functions.hostapd | 65 +++++++++++- + src/functions/functions.phy | 17 +++ + src/libnetwork/libnetwork.sym | 37 ++++--- + src/libnetwork/network/phy.h | 22 ++++ + src/libnetwork/phy.c | 149 +++++++++++++++++++++++++++ + src/utils/.gitignore | 1 + + src/utils/network-phy-list-ciphers.c | 61 +++++++++++ + 8 files changed, 340 insertions(+), 19 deletions(-) + create mode 100644 src/utils/network-phy-list-ciphers.c + +diff --git a/Makefile.am b/Makefile.am +index 0139f95..1b5e7e9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -301,6 +301,7 @@ EXTRA_DIST += \ + + util_PROGRAMS = \ + src/utils/network-phy-list-channels \ ++ src/utils/network-phy-list-ciphers \ + src/utils/network-phy-list-ht-caps \ + src/utils/network-phy-list-vht-caps + +@@ -310,6 +311,12 @@ src_utils_network_phy_list_channels_SOURCES = \ + src_utils_network_phy_list_channels_LDADD = \ + src/libnetwork.la + ++src_utils_network_phy_list_ciphers_SOURCES = \ ++ src/utils/network-phy-list-ciphers.c ++ ++src_utils_network_phy_list_ciphers_LDADD = \ ++ src/libnetwork.la ++ + src_utils_network_phy_list_ht_caps_SOURCES = \ + src/utils/network-phy-list-ht-caps.c + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 737bd1a..6111457 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -23,6 +23,19 @@ HOSTAPD_CONTROL_INTERFACE_DIR="/run/hostapd/ctrl" + + HOSTAPD_SUPPORTED_MODES="802.11a 802.11a/n 802.11ac 802.11g 802.11g/n" + ++HOSTAPD_SUPPORTED_PAIRWISE_CIPHERS=( ++ "GCMP-256" # Galois/counter mode protocol with 256 bit key ++ "CCMP-256" # AES in Counter mode with CBC-MAC with 256 bit key ++ "GCMP-128" # Galois/counter mode protocol with 128 bit key ++ "CCMP-128" # AES in Counter mode with CBC-MAC with 128 bit key ++) ++ ++# This must be supported by all stations on the network and therefore ++# can effectively only be CCMP ++HOSTAPD_SUPPORTED_GROUP_CIPHERS=( ++ "CCMP-128" ++) ++ + hostapd_config_write() { + local device=${1} + assert isset device +@@ -33,6 +46,16 @@ hostapd_config_write() { + # Shift the device and file argument. + shift 2 + ++ # Device must exist ++ if ! device_exists "${device}"; then ++ error "Cannot write hostapd configuration for non-existant device: ${device}" ++ return ${EXIT_ERROR} ++ fi ++ ++ # Get the phy for device ++ local phy="$(device_get_phy "${device}")" ++ assert isset phy ++ + local broadcast_ssid + local channel + local channel_bandwidth +@@ -201,6 +224,25 @@ hostapd_config_write() { + ;; + esac + ++ # Cryptography ++ local cipher ++ ++ # Get all supported pairwise ciphers ++ local pairwise_ciphers=() ++ for cipher in ${HOSTAPD_SUPPORTED_PAIRWISE_CIPHERS[*]}; do ++ if phy_supports_cipher "${phy}" "${cipher}"; then ++ pairwise_ciphers+=( "$(hostapd_cipher_name "${cipher}")" ) ++ fi ++ done ++ ++ # Get all supported group ciphers ++ local group_ciphers=() ++ for cipher in ${HOSTAPD_SUPPORTED_GROUP_CIPHERS[*]}; do ++ if phy_supports_cipher "${phy}" "${cipher}"; then ++ group_ciphers+=( "$(hostapd_cipher_name "${cipher}")" ) ++ fi ++ done ++ + # Create configuration directory. + local config_dir=$(dirname ${file}) + mkdir -p ${HOSTAPD_CONTROL_INTERFACE_DIR} ${config_dir} 2>/dev/null +@@ -372,8 +414,9 @@ hostapd_config_write() { + print "wpa=${encryption_mode}" + print "wpa_passphrase=${key}" + print "wpa_key_mgmt=WPA-PSK" +- print "wpa_pairwise=TKIP" +- print "rsn_pairwise=CCMP" ++ print "wpa_pairwise=${pairwise_ciphers[*]}" ++ print "rsn_pairwise=${pairwise_ciphers[*]}" ++ print "group_cipher=${group_ciphers[*]}" + print + ) >> ${file} + fi +@@ -407,3 +450,21 @@ hostapd_stop() { + + service_stop "hostapd@${device}.service" + } ++ ++hostapd_cipher_name() { ++ local cipher="${1}" ++ ++ case "${cipher}" in ++ CCMP-128) ++ print "CCMP" ++ ;; ++ ++ GCMP-128) ++ print "GCMP" ++ ;; ++ ++ *) ++ print "${cipher}" ++ ;; ++ esac ++} +diff --git a/src/functions/functions.phy b/src/functions/functions.phy +index 120117c..c06389c 100644 +--- a/src/functions/functions.phy ++++ b/src/functions/functions.phy +@@ -208,6 +208,23 @@ phy_supports_channel() { + return ${EXIT_FALSE} + } + ++phy_list_ciphers() { ++ local phy="${1}" ++ assert isset phy ++ ++ network-phy-list-ciphers "${phy}" ++} ++ ++phy_supports_cipher() { ++ local phy="${1}" ++ assert isset phy ++ ++ local cipher="${2}" ++ assert isset cipher ++ ++ list_match "${cipher}" $(phy_list_ciphers "${phy}") ++} ++ + __phy_list_ht_capabilities() { + local phy="${1}" + assert isset phy +diff --git a/src/libnetwork/libnetwork.sym b/src/libnetwork/libnetwork.sym +index 593c4a2..034d43f 100644 +--- a/src/libnetwork/libnetwork.sym ++++ b/src/libnetwork/libnetwork.sym +@@ -1,21 +1,24 @@ + LIBNETWORK_0 { + global: +- network_interface_get_name; +- network_interface_new; +- network_interface_ref; +- network_interface_unref; +- network_new; +- network_phy_has_ht_capability; +- network_phy_has_vht_capability; +- network_phy_list_channels; +- network_phy_list_ht_capabilities; +- network_phy_list_vht_capabilities; +- network_phy_new; +- network_phy_ref; +- network_phy_unref; +- network_ref; +- network_unref; +- network_version; ++ network_interface_get_name; ++ network_interface_new; ++ network_interface_ref; ++ network_interface_unref; ++ network_new; ++ network_phy_get_cipher_string; ++ network_phy_has_ht_capability; ++ network_phy_has_vht_capability; ++ network_phy_list_channels; ++ network_phy_list_ciphers; ++ network_phy_list_ht_capabilities; ++ network_phy_list_vht_capabilities; ++ network_phy_supports_cipher; ++ network_phy_new; ++ network_phy_ref; ++ network_phy_unref; ++ network_ref; ++ network_unref; ++ network_version; + local: +- *; ++ *; + }; +diff --git a/src/libnetwork/network/phy.h b/src/libnetwork/network/phy.h +index 9059680..bc6dafb 100644 +--- a/src/libnetwork/network/phy.h ++++ b/src/libnetwork/network/phy.h +@@ -30,6 +30,25 @@ int network_phy_new(struct network_ctx*, struct network_phy** phy, const char* n + struct network_phy* network_phy_ref(struct network_phy* phy); + struct network_phy* network_phy_unref(struct network_phy* phy); + ++enum network_phy_ciphers { ++ NETWORK_PHY_CIPHER_WEP40 = (1 << 0), ++ NETWORK_PHY_CIPHER_TKIP = (1 << 1), ++ NETWORK_PHY_CIPHER_CCMP128 = (1 << 2), ++ NETWORK_PHY_CIPHER_WEP104 = (1 << 3), ++ NETWORK_PHY_CIPHER_CMAC128 = (1 << 4), ++ NETWORK_PHY_CIPHER_GCMP128 = (1 << 5), ++ NETWORK_PHY_CIPHER_GCMP256 = (1 << 6), ++ NETWORK_PHY_CIPHER_CCMP256 = (1 << 7), ++ NETWORK_PHY_CIPHER_GMAC128 = (1 << 8), ++ NETWORK_PHY_CIPHER_GMAC256 = (1 << 9), ++ NETWORK_PHY_CIPHER_CMAC256 = (1 << 10), ++ NETWORK_PHY_CIPHER_WPISMS4 = (1 << 11), ++}; ++ ++const char* network_phy_get_cipher_string(const enum network_phy_ciphers cipher); ++int network_phy_supports_cipher(struct network_phy* phy, const enum network_phy_ciphers cipher); ++char* network_phy_list_ciphers(struct network_phy* phy); ++ + enum network_phy_ht_caps { + NETWORK_PHY_HT_CAP_RX_LDPC = (1 << 0), + NETWORK_PHY_HT_CAP_HT40 = (1 << 1), +@@ -81,6 +100,9 @@ char* network_phy_list_ht_capabilities(struct network_phy* phy); + struct nl_msg* network_phy_make_netlink_message(struct network_phy* phy, + enum nl80211_commands cmd, int flags); + ++#define foreach_cipher(cipher) \ ++ for(enum network_phy_ciphers cipher = NETWORK_PHY_CIPHER_WEP40; cipher <= NETWORK_PHY_CIPHER_WPISMS4; cipher <<= 1) ++ + #define foreach_vht_cap(cap) \ + for(int cap = NETWORK_PHY_VHT_CAP_VHT160; cap <= NETWORK_PHY_VHT_CAP_TX_ANTENNA_PATTERN; cap <<= 1) + +diff --git a/src/libnetwork/phy.c b/src/libnetwork/phy.c +index 0bf9c81..e3f2aad 100644 +--- a/src/libnetwork/phy.c ++++ b/src/libnetwork/phy.c +@@ -52,6 +52,7 @@ struct network_phy { + + TAILQ_HEAD(head, network_phy_channel) channels; + ++ enum network_phy_ciphers ciphers; + ssize_t max_mpdu_length; + unsigned int vht_caps; + unsigned int ht_caps; +@@ -80,6 +81,81 @@ static int phy_get_index(const char* name) { + return atoi(index); + } + ++static void phy_parse_ciphers(struct network_phy* phy, __u32* ciphers, int num) { ++ enum network_phy_ciphers cipher; ++ ++ // Reset value ++ phy->ciphers = 0; ++ ++ for (int i = 0; i < num; i++) { ++ switch (ciphers[i]) { ++ case 0x000fac01: ++ cipher = NETWORK_PHY_CIPHER_WEP40; ++ break; ++ ++ case 0x000fac02: ++ cipher = NETWORK_PHY_CIPHER_TKIP; ++ break; ++ ++ case 0x000fac04: ++ cipher = NETWORK_PHY_CIPHER_CCMP128; ++ break; ++ ++ case 0x000fac05: ++ cipher = NETWORK_PHY_CIPHER_WEP104; ++ break; ++ ++ case 0x000fac06: ++ cipher = NETWORK_PHY_CIPHER_CMAC128; ++ break; ++ ++ case 0x000fac08: ++ cipher = NETWORK_PHY_CIPHER_GCMP128; ++ break; ++ ++ case 0x000fac09: ++ cipher = NETWORK_PHY_CIPHER_GCMP256; ++ break; ++ ++ /* ++ I have no idea what these are. My card reports them but ++ I could not find out anything about them. ++ */ ++ case 0x000fac0a: ++ case 0x000fac0b: ++ case 0x000fac0c: ++ case 0x000fac0d: ++ continue; ++ ++ case 0x000fac10: ++ cipher = NETWORK_PHY_CIPHER_CCMP256; ++ break; ++ ++ case 0x000fac11: ++ cipher = NETWORK_PHY_CIPHER_GMAC128; ++ break; ++ ++ case 0x000fac12: ++ cipher = NETWORK_PHY_CIPHER_GMAC256; ++ break; ++ ++ case 0x000fac13: ++ cipher = NETWORK_PHY_CIPHER_CMAC256; ++ break; ++ ++ case 0x00147201: ++ cipher = NETWORK_PHY_CIPHER_WPISMS4; ++ break; ++ ++ default: ++ ERROR(phy->ctx, "Unknown cipher found: %x\n", ciphers[i]); ++ continue; ++ } ++ ++ phy->ciphers |= cipher; ++ } ++} ++ + static void phy_parse_vht_capabilities(struct network_phy* phy, __u32 caps) { + // Max MPDU length + switch (caps & 0x3) { +@@ -325,6 +401,13 @@ static int phy_parse_info(struct nl_msg* msg, void* data) { + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + ++ // Ciphers ++ if (attrs[NL80211_ATTR_CIPHER_SUITES]) { ++ int num = nla_len(attrs[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32); ++ __u32* ciphers = nla_data(attrs[NL80211_ATTR_CIPHER_SUITES]); ++ phy_parse_ciphers(phy, ciphers, num); ++ } ++ + if (attrs[NL80211_ATTR_WIPHY_BANDS]) { + struct nlattr* nl_band; + int i; +@@ -464,6 +547,72 @@ nla_put_failure: + return NULL; + } + ++NETWORK_EXPORT const char* network_phy_get_cipher_string(const enum network_phy_ciphers cipher) { ++ switch (cipher) { ++ case NETWORK_PHY_CIPHER_WEP40: ++ return "WEP40"; ++ ++ case NETWORK_PHY_CIPHER_TKIP: ++ return "TKIP"; ++ ++ case NETWORK_PHY_CIPHER_CCMP128: ++ return "CCMP-128"; ++ ++ case NETWORK_PHY_CIPHER_WEP104: ++ return "WEP-104"; ++ ++ case NETWORK_PHY_CIPHER_CMAC128: ++ return "CMAC-128"; ++ ++ case NETWORK_PHY_CIPHER_GCMP128: ++ return "GCMP-128"; ++ ++ case NETWORK_PHY_CIPHER_GCMP256: ++ return "GCMP-256"; ++ ++ case NETWORK_PHY_CIPHER_CCMP256: ++ return "CCMP-256"; ++ ++ case NETWORK_PHY_CIPHER_GMAC128: ++ return "GMAC-128"; ++ ++ case NETWORK_PHY_CIPHER_GMAC256: ++ return "GMAC-256"; ++ ++ case NETWORK_PHY_CIPHER_CMAC256: ++ return "CMAC-256"; ++ ++ case NETWORK_PHY_CIPHER_WPISMS4: ++ return "WPI-SMS4"; ++ } ++ ++ return NULL; ++} ++ ++NETWORK_EXPORT int network_phy_supports_cipher(struct network_phy* phy, const enum network_phy_ciphers cipher) { ++ return phy->ciphers & cipher; ++} ++ ++NETWORK_EXPORT char* network_phy_list_ciphers(struct network_phy* phy) { ++ char* buffer = NULL; ++ ++ foreach_cipher(cipher) { ++ if (network_phy_supports_cipher(phy, cipher)) { ++ const char* s = network_phy_get_cipher_string(cipher); ++ ++ if (!s) ++ continue; ++ ++ if (buffer) ++ asprintf(&buffer, "%s %s", buffer, s); ++ else ++ asprintf(&buffer, "%s", s); ++ } ++ } ++ ++ return buffer; ++} ++ + NETWORK_EXPORT int network_phy_has_vht_capability(struct network_phy* phy, const enum network_phy_vht_caps cap) { + return phy->vht_caps & cap; + } +diff --git a/src/utils/.gitignore b/src/utils/.gitignore +index 11cf3b6..df712dc 100644 +--- a/src/utils/.gitignore ++++ b/src/utils/.gitignore +@@ -1,3 +1,4 @@ + /network-phy-list-channels ++/network-phy-list-ciphers + /network-phy-list-ht-caps + /network-phy-list-vht-caps +diff --git a/src/utils/network-phy-list-ciphers.c b/src/utils/network-phy-list-ciphers.c +new file mode 100644 +index 0000000..0132c0c +--- /dev/null ++++ b/src/utils/network-phy-list-ciphers.c +@@ -0,0 +1,61 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2019 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++int main(int argc, char** argv) { ++ struct network_ctx* ctx = NULL; ++ struct network_phy* phy = NULL; ++ int r; ++ ++ if (argc < 2) { ++ fprintf(stderr, "No enough arguments\n"); ++ r = 2; ++ goto END; ++ } ++ ++ // Initialise context ++ r = network_new(&ctx); ++ if (r) ++ return r; ++ ++ r = network_phy_new(ctx, &phy, argv[1]); ++ if (r) { ++ fprintf(stderr, "Could not find %s\n", argv[1]); ++ goto END; ++ } ++ ++ // Print all supported ciphers ++ char* ciphers = network_phy_list_ciphers(phy); ++ if (ciphers && *ciphers) { ++ printf("%s\n", ciphers); ++ free(ciphers); ++ } ++ ++END: ++ network_phy_unref(phy); ++ network_unref(ctx); ++ return r; ++} +-- +2.39.2 + diff --git a/network/patches/0033-hostapd-Enable-WPA-authentication-with-SHA256.patch b/network/patches/0033-hostapd-Enable-WPA-authentication-with-SHA256.patch new file mode 100644 index 000000000..70a50a310 --- /dev/null +++ b/network/patches/0033-hostapd-Enable-WPA-authentication-with-SHA256.patch @@ -0,0 +1,26 @@ +From 27380e6e6343faa0b2c1a87234ecf21ecc6f0840 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 12:47:32 +0100 +Subject: [PATCH 033/304] hostapd: Enable WPA authentication with SHA256 + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 6111457..79fb4db 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -413,7 +413,7 @@ hostapd_config_write() { + print "# Encryption settings" + print "wpa=${encryption_mode}" + print "wpa_passphrase=${key}" +- print "wpa_key_mgmt=WPA-PSK" ++ print "wpa_key_mgmt=WPA-PSK-SHA256 WPA-PSK" + print "wpa_pairwise=${pairwise_ciphers[*]}" + print "rsn_pairwise=${pairwise_ciphers[*]}" + print "group_cipher=${group_ciphers[*]}" +-- +2.39.2 + diff --git a/network/patches/0034-hooks-Automatically-set-defaults-for-all-port-hooks.patch b/network/patches/0034-hooks-Automatically-set-defaults-for-all-port-hooks.patch new file mode 100644 index 000000000..f2940d01a --- /dev/null +++ b/network/patches/0034-hooks-Automatically-set-defaults-for-all-port-hooks.patch @@ -0,0 +1,98 @@ +From 4637109c42417e34c02631cd8391bccc7f2733cb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 13:03:59 +0100 +Subject: [PATCH 034/304] hooks: Automatically set defaults for all port hooks + +Before, this was broken so that all configuration parameters +had to be passed all the time. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hook | 5 ++--- + src/header-port | 4 ++++ + src/hooks/ports/bonding | 5 ++--- + src/hooks/ports/wireless-ap | 15 +++++---------- + 4 files changed, 13 insertions(+), 16 deletions(-) + +diff --git a/src/functions/functions.hook b/src/functions/functions.hook +index 2f3ced0..c0ebfcb 100644 +--- a/src/functions/functions.hook ++++ b/src/functions/functions.hook +@@ -130,9 +130,8 @@ hook_set_defaults() { + for setting in ${HOOK_SETTINGS}; do + local default="DEFAULT_${setting}" + +- if isset ${default}; then +- assign "${setting}" "${!default}" +- fi ++ # Sets the default or empty ++ assign "${setting}" "${!default}" + done + } + +diff --git a/src/header-port b/src/header-port +index ce1c192..141228a 100644 +--- a/src/header-port ++++ b/src/header-port +@@ -44,6 +44,10 @@ hook_hotplug_rename() { + + hook_default_new() { + local ${HOOK_SETTINGS} ++ ++ # Import all default variables ++ hook_set_defaults ++ + if ! hook_parse_cmdline "$@"; then + return ${EXIT_ERROR} + fi +diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding +index 40d849f..f0572c3 100644 +--- a/src/hooks/ports/bonding ++++ b/src/hooks/ports/bonding +@@ -23,9 +23,8 @@ + + HOOK_SETTINGS="ADDRESS MIIMON MODE OFFLOADING SLAVES" + +-SLAVES="" +-MIIMON=100 +-MODE="balance-rr" ++DEFAULT_MIIMON=100 ++DEFAULT_MODE="balance-rr" + + hook_check_settings() { + assert isset ADDRESS +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 7073cbc..2bb4977 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -27,22 +27,17 @@ HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL CHANNEL_BANDWIDTH DFS MODE PHY" + HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION ENVIRONMENT KEY SSID" + HOOK_SETTINGS="${HOOK_SETTINGS} MFP" + +-ADDRESS=$(mac_generate) +-BROADCAST_SSID=on +-CHANNEL= +-CHANNEL_BANDWIDTH= +-ENCRYPTION="" +-KEY="" +-SSID= ++# Broadcast SSID by default ++DEFAULT_BROADCAST_SSID="on" + + # Perform radar detection by default when possible +-DFS="on" ++DEFAULT_DFS="on" + + # 802.11w - Management Frame Protection + # Disable by default because many clients cannot connect when enabled +-MFP="off" ++DEFAULT_MFP="off" + +-ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" ++DEFAULT_ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" + + hook_check_settings() { + assert isset ADDRESS +-- +2.39.2 + diff --git a/network/patches/0035-hooks-Import-zone-default-settings-too.patch b/network/patches/0035-hooks-Import-zone-default-settings-too.patch new file mode 100644 index 000000000..c31e8e94d --- /dev/null +++ b/network/patches/0035-hooks-Import-zone-default-settings-too.patch @@ -0,0 +1,176 @@ +From 53e764a73d5a04f653a4fda3c7f8810e8de13ed8 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 13:10:58 +0100 +Subject: [PATCH 035/304] hooks: Import zone default settings, too + +Signed-off-by: Michael Tremer +--- + src/header-zone | 5 +++++ + src/hooks/zones/bridge | 11 ++--------- + src/hooks/zones/ip-tunnel | 8 +------- + src/hooks/zones/modem | 12 +----------- + src/hooks/zones/pppoe | 20 ++------------------ + 5 files changed, 11 insertions(+), 45 deletions(-) + +diff --git a/src/header-zone b/src/header-zone +index ead4a32..7ad3e39 100644 +--- a/src/header-zone ++++ b/src/header-zone +@@ -34,6 +34,11 @@ hook_new() { + assert isset zone + shift + ++ local ${HOOK_SETTINGS} ++ ++ # Import all default variables ++ hook_set_defaults ++ + if ! hook_parse_cmdline "$@"; then + return ${EXIT_ERROR} + fi +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 93a3a31..33d5811 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -29,6 +29,7 @@ HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MTU" + HOOK_PORT_SETTINGS="COST PRIORITY" + + # Default values ++DEFAULT_STP="on" + DEFAULT_STP_FORWARD_DELAY=0 + DEFAULT_STP_HELLO=2 + DEFAULT_STP_MAXAGE=20 +@@ -123,19 +124,11 @@ hook_parse_cmdline() { + shift + done + +- # Generate a random MAC address if the user passed no one ++ # Generate a random MAC address if the user passed none + if ! isset ADDRESS; then + ADDRESS="$(mac_generate)" + fi + +- # Enable Spanning Tree Protocol by default +- if ! isset STP; then +- STP="on" +- fi +- +- # Set all other defaults +- hook_set_defaults +- + return ${EXIT_OK} + } + +diff --git a/src/hooks/zones/ip-tunnel b/src/hooks/zones/ip-tunnel +index c9c73ba..e4be361 100644 +--- a/src/hooks/zones/ip-tunnel ++++ b/src/hooks/zones/ip-tunnel +@@ -26,13 +26,7 @@ SUPPORTED_IP_TUNNEL_MODES="gre vti" + HOOK_SETTINGS="HOOK MARK MODE PEER LOCAL_ADDRESS" + + # Default mode of the tunnel +-MODE="gre" +- +-# The IP address of the tunnel endpoint where to connect to +-PEER= +- +-# The local IP address of the tunnel endpoint +-LOCAL_ADDRESS= ++DEFAULT_MODE="gre" + + hook_check_settings() { + assert isset MODE && assert isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES} +diff --git a/src/hooks/zones/modem b/src/hooks/zones/modem +index 1b4c3c0..50d43c7 100644 +--- a/src/hooks/zones/modem ++++ b/src/hooks/zones/modem +@@ -27,47 +27,37 @@ MODEM_ALLOWED_AUTH_METHODS="${PPP_ALLOWED_AUTH_METHODS}" + HOOK_SETTINGS="HOOK" + + # Access Point Name. +-APN= + HOOK_SETTINGS="${HOOK_SETTINGS} APN" + + # Sets the authentication algortihm that must be used. +-AUTH= + HOOK_SETTINGS="${HOOK_SETTINGS} AUTH" + + # Baudrate. +-BAUDRATE=921600 ++DEFAULT_BAUDRATE=921600 + HOOK_SETTINGS="${HOOK_SETTINGS} BAUDRATE" + + # The device name of the serial device. + # XXX how can we make sure that this does not change all the time? +-DEVICE= + HOOK_SETTINGS="${HOOK_SETTINGS} DEVICE" + + # A monitor device. + # Send AT commands to this device, when the primary device is + # connected. +-MONITOR_DEVICE= + HOOK_SETTINGS="${HOOK_SETTINGS} MONITOR_DEVICE" + + # Maximum transmission unit. +-MTU= + HOOK_SETTINGS="${HOOK_SETTINGS} MTU" + + # User credentials. +-USERNAME= +-PASSWORD= + HOOK_SETTINGS="${HOOK_SETTINGS} USERNAME PASSWORD" + + # PIN code. +-PIN= + HOOK_SETTINGS="${HOOK_SETTINGS} PIN" + + # Phone number. +-PHONE_NUMBER= + HOOK_SETTINGS="${HOOK_SETTINGS} PHONE_NUMBER" + + # IMSI +-IMSI= + HOOK_SETTINGS="${HOOK_SETTINGS} IMSI" + + hook_check_settings() { +diff --git a/src/hooks/zones/pppoe b/src/hooks/zones/pppoe +index e113c92..cd3913b 100644 +--- a/src/hooks/zones/pppoe ++++ b/src/hooks/zones/pppoe +@@ -24,31 +24,15 @@ + HOOK_SETTINGS="HOOK ACCESS_CONCENTRATOR AUTH USERNAME PASSWORD" + HOOK_SETTINGS="${HOOK_SETTINGS} SERVICE_NAME MTU IPV6 PREFIX_DELEGATION" + +-# User credentials for the dialin. +-USERNAME="" +-PASSWORD="" +- +-# Set the authentication mechanism. +-AUTH= +- +-# Access Concentrator. +-ACCESS_CONCENTRATOR="" +- +-# Service name. +-SERVICE_NAME="" +- +-# Maximum Transmission Unit. +-MTU= +- + # This hook can work with all authentication methods supported by pppd. + PPPOE_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}" + PPPOE_PLUGIN="rp-pppoe.so" + + # Request an IPv6 address. +-IPV6="true" ++DEFAULT_IPV6="true" + + # Use IPv6 prefix delegation. +-PREFIX_DELEGATION="true" ++DEFAULT_PREFIX_DELEGATION="true" + + hook_check_settings() { + assert isset USERNAME +-- +2.39.2 + diff --git a/network/patches/0036-Convert-HOOK_SETTINGS-into-an-array.patch b/network/patches/0036-Convert-HOOK_SETTINGS-into-an-array.patch new file mode 100644 index 000000000..ad1fc9ade --- /dev/null +++ b/network/patches/0036-Convert-HOOK_SETTINGS-into-an-array.patch @@ -0,0 +1,628 @@ +From d389e96b6c0a73fefd907bc99401b4ce4021bf97 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 13:49:08 +0100 +Subject: [PATCH 036/304] Convert HOOK_SETTINGS into an array + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hook | 2 +- + src/functions/functions.ports | 4 +-- + src/functions/functions.zone | 6 ++--- + src/header-port | 10 ++++---- + src/header-zone | 2 +- + src/hooks/ports/bonding | 20 +++++++++------ + src/hooks/ports/dummy | 10 +++++--- + src/hooks/ports/ethernet | 19 +++++++++------ + src/hooks/ports/ip-tunnel | 16 ++++++++---- + src/hooks/ports/vlan | 14 +++++++---- + src/hooks/ports/wireless-ap | 19 ++++++++++++--- + src/hooks/ports/wireless-mesh | 12 ++++++--- + src/hooks/zones/bridge | 17 ++++++++++--- + src/hooks/zones/ip-tunnel | 7 +++++- + src/hooks/zones/modem | 46 ++++++++++------------------------- + src/hooks/zones/pppoe | 12 +++++++-- + src/hooks/zones/wireless | 5 +++- + 17 files changed, 132 insertions(+), 89 deletions(-) + +diff --git a/src/functions/functions.hook b/src/functions/functions.hook +index c0ebfcb..fb68037 100644 +--- a/src/functions/functions.hook ++++ b/src/functions/functions.hook +@@ -127,7 +127,7 @@ hook_help() { + # Sets all settings in HOOK_SETTINGS to their DEFAULT_* values + hook_set_defaults() { + local setting +- for setting in ${HOOK_SETTINGS}; do ++ for setting in ${HOOK_SETTINGS[*]}; do + local default="DEFAULT_${setting}" + + # Sets the default or empty +diff --git a/src/functions/functions.ports b/src/functions/functions.ports +index f70adf6..fb22715 100644 +--- a/src/functions/functions.ports ++++ b/src/functions/functions.ports +@@ -85,7 +85,7 @@ port_settings_read() { + # Save the HOOK variable. + local hook="${HOOK}" + +- settings_read "$(port_file "${port}")" ${HOOK_SETTINGS} ++ settings_read "$(port_file "${port}")" ${HOOK_SETTINGS[*]} + + # Restore hook. + HOOK="${hook}" +@@ -100,7 +100,7 @@ port_settings_write() { + if function_exists "hook_check_settings"; then + list_append args "--check=\"hook_check_settings\"" + fi +- list_append args HOOK ${HOOK_SETTINGS} ++ list_append args HOOK ${HOOK_SETTINGS[*]} + + settings_write "$(port_file "${port}")" ${args} + } +diff --git a/src/functions/functions.zone b/src/functions/functions.zone +index 57e0b71..a0d3cfb 100644 +--- a/src/functions/functions.zone ++++ b/src/functions/functions.zone +@@ -1248,8 +1248,8 @@ zone_settings_read() { + shift + + local args +- if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS}" ]; then +- list_append args ${HOOK_SETTINGS} ++ if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS[*]}" ]; then ++ list_append args ${HOOK_SETTINGS[*]} + else + list_append args "$@" + fi +@@ -1271,7 +1271,7 @@ zone_settings_write() { + if function_exists "hook_check_settings"; then + list_append args "--check=\"hook_check_settings\"" + fi +- list_append args ${HOOK_SETTINGS} ++ list_append args HOOK ${HOOK_SETTINGS[*]} + + settings_write "${NETWORK_ZONES_DIR}/${zone}/settings" ${args} + } +diff --git a/src/header-port b/src/header-port +index 141228a..2d8a820 100644 +--- a/src/header-port ++++ b/src/header-port +@@ -43,7 +43,7 @@ hook_hotplug_rename() { + } + + hook_default_new() { +- local ${HOOK_SETTINGS} ++ local ${HOOK_SETTINGS[*]} + + # Import all default variables + hook_set_defaults +@@ -57,7 +57,7 @@ hook_default_new() { + local port=$(port_find_free ${HOOK_PORT_PATTERN}) + assert isset port + +- port_settings_write "${port}" ${HOOK_SETTINGS} ++ port_settings_write "${port}" ${HOOK_SETTINGS[*]} + + exit ${EXIT_OK} + } +@@ -72,7 +72,7 @@ hook_default_edit() { + shift + + # Read settings +- if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then ++ if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then + error "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -83,7 +83,7 @@ hook_default_edit() { + fi + + # Save settings +- if ! port_settings_write "${port}" ${HOOK_SETTINGS}; then ++ if ! port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then + error "Could not write settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -102,7 +102,7 @@ hook_edit() { + hook_children() { + local port="${1}" + +- if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then ++ if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then + log ERROR "Could not read port settings: ${port}" + return ${EXIT_OK} + fi +diff --git a/src/header-zone b/src/header-zone +index 7ad3e39..2174b01 100644 +--- a/src/header-zone ++++ b/src/header-zone +@@ -34,7 +34,7 @@ hook_new() { + assert isset zone + shift + +- local ${HOOK_SETTINGS} ++ local ${HOOK_SETTINGS[*]} + + # Import all default variables + hook_set_defaults +diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding +index f0572c3..09fb74f 100644 +--- a/src/hooks/ports/bonding ++++ b/src/hooks/ports/bonding +@@ -21,7 +21,13 @@ + + . /usr/lib/network/header-port + +-HOOK_SETTINGS="ADDRESS MIIMON MODE OFFLOADING SLAVES" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "MIIMON" ++ "MODE" ++ "OFFLOADING" ++ "SLAVES" ++) + + DEFAULT_MIIMON=100 + DEFAULT_MODE="balance-rr" +@@ -110,7 +116,7 @@ hook_new() { + assert isset port + + # Save configuration +- if port_settings_write "${port}" ${HOOK_SETTINGS}; then ++ if port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then + log INFO "New port ${port} has been created" + else + error "Could not save configuration for ${port}" +@@ -162,7 +168,7 @@ hook_create() { + # Exit silently if the device already exists + device_exists "${port}" && exit ${EXIT_OK} + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Create the bonding devices + bonding_create "${port}" \ +@@ -178,7 +184,7 @@ hook_remove() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Remove the bonding device + if device_exists "${port}"; then +@@ -190,7 +196,7 @@ hook_up() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Auto-enable or disable hardware offloading + if ! isset OFFLOADING || enabled OFFLOADING; then +@@ -213,7 +219,7 @@ hook_down() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Bring down all slaves + local slave +@@ -234,7 +240,7 @@ hook_hotplug() { + # Handle events of the same interface + if hotplug_event_port_is_interface "${port}"; then + # Read configuration +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Bring up all slaves + # Attach those which already exist and try to create +diff --git a/src/hooks/ports/dummy b/src/hooks/ports/dummy +index 61d2f94..1c4b3c9 100644 +--- a/src/hooks/ports/dummy ++++ b/src/hooks/ports/dummy +@@ -21,7 +21,9 @@ + + . /usr/lib/network/header-port + +-HOOK_SETTINGS="ADDRESS" ++HOOK_SETTINGS=( ++ "ADDRESS" ++) + + hook_check_settings() { + assert ismac ADDRESS +@@ -60,7 +62,7 @@ hook_new() { + local port=$(port_find_free ${DUMMY_PORT_PATTERN}) + assert isset port + +- if port_settings_write "${port}" ${HOOK_SETTINGS}; then ++ if port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then + log INFO "New dummy port '${port}' has been created" + fi + +@@ -72,7 +74,7 @@ hook_create() { + assert isset port + + # Read configuration +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Create the dummy device + dummy_create "${port}" "${ADDRESS}" +@@ -115,7 +117,7 @@ hook_hotplug_rename() { + local device=${2} + assert isset device + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + if [ "${ADDRESS}" = "$(device_get_address ${device})" ]; then + log DEBUG "Device '${device}' equals port '${port}'." +diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet +index 0d9c5cd..f3e3f9f 100644 +--- a/src/hooks/ports/ethernet ++++ b/src/hooks/ports/ethernet +@@ -21,10 +21,13 @@ + + . /usr/lib/network/header-port + +-# DEVICE equals the actual MAC address of the device. +-# If ADDRESS is set, the device will get ADDRESS set for its MAC address. +- +-HOOK_SETTINGS="ADDRESS ADVERTISED_LINK_SPEEDS DEVICE OFFLOADING MTU" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "ADVERTISED_LINK_SPEEDS" ++ "DEVICE" ++ "OFFLOADING" ++ "MTU" ++) + + hook_check_settings() { + assert ismac DEVICE +@@ -114,7 +117,7 @@ hook_new() { + + local DEVICE="$(device_get_address "${device}")" + +- if ! port_settings_write "${port}" ${HOOK_SETTINGS}; then ++ if ! port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then + log ERROR "Could not write settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -129,8 +132,8 @@ hook_create() { + hook_up() { + local port="${1}" + +- local ${HOOK_SETTINGS} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then ++ local ${HOOK_SETTINGS[*]} ++ if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -177,7 +180,7 @@ hook_hotplug_rename() { + assert isset device + + # Read in the conifguration file. +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Get the current MAC address of the device. + local address=$(device_get_address ${device}) +diff --git a/src/hooks/ports/ip-tunnel b/src/hooks/ports/ip-tunnel +index 3943e4c..b426963 100644 +--- a/src/hooks/ports/ip-tunnel ++++ b/src/hooks/ports/ip-tunnel +@@ -23,7 +23,13 @@ + + SUPPORTED_IP_TUNNEL_MODES="gretap" + +-HOOK_SETTINGS="ADDRESS MARK MODE PEER LOCAL_ADDRESS" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "MARK" ++ "MODE" ++ "PEER" ++ "LOCAL_ADDRESS" ++) + + hook_check_settings() { + assert isset MODE +@@ -108,8 +114,8 @@ hook_create() { + local port="${1}" + assert isset port + +- local ${HOOK_SETTINGS} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then ++ local ${HOOK_SETTINGS[*]} ++ if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -146,8 +152,8 @@ hook_hotplug_rename() { + local device="${2}" + assert isset device + +- local ${HOOK_SETTINGS} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then ++ local ${HOOK_SETTINGS[*]} ++ if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index bc12a9e..e9aa545 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -21,7 +21,11 @@ + + . /usr/lib/network/header-port + +-HOOK_SETTINGS="ADDRESS PARENT_DEVICE TAG" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "PARENT_DEVICE" ++ "TAG" ++) + + PORT_PARENTS_VAR="PARENT" + +@@ -68,7 +72,7 @@ hook_new() { + + local port="${PARENT_DEVICE}${VLAN_PORT_INTERFIX}${TAG}" + +- port_settings_write "${port}" ${HOOK_SETTINGS} ++ port_settings_write "${port}" ${HOOK_SETTINGS[*]} + + exit ${EXIT_OK} + } +@@ -78,7 +82,7 @@ hook_edit() { + assert isset port + shift + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + while [ $# -gt 0 ]; do + case "${1}" in +@@ -92,7 +96,7 @@ hook_edit() { + shift + done + +- port_settings_write "${port}" ${HOOK_SETTINGS} ++ port_settings_write "${port}" ${HOOK_SETTINGS[*]} + + exit ${EXIT_OK} + } +@@ -104,7 +108,7 @@ hook_create() { + device_exists "${port}" && exit ${EXIT_OK} + + # Read configruation +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Create the VLAN device + vlan_create "${port}" "${PARENT_DEVICE}" "${TAG}" "${ADDRESS}" +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 2bb4977..8d495d2 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -23,9 +23,20 @@ + + HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}" + +-HOOK_SETTINGS="ADDRESS BROADCAST_SSID CHANNEL CHANNEL_BANDWIDTH DFS MODE PHY" +-HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION ENVIRONMENT KEY SSID" +-HOOK_SETTINGS="${HOOK_SETTINGS} MFP" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "BROADCAST_SSID" ++ "CHANNEL" ++ "CHANNEL_BANDWIDTH" ++ "DFS" ++ "ENCRYPTION" ++ "ENVIRONMENT" ++ "KEY" ++ "MFP" ++ "MODE" ++ "PHY" ++ "SSID" ++) + + # Broadcast SSID by default + DEFAULT_BROADCAST_SSID="on" +@@ -186,7 +197,7 @@ hook_create() { + + device_exists "${port}" && exit ${EXIT_OK} + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Check if the PHY is present. + local phy=$(phy_get ${PHY}) +diff --git a/src/hooks/ports/wireless-mesh b/src/hooks/ports/wireless-mesh +index 4fb4dc9..306263d 100644 +--- a/src/hooks/ports/wireless-mesh ++++ b/src/hooks/ports/wireless-mesh +@@ -23,7 +23,13 @@ + + HOOK_PORT_PATTERN="${PORT_PATTERN_MESH}" + +-HOOK_SETTINGS="ADDRESS MESH_ID CHANNEL PHY PSK" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "CHANNEL" ++ "MESH_ID" ++ "PHY" ++ "PSK" ++) + + hook_check_settings() { + assert ismac ADDRESS +@@ -84,7 +90,7 @@ hook_create() { + assert isset port + + # Read settings +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + # Check if the PHY is present. + local phy="$(phy_get "${PHY}")" +@@ -143,7 +149,7 @@ hook_hotplug() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS} ++ port_settings_read "${port}" ${HOOK_SETTINGS[*]} + + case "$(hotplug_action)" in + add) +diff --git a/src/hooks/zones/bridge b/src/hooks/zones/bridge +index 33d5811..0b18331 100644 +--- a/src/hooks/zones/bridge ++++ b/src/hooks/zones/bridge +@@ -23,10 +23,19 @@ + + HOOK_MANPAGE="network-zone-bridge" + +-HOOK_SETTINGS="HOOK ADDRESS STP STP_FORWARD_DELAY STP_HELLO STP_MAXAGE" +-HOOK_SETTINGS="${HOOK_SETTINGS} STP_PRIORITY MTU" +- +-HOOK_PORT_SETTINGS="COST PRIORITY" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "STP" ++ "STP_FORWARD_DELAY" ++ "STP_HELLO STP_MAXAGE" ++ "STP_PRIORITY" ++ "MTU" ++) ++ ++HOOK_PORT_SETTINGS=( ++ "COST" ++ "PRIORITY" ++) + + # Default values + DEFAULT_STP="on" +diff --git a/src/hooks/zones/ip-tunnel b/src/hooks/zones/ip-tunnel +index e4be361..634154e 100644 +--- a/src/hooks/zones/ip-tunnel ++++ b/src/hooks/zones/ip-tunnel +@@ -23,7 +23,12 @@ + + SUPPORTED_IP_TUNNEL_MODES="gre vti" + +-HOOK_SETTINGS="HOOK MARK MODE PEER LOCAL_ADDRESS" ++HOOK_SETTINGS=( ++ "MARK" ++ "MODE" ++ "PEER" ++ "LOCAL_ADDRESS" ++) + + # Default mode of the tunnel + DEFAULT_MODE="gre" +diff --git a/src/hooks/zones/modem b/src/hooks/zones/modem +index 50d43c7..e12b104 100644 +--- a/src/hooks/zones/modem ++++ b/src/hooks/zones/modem +@@ -24,41 +24,21 @@ + # Modems support all authentication methods, that pppd does support. + MODEM_ALLOWED_AUTH_METHODS="${PPP_ALLOWED_AUTH_METHODS}" + +-HOOK_SETTINGS="HOOK" ++HOOK_SETTINGS=( ++ "APN" ++ "AUTH" ++ "BAUDRATE" ++ "DEVICE" ++ "MONITOR_DEVICE" ++ "MTU" ++ "USERNAME" ++ "PASSWORD" ++ "PIN" ++ "PHONE_NUMBER" ++ "IMSI" ++) + +-# Access Point Name. +-HOOK_SETTINGS="${HOOK_SETTINGS} APN" +- +-# Sets the authentication algortihm that must be used. +-HOOK_SETTINGS="${HOOK_SETTINGS} AUTH" +- +-# Baudrate. + DEFAULT_BAUDRATE=921600 +-HOOK_SETTINGS="${HOOK_SETTINGS} BAUDRATE" +- +-# The device name of the serial device. +-# XXX how can we make sure that this does not change all the time? +-HOOK_SETTINGS="${HOOK_SETTINGS} DEVICE" +- +-# A monitor device. +-# Send AT commands to this device, when the primary device is +-# connected. +-HOOK_SETTINGS="${HOOK_SETTINGS} MONITOR_DEVICE" +- +-# Maximum transmission unit. +-HOOK_SETTINGS="${HOOK_SETTINGS} MTU" +- +-# User credentials. +-HOOK_SETTINGS="${HOOK_SETTINGS} USERNAME PASSWORD" +- +-# PIN code. +-HOOK_SETTINGS="${HOOK_SETTINGS} PIN" +- +-# Phone number. +-HOOK_SETTINGS="${HOOK_SETTINGS} PHONE_NUMBER" +- +-# IMSI +-HOOK_SETTINGS="${HOOK_SETTINGS} IMSI" + + hook_check_settings() { + assert isset DEVICE +diff --git a/src/hooks/zones/pppoe b/src/hooks/zones/pppoe +index cd3913b..4f7ae51 100644 +--- a/src/hooks/zones/pppoe ++++ b/src/hooks/zones/pppoe +@@ -21,8 +21,16 @@ + + . /usr/lib/network/header-zone + +-HOOK_SETTINGS="HOOK ACCESS_CONCENTRATOR AUTH USERNAME PASSWORD" +-HOOK_SETTINGS="${HOOK_SETTINGS} SERVICE_NAME MTU IPV6 PREFIX_DELEGATION" ++HOOK_SETTINGS=( ++ "ACCESS_CONCENTRATOR" ++ "AUTH" ++ "USERNAME" ++ "PASSWORD" ++ "SERVICE_NAME" ++ "MTU" ++ "IPV6" ++ "PREFIX_DELEGATION" ++) + + # This hook can work with all authentication methods supported by pppd. + PPPOE_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}" +diff --git a/src/hooks/zones/wireless b/src/hooks/zones/wireless +index 553d917..9c52dce 100644 +--- a/src/hooks/zones/wireless ++++ b/src/hooks/zones/wireless +@@ -21,7 +21,10 @@ + + . /usr/lib/network/header-zone + +-HOOK_SETTINGS="HOOK ADDRESS PHY" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "PHY" ++) + + hook_check_settings() { + assert ismac ADDRESS +-- +2.39.2 + diff --git a/network/patches/0037-settings-Some-code-refactoring.patch b/network/patches/0037-settings-Some-code-refactoring.patch new file mode 100644 index 000000000..e3f473f0b --- /dev/null +++ b/network/patches/0037-settings-Some-code-refactoring.patch @@ -0,0 +1,133 @@ +From 227d458f4fac10cbf0970515edd3227913fc1bf4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 14:04:35 +0100 +Subject: [PATCH 037/304] settings: Some code refactoring + +No functional changes + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hook | 13 +++++++++++++ + src/functions/functions.ports | 10 ++-------- + src/functions/functions.zone | 32 ++++++++------------------------ + 3 files changed, 23 insertions(+), 32 deletions(-) + +diff --git a/src/functions/functions.hook b/src/functions/functions.hook +index fb68037..11887cd 100644 +--- a/src/functions/functions.hook ++++ b/src/functions/functions.hook +@@ -124,6 +124,19 @@ hook_help() { + exit $? + } + ++# Dummy functions being overlayed by hooks ++hook_check_settings() { ++ : ++} ++ ++hook_check_config_settings() { ++ : ++} ++ ++hook_check_port_settings() { ++ : ++} ++ + # Sets all settings in HOOK_SETTINGS to their DEFAULT_* values + hook_set_defaults() { + local setting +diff --git a/src/functions/functions.ports b/src/functions/functions.ports +index fb22715..d8a9140 100644 +--- a/src/functions/functions.ports ++++ b/src/functions/functions.ports +@@ -94,15 +94,9 @@ port_settings_read() { + port_settings_write() { + local port="${1}" + assert isset port +- shift +- +- local args +- if function_exists "hook_check_settings"; then +- list_append args "--check=\"hook_check_settings\"" +- fi +- list_append args HOOK ${HOOK_SETTINGS[*]} + +- settings_write "$(port_file "${port}")" ${args} ++ settings_write "$(port_file "${port}")" \ ++ --check="hook_check_settings" HOOK ${HOOK_SETTINGS[*]} + } + + port_file() { +diff --git a/src/functions/functions.zone b/src/functions/functions.zone +index a0d3cfb..e81371b 100644 +--- a/src/functions/functions.zone ++++ b/src/functions/functions.zone +@@ -1267,13 +1267,8 @@ zone_settings_write() { + local zone="${1}" + assert isset zone + +- local args +- if function_exists "hook_check_settings"; then +- list_append args "--check=\"hook_check_settings\"" +- fi +- list_append args HOOK ${HOOK_SETTINGS[*]} +- +- settings_write "${NETWORK_ZONES_DIR}/${zone}/settings" ${args} ++ settings_write "${NETWORK_ZONES_DIR}/${zone}/settings" \ ++ --check="hook_check_settings" HOOK ${HOOK_SETTINGS[*]} + } + + zone_settings_set() { +@@ -1328,7 +1323,7 @@ zone_config_settings_read() { + } + + zone_config_settings_write() { +- assert [ $# -ge 2 ] ++ assert [ $# -eq 2 ] + + local zone="${1}" + local hook="${2}" +@@ -1336,14 +1331,9 @@ zone_config_settings_write() { + + assert isset id + +- local args +- if function_exists "hook_check_config_settings"; then +- list_append args "--check=\"hook_check_config_settings\"" +- fi +- list_append args ${HOOK_CONFIG_SETTINGS} +- + local path="${NETWORK_ZONES_DIR}/${zone}/configs/${hook}.${id}" +- settings_write "${path}" ${args} ++ settings_write "${path}" \ ++ --check="hook_check_config_settings" ${HOOK_CONFIG_SETTINGS[*]} + } + + zone_config_settings_destroy() { +@@ -1416,20 +1406,14 @@ zone_port_settings_read() { + } + + zone_port_settings_write() { +- assert [ $# -ge 2 ] ++ assert [ $# -eq 2 ] + + local zone="${1}" + local port="${2}" +- shift 2 +- +- local args +- if function_exists "hook_check_port_settings"; then +- list_append args "--check=\"hook_check_port_settings\"" +- fi +- list_append args ${HOOK_PORT_SETTINGS} + + local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}" +- settings_write "${path}" ${args} ++ settings_write "${path}" \ ++ --check="hook_check_port_settings" ${HOOK_PORT_SETTINGS[*]} + } + + zone_port_settings_remove() { +-- +2.39.2 + diff --git a/network/patches/0038-ports-Drop-HOOK_SETTINGS-variable.patch b/network/patches/0038-ports-Drop-HOOK_SETTINGS-variable.patch new file mode 100644 index 000000000..87b3a1f12 --- /dev/null +++ b/network/patches/0038-ports-Drop-HOOK_SETTINGS-variable.patch @@ -0,0 +1,239 @@ +From eba9fa9c0b647552d8a43fb6ff5ab00c2ab21402 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 14:14:56 +0100 +Subject: [PATCH 038/304] ports: Drop HOOK_SETTINGS variable + +This does not need to be passed to the port_settings_* functions +any more which makes them more easy to use + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/bonding | 12 ++++++------ + src/hooks/ports/dummy | 6 +++--- + src/hooks/ports/ethernet | 6 +++--- + src/hooks/ports/ip-tunnel | 4 ++-- + src/hooks/ports/vlan | 8 ++++---- + src/hooks/ports/wireless-ap | 2 +- + src/hooks/ports/wireless-mesh | 4 ++-- + 7 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding +index 09fb74f..a0cf5c0 100644 +--- a/src/hooks/ports/bonding ++++ b/src/hooks/ports/bonding +@@ -116,7 +116,7 @@ hook_new() { + assert isset port + + # Save configuration +- if port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then ++ if port_settings_write "${port}"; then + log INFO "New port ${port} has been created" + else + error "Could not save configuration for ${port}" +@@ -168,7 +168,7 @@ hook_create() { + # Exit silently if the device already exists + device_exists "${port}" && exit ${EXIT_OK} + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Create the bonding devices + bonding_create "${port}" \ +@@ -184,7 +184,7 @@ hook_remove() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Remove the bonding device + if device_exists "${port}"; then +@@ -196,7 +196,7 @@ hook_up() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Auto-enable or disable hardware offloading + if ! isset OFFLOADING || enabled OFFLOADING; then +@@ -219,7 +219,7 @@ hook_down() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Bring down all slaves + local slave +@@ -240,7 +240,7 @@ hook_hotplug() { + # Handle events of the same interface + if hotplug_event_port_is_interface "${port}"; then + # Read configuration +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Bring up all slaves + # Attach those which already exist and try to create +diff --git a/src/hooks/ports/dummy b/src/hooks/ports/dummy +index 1c4b3c9..387c88b 100644 +--- a/src/hooks/ports/dummy ++++ b/src/hooks/ports/dummy +@@ -62,7 +62,7 @@ hook_new() { + local port=$(port_find_free ${DUMMY_PORT_PATTERN}) + assert isset port + +- if port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then ++ if port_settings_write "${port}"; then + log INFO "New dummy port '${port}' has been created" + fi + +@@ -74,7 +74,7 @@ hook_create() { + assert isset port + + # Read configuration +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Create the dummy device + dummy_create "${port}" "${ADDRESS}" +@@ -117,7 +117,7 @@ hook_hotplug_rename() { + local device=${2} + assert isset device + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + if [ "${ADDRESS}" = "$(device_get_address ${device})" ]; then + log DEBUG "Device '${device}' equals port '${port}'." +diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet +index f3e3f9f..5f76e15 100644 +--- a/src/hooks/ports/ethernet ++++ b/src/hooks/ports/ethernet +@@ -117,7 +117,7 @@ hook_new() { + + local DEVICE="$(device_get_address "${device}")" + +- if ! port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then ++ if ! port_settings_write "${port}"; then + log ERROR "Could not write settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -133,7 +133,7 @@ hook_up() { + local port="${1}" + + local ${HOOK_SETTINGS[*]} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then ++ if ! port_settings_read "${port}"; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -180,7 +180,7 @@ hook_hotplug_rename() { + assert isset device + + # Read in the conifguration file. +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Get the current MAC address of the device. + local address=$(device_get_address ${device}) +diff --git a/src/hooks/ports/ip-tunnel b/src/hooks/ports/ip-tunnel +index b426963..fa7193c 100644 +--- a/src/hooks/ports/ip-tunnel ++++ b/src/hooks/ports/ip-tunnel +@@ -115,7 +115,7 @@ hook_create() { + assert isset port + + local ${HOOK_SETTINGS[*]} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then ++ if ! port_settings_read "${port}"; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +@@ -153,7 +153,7 @@ hook_hotplug_rename() { + assert isset device + + local ${HOOK_SETTINGS[*]} +- if ! port_settings_read "${port}" ${HOOK_SETTINGS[*]}; then ++ if ! port_settings_read "${port}"; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index e9aa545..f511986 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -72,7 +72,7 @@ hook_new() { + + local port="${PARENT_DEVICE}${VLAN_PORT_INTERFIX}${TAG}" + +- port_settings_write "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_write "${port}" + + exit ${EXIT_OK} + } +@@ -82,7 +82,7 @@ hook_edit() { + assert isset port + shift + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + while [ $# -gt 0 ]; do + case "${1}" in +@@ -96,7 +96,7 @@ hook_edit() { + shift + done + +- port_settings_write "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_write "${port}" + + exit ${EXIT_OK} + } +@@ -108,7 +108,7 @@ hook_create() { + device_exists "${port}" && exit ${EXIT_OK} + + # Read configruation +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Create the VLAN device + vlan_create "${port}" "${PARENT_DEVICE}" "${TAG}" "${ADDRESS}" +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 8d495d2..e393f5f 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -197,7 +197,7 @@ hook_create() { + + device_exists "${port}" && exit ${EXIT_OK} + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Check if the PHY is present. + local phy=$(phy_get ${PHY}) +diff --git a/src/hooks/ports/wireless-mesh b/src/hooks/ports/wireless-mesh +index 306263d..35f0950 100644 +--- a/src/hooks/ports/wireless-mesh ++++ b/src/hooks/ports/wireless-mesh +@@ -90,7 +90,7 @@ hook_create() { + assert isset port + + # Read settings +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + # Check if the PHY is present. + local phy="$(phy_get "${PHY}")" +@@ -149,7 +149,7 @@ hook_hotplug() { + local port="${1}" + assert isset port + +- port_settings_read "${port}" ${HOOK_SETTINGS[*]} ++ port_settings_read "${port}" + + case "$(hotplug_action)" in + add) +-- +2.39.2 + diff --git a/network/patches/0039-hotplug-Remove-multiple-copies-of-the-same-function.patch b/network/patches/0039-hotplug-Remove-multiple-copies-of-the-same-function.patch new file mode 100644 index 000000000..ee5f6592e --- /dev/null +++ b/network/patches/0039-hotplug-Remove-multiple-copies-of-the-same-function.patch @@ -0,0 +1,162 @@ +From 12f9c8d2550c8fcab536bb8b971caddfa8ee0c80 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 14:58:12 +0100 +Subject: [PATCH 039/304] hotplug: Remove multiple copies of the same function + +Signed-off-by: Michael Tremer +--- + src/header-port | 26 ++++++++++++++++++++++++++ + src/hooks/ports/dummy | 36 +----------------------------------- + src/hooks/ports/ethernet | 22 +--------------------- + src/hooks/ports/ip-tunnel | 23 +---------------------- + 4 files changed, 29 insertions(+), 78 deletions(-) + +diff --git a/src/header-port b/src/header-port +index 2d8a820..d75fdd8 100644 +--- a/src/header-port ++++ b/src/header-port +@@ -42,6 +42,32 @@ hook_hotplug_rename() { + exit ${EXIT_FALSE} + } + ++hook_hotplug_rename_by_address() { ++ local port="${1}" ++ assert isset port ++ ++ local device="${2}" ++ assert isset device ++ ++ # Read in the conifguration file. ++ if ! port_settings_read "${port}"; then ++ return ${EXIT_ERROR} ++ fi ++ ++ # Get the current MAC address of the device. ++ local address="$(device_get_address "${device}")" ++ assert isset address ++ ++ # Check if the address matches with the configuration. ++ if list_match "${address}" "${ADDRESS}" "${DEVICE}"; then ++ log DEBUG "Device '${device}' is port '${port}'" ++ return ${EXIT_OK} ++ fi ++ ++ log DEBUG "Device '${device}' is not port '${port}'" ++ return ${EXIT_ERROR} ++} ++ + hook_default_new() { + local ${HOOK_SETTINGS[*]} + +diff --git a/src/hooks/ports/dummy b/src/hooks/ports/dummy +index 387c88b..3688831 100644 +--- a/src/hooks/ports/dummy ++++ b/src/hooks/ports/dummy +@@ -90,40 +90,6 @@ hook_remove() { + dummy_remove "${port}" + } + +-hook_up() { +- local port="${1}" +- assert isset port +- +- # Bring up the port. +- device_set_up ${port} +- +- exit ${EXIT_OK} +-} +- +-hook_down() { +- local port="${1}" +- assert isset port +- +- # Tear down the port. +- device_set_down ${port} +- +- exit ${EXIT_OK} +-} +- + hook_hotplug_rename() { +- local port=${1} +- assert isset port +- +- local device=${2} +- assert isset device +- +- port_settings_read "${port}" +- +- if [ "${ADDRESS}" = "$(device_get_address ${device})" ]; then +- log DEBUG "Device '${device}' equals port '${port}'." +- exit ${EXIT_OK} +- fi +- +- log DEBUG "Device '${device}' does not equal port '${port}'." +- exit ${EXIT_ERROR} ++ hook_hotplug_rename_by_address "$@" + } +diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet +index 5f76e15..82664fa 100644 +--- a/src/hooks/ports/ethernet ++++ b/src/hooks/ports/ethernet +@@ -173,25 +173,5 @@ hook_remove() { + } + + hook_hotplug_rename() { +- local port=${1} +- assert isset port +- +- local device=${2} +- assert isset device +- +- # Read in the conifguration file. +- port_settings_read "${port}" +- +- # Get the current MAC address of the device. +- local address=$(device_get_address ${device}) +- assert isset address +- +- # Check if the address matches with the configuration. +- if list_match "${address}" ${DEVICE} ${ADDRESS}; then +- log DEBUG "Device '${device}' equals port '${port}'." +- exit ${EXIT_OK} +- fi +- +- log DEBUG "Device '${device}' does not equal port '${port}'." +- exit ${EXIT_ERROR} ++ hook_hotplug_rename_by_address "$@" + } +diff --git a/src/hooks/ports/ip-tunnel b/src/hooks/ports/ip-tunnel +index fa7193c..482511e 100644 +--- a/src/hooks/ports/ip-tunnel ++++ b/src/hooks/ports/ip-tunnel +@@ -146,26 +146,5 @@ hook_remove() { + } + + hook_hotplug_rename() { +- local port="${1}" +- assert isset port +- +- local device="${2}" +- assert isset device +- +- local ${HOOK_SETTINGS[*]} +- if ! port_settings_read "${port}"; then +- log ERROR "Could not read settings for port ${port}" +- return ${EXIT_ERROR} +- fi +- +- # Get the current MAC address of the device. +- local address="$(device_get_address ${device})" +- assert isset address +- +- # Return OK on match +- if [ "${ADDRESS}" = "${address}" ]; then +- return ${EXIT_OK} +- fi +- +- return ${EXIT_ERROR} ++ hook_hotplug_rename_by_address "$@" + } +-- +2.39.2 + diff --git a/network/patches/0040-wireless-ap-Remove-support-for-WPA.patch b/network/patches/0040-wireless-ap-Remove-support-for-WPA.patch new file mode 100644 index 000000000..7ec95a7b1 --- /dev/null +++ b/network/patches/0040-wireless-ap-Remove-support-for-WPA.patch @@ -0,0 +1,58 @@ +From 66fdbcaf15d3fb7ce4a1e0f7e6299818f4638c84 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 15:02:34 +0100 +Subject: [PATCH 040/304] wireless-ap: Remove support for WPA + +This is a deprecated protocol and not secure. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 8 +------- + src/hooks/ports/wireless-ap | 2 +- + 2 files changed, 2 insertions(+), 8 deletions(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 79fb4db..d3eaa74 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -138,7 +138,7 @@ hostapd_config_write() { + + # Check if key is set when encryption is used. + if isset encryption; then +- assert isoneof encryption WPA WPA2 WPA/WPA2 ++ assert isoneof encryption WPA2 + assert isset key + fi + +@@ -398,15 +398,9 @@ hostapd_config_write() { + if isset encryption; then + local encryption_mode=0 + case "${encryption}" in +- WPA) +- encryption_mode=1 +- ;; + WPA2) + encryption_mode=2 + ;; +- WPA/WPA2) +- encryption_mode=3 +- ;; + esac + + ( +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index e393f5f..a964fac 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -65,7 +65,7 @@ hook_check_settings() { + assert isset SSID + + if isset ENCRYPTION; then +- assert isoneof ENCRYPTION WPA WPA2 WPA/WPA2 ++ assert isoneof ENCRYPTION WPA2 + + assert isset KEY + assert [ ${#KEY} -ge 8 ] +-- +2.39.2 + diff --git a/network/patches/0041-wireless-ap-Add-support-for-WPA3-and-rewrite-WPA2.patch b/network/patches/0041-wireless-ap-Add-support-for-WPA3-and-rewrite-WPA2.patch new file mode 100644 index 000000000..55b78d002 --- /dev/null +++ b/network/patches/0041-wireless-ap-Add-support-for-WPA3-and-rewrite-WPA2.patch @@ -0,0 +1,280 @@ +From 0a4c5abab952ae0d864505f037f46cd0a27d6701 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:12:53 +0100 +Subject: [PATCH 041/304] wireless-ap: Add support for WPA3 and rewrite WPA2 + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 90 +++++++++++++++++++++---------- + src/helpers/hostapd-config-helper | 5 +- + src/hooks/ports/wireless-ap | 38 +++++++------ + 3 files changed, 86 insertions(+), 47 deletions(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index d3eaa74..6c2fbd9 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -61,13 +61,14 @@ hostapd_config_write() { + local channel_bandwidth + local country_code="$(wireless_get_reg_domain)" + local dfs="on" +- local encryption + local environment="${WIRELESS_DEFAULT_ENVIRONMENT}" +- local key + local mfp="off" + local mode ++ local secret + local ssid + local wmm="1" ++ local wpa2_personal="off" ++ local wpa3_personal="off" + + while [ $# -gt 0 ]; do + case "${1}" in +@@ -89,9 +90,6 @@ hostapd_config_write() { + --environment=*) + environment="$(cli_get_val "${1}")" + ;; +- --key=*) +- key=$(cli_get_val "${1}") +- ;; + --mfp=*) + mfp="$(cli_get_val "${1}")" + ;; +@@ -103,6 +101,9 @@ hostapd_config_write() { + return ${EXIT_ERROR} + fi + ;; ++ --secret=*) ++ secret="$(cli_get_val "${1}")" ++ ;; + --ssid=*) + ssid=$(cli_get_val "${1}") + ;; +@@ -114,6 +115,12 @@ hostapd_config_write() { + wmm="0" + fi + ;; ++ --wpa2-personal=*) ++ wpa2_personal="$(cli_get_bool "${1}")" ++ ;; ++ --wpa3-personal=*) ++ wpa3_personal="$(cli_get_bool "${1}")" ++ ;; + *) + warning_log "Ignoring unknown argument '${1}'." + ;; +@@ -136,12 +143,6 @@ hostapd_config_write() { + assert isset mode + assert isset ssid + +- # Check if key is set when encryption is used. +- if isset encryption; then +- assert isoneof encryption WPA2 +- assert isset key +- fi +- + # Check wireless environment + if ! wireless_environment_is_valid "${environment}"; then + error "Invalid wireless environment: ${environment}" +@@ -166,6 +167,12 @@ hostapd_config_write() { + return ${EXIT_ERROR} + fi + ++ # Check if secret is set for personal authentication ++ if ! isset secret && (enabled WPA3_PERSONAL || enabled WPA2_PERSONAL); then ++ error "Secret not set but personal authentication enabled" ++ return ${EXIT_ERROR} ++ fi ++ + # 802.11ac/n flags + local ieee80211ac + local ieee80211n +@@ -394,27 +401,52 @@ hostapd_config_write() { + print + ) >> ${file} + +- # Encryption settings +- if isset encryption; then +- local encryption_mode=0 +- case "${encryption}" in +- WPA2) +- encryption_mode=2 +- ;; +- esac ++ # Authentication Settings ++ local wpa ++ local wpa_key_mgmt ++ local wpa_passphrase ++ local sae_password ++ local wpa_strict_rekey ++ ++ # WPA3 Personal ++ if enabled WPA3_PERSONAL; then ++ # Enable RSN ++ wpa="2" ++ ++ # Add WPA key management ++ list_append wpa_key_mgmt "SAE" ++ sae_password="${secret}" ++ fi ++ ++ # WPA2 Personal ++ if enabled WPA2_PERSONAL; then ++ # Enable RSN ++ wpa="2" ++ ++ # Add WPA key management ++ list_append wpa_key_mgmt "WPA-PSK-SHA256" "WPA-PSK" ++ wpa_passphrase="${secret}" + +- ( +- print "# Encryption settings" +- print "wpa=${encryption_mode}" +- print "wpa_passphrase=${key}" +- print "wpa_key_mgmt=WPA-PSK-SHA256 WPA-PSK" +- print "wpa_pairwise=${pairwise_ciphers[*]}" +- print "rsn_pairwise=${pairwise_ciphers[*]}" +- print "group_cipher=${group_ciphers[*]}" +- print +- ) >> ${file} ++ # Enable WPA strict rekey ++ wpa_strict_rekey="1" + fi + ++ # Enable RSN ciphers when RSN is enabled ++ local rsn_pairwise ++ local group_cipher ++ if [ "${wpa}" = "2" ]; then ++ rsn_pairwise="${pairwise_ciphers[*]}" ++ group_cipher="${group_ciphers[*]}" ++ fi ++ ++ local var ++ for var in wpa wpa_key_mgmt wpa_passphrase sae_password \ ++ rsn_pairwise group_cipher wpa_strict_rekey; do ++ if [ -n "${!var}" ]; then ++ print "${var}=${!var}" ++ fi ++ done >> "${file}" ++ + # Log configuration file + file_to_log DEBUG "${file}" + +diff --git a/src/helpers/hostapd-config-helper b/src/helpers/hostapd-config-helper +index 7af723d..6d9f685 100644 +--- a/src/helpers/hostapd-config-helper ++++ b/src/helpers/hostapd-config-helper +@@ -42,12 +42,13 @@ case "${action}" in + --channel="${CHANNEL}" \ + --channel-bandwidth="${CHANNEL_BANDWIDTH}" \ + --dfs="${DFS}" \ +- --encryption="${ENCRYPTION}" \ + --environment="${ENVIRONMENT}" \ +- --key="${KEY}" \ ++ --secret="${SECRET}" \ + --mfp="${MFP}" \ + --mode="${MODE}" \ + --ssid="${SSID}" \ ++ --wpa3-personal="${WPA3_PERSONAL}" \ ++ --wpa2-personal="${WPA2_PERSONAL}" \ + || exit $? + ;; + +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index a964fac..7176ee5 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -29,15 +29,20 @@ HOOK_SETTINGS=( + "CHANNEL" + "CHANNEL_BANDWIDTH" + "DFS" +- "ENCRYPTION" + "ENVIRONMENT" +- "KEY" + "MFP" + "MODE" + "PHY" ++ "SECRET" + "SSID" ++ "WPA3_PERSONAL" ++ "WPA2_PERSONAL" + ) + ++# Disable WPA3+2 by default ++DEFAULT_WPA3_PERSONAL="off" ++DEFAULT_WPA2_PERSONAL="off" ++ + # Broadcast SSID by default + DEFAULT_BROADCAST_SSID="on" + +@@ -64,14 +69,6 @@ hook_check_settings() { + assert ismac PHY + assert isset SSID + +- if isset ENCRYPTION; then +- assert isoneof ENCRYPTION WPA2 +- +- assert isset KEY +- assert [ ${#KEY} -ge 8 ] +- assert [ ${#KEY} -le 63 ] +- fi +- + assert wireless_environment_is_valid "${ENVIRONMENT}" + } + +@@ -99,9 +96,6 @@ hook_parse_cmdline() { + return ${EXIT_ERROR} + fi + ;; +- --encryption=*) +- ENCRYPTION=$(cli_get_val "${1}") +- ;; + --environment=*) + ENVIRONMENT="$(cli_get_val "${1}")" + +@@ -110,9 +104,6 @@ hook_parse_cmdline() { + return ${EXIT_ERROR} + fi + ;; +- --key=*) +- KEY=$(cli_get_val "${1}") +- ;; + --mac=*) + ADDRESS=$(cli_get_val "${1}") + ;; +@@ -140,9 +131,18 @@ hook_parse_cmdline() { + --phy=*) + PHY=$(cli_get_val "${1}") + ;; ++ --secret=*) ++ SECRET="$(cli_get_val "${1}")" ++ ;; + --ssid=*) + SSID=$(cli_get_val "${1}") + ;; ++ --wpa2-personal=*) ++ WPA2_PERSONAL="$(cli_get_bool "${1}")" ++ ;; ++ --wpa3-personal=*) ++ WPA3_PERSONAL="$(cli_get_bool "${1}")" ++ ;; + *) + warning "Ignoring unknown argument '${1}'" + ;; +@@ -174,6 +174,12 @@ hook_parse_cmdline() { + return ${EXIT_ERROR} + fi + ++ # Check if SECRET is set when WPA* is enabled ++ if ! isset SECRET && (enabled WPA3_PERSONAL || enabled WPA2_PERSONAL); then ++ error "Secret is not set when PSK authentication is enabled" ++ return ${EXIT_ERROR} ++ fi ++ + # Save address of phy do identify it again + PHY=$(phy_get ${PHY}) + PHY=$(phy_get_address ${PHY}) +-- +2.39.2 + diff --git a/network/patches/0042-hotplug-rename-Drop-unused-variable.patch b/network/patches/0042-hotplug-rename-Drop-unused-variable.patch new file mode 100644 index 000000000..bbf85305c --- /dev/null +++ b/network/patches/0042-hotplug-rename-Drop-unused-variable.patch @@ -0,0 +1,27 @@ +From 729cc3a2518ac4db00dd2ab390f7d253154f3333 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:19:24 +0100 +Subject: [PATCH 042/304] hotplug-rename: Drop unused variable + +Signed-off-by: Michael Tremer +--- + src/udev/network-hotplug-rename | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/udev/network-hotplug-rename b/src/udev/network-hotplug-rename +index 903a07c..5f82f7c 100644 +--- a/src/udev/network-hotplug-rename ++++ b/src/udev/network-hotplug-rename +@@ -28,9 +28,6 @@ LOG_DISABLE_STDOUT="true" + # Read network settings + network_settings_read + +-# Setup the locking +-LOCKFILE="${LOCK_DIR}/.network-rename-lock" +- + # Check if the INTERFACE variable is properly set. + assert isset INTERFACE + +-- +2.39.2 + diff --git a/network/patches/0043-hostapd-Allow-WPA2-authentication-only-with-SHA256.patch b/network/patches/0043-hostapd-Allow-WPA2-authentication-only-with-SHA256.patch new file mode 100644 index 000000000..166386eda --- /dev/null +++ b/network/patches/0043-hostapd-Allow-WPA2-authentication-only-with-SHA256.patch @@ -0,0 +1,29 @@ +From 21ef3b742e6031cb40d0da94015aced31fc18be2 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:22:45 +0100 +Subject: [PATCH 043/304] hostapd: Allow WPA2 authentication only with SHA256 + +This experimental change disables support for the legacy WPA2 +authentication that does not support SHA256. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 6c2fbd9..095beb8 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -424,7 +424,7 @@ hostapd_config_write() { + wpa="2" + + # Add WPA key management +- list_append wpa_key_mgmt "WPA-PSK-SHA256" "WPA-PSK" ++ list_append wpa_key_mgmt "WPA-PSK-SHA256" + wpa_passphrase="${secret}" + + # Enable WPA strict rekey +-- +2.39.2 + diff --git a/network/patches/0044-wireless-ap-Enable-802.11w-by-default.patch b/network/patches/0044-wireless-ap-Enable-802.11w-by-default.patch new file mode 100644 index 000000000..fd371582c --- /dev/null +++ b/network/patches/0044-wireless-ap-Enable-802.11w-by-default.patch @@ -0,0 +1,31 @@ +From 298a1ffe3f10ec14416c3aed19bb541553de160a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:23:55 +0100 +Subject: [PATCH 044/304] wireless-ap: Enable 802.11w by default + +This causes some problems on broken Intel systems, but I +guess it is better to prefer security than compatibility in the +default settings. + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/wireless-ap | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 7176ee5..9676369 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -50,8 +50,7 @@ DEFAULT_BROADCAST_SSID="on" + DEFAULT_DFS="on" + + # 802.11w - Management Frame Protection +-# Disable by default because many clients cannot connect when enabled +-DEFAULT_MFP="off" ++DEFAULT_MFP="on" + + DEFAULT_ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" + +-- +2.39.2 + diff --git a/network/patches/0045-hooks-Use-cli_get_bool-convenience-function-where-ev.patch b/network/patches/0045-hooks-Use-cli_get_bool-convenience-function-where-ev.patch new file mode 100644 index 000000000..1b19ff1d9 --- /dev/null +++ b/network/patches/0045-hooks-Use-cli_get_bool-convenience-function-where-ev.patch @@ -0,0 +1,100 @@ +From f6659cc56ecdef375fb868a3a44ada37b4cbfc3c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:30:05 +0100 +Subject: [PATCH 045/304] hooks: Use cli_get_bool convenience function where + ever possible + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/bonding | 11 +---------- + src/hooks/ports/ethernet | 11 +---------- + src/hooks/ports/wireless-ap | 22 ++-------------------- + 3 files changed, 4 insertions(+), 40 deletions(-) + +diff --git a/src/hooks/ports/bonding b/src/hooks/ports/bonding +index a0cf5c0..96cb854 100644 +--- a/src/hooks/ports/bonding ++++ b/src/hooks/ports/bonding +@@ -59,16 +59,7 @@ hook_parse_cmdline() { + MODE=$(cli_get_val "${1}") + ;; + --offloading=*) +- OFFLOADING="$(cli_get_val "${1}")" +- +- if enabled OFFLOADING; then +- OFFLOADING="on" +- elif disabled OFFLOADING; then +- OFFLOADING="off" +- else +- error "Invalid value for offloading: ${OFFLOADING}" +- return ${EXIT_ERROR} +- fi ++ OFFLOADING="$(cli_get_bool "${1}")" + ;; + +*) + local slave=$(cli_get_val "${1:1}") +diff --git a/src/hooks/ports/ethernet b/src/hooks/ports/ethernet +index 82664fa..80b5503 100644 +--- a/src/hooks/ports/ethernet ++++ b/src/hooks/ports/ethernet +@@ -85,16 +85,7 @@ hook_parse_cmdline() { + ;; + + --offloading=*) +- OFFLOADING="$(cli_get_val "${1}")" +- +- if enabled OFFLOADING; then +- OFFLOADING="on" +- elif disabled OFFLOADING; then +- OFFLOADING="off" +- else +- error "Invalid value for offloading: ${OFFLOADING}" +- return ${EXIT_ERROR} +- fi ++ OFFLOADING="$(cli_get_bool "${1}")" + ;; + + *) +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 9676369..2528585 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -84,16 +84,7 @@ hook_parse_cmdline() { + CHANNEL_BANDWIDTH="$(cli_get_val "${1}")" + ;; + --dfs=*) +- DFS="$(cli_get_val "${1}")" +- +- if enabled DFS; then +- DFS="on" +- elif disabled DFS; then +- DFS="off" +- else +- error "Invalid value for DFS: ${DFS}" +- return ${EXIT_ERROR} +- fi ++ DFS="$(cli_get_bool "${1}")" + ;; + --environment=*) + ENVIRONMENT="$(cli_get_val "${1}")" +@@ -107,16 +98,7 @@ hook_parse_cmdline() { + ADDRESS=$(cli_get_val "${1}") + ;; + --mfp=*) +- MFP="$(cli_get_val "${1}")" +- +- if enabled MFP; then +- MFP="on" +- elif disabled MFP; then +- MFP="off" +- else +- error "Invalid value for --mfp: ${MFP}" +- return ${EXIT_ERROR} +- fi ++ MFP="$(cli_get_bool "${1}")" + ;; + --mode=*) + MODE=$(cli_get_val "${1}") +-- +2.39.2 + diff --git a/network/patches/0046-hook-Rename-HOOK_CONFIG_SETTINGS-to-HOOK_SETTINGS.patch b/network/patches/0046-hook-Rename-HOOK_CONFIG_SETTINGS-to-HOOK_SETTINGS.patch new file mode 100644 index 000000000..29b8c1a55 --- /dev/null +++ b/network/patches/0046-hook-Rename-HOOK_CONFIG_SETTINGS-to-HOOK_SETTINGS.patch @@ -0,0 +1,196 @@ +From 636f1b96fc0b60c47cf5636f95b1ee6c856a701c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:54:04 +0100 +Subject: [PATCH 046/304] hook: Rename HOOK_CONFIG_SETTINGS to HOOK_SETTINGS + +Signed-off-by: Michael Tremer +--- + src/functions/functions.zone | 8 ++++---- + src/header-config | 5 ++++- + src/hooks/configs/dhcp | 13 +++++++++---- + src/hooks/configs/ipv6-auto | 15 +++++---------- + src/hooks/configs/pppoe-server | 24 +++++++++--------------- + src/hooks/configs/static | 6 +++++- + 6 files changed, 36 insertions(+), 35 deletions(-) + +diff --git a/src/functions/functions.zone b/src/functions/functions.zone +index e81371b..28fbecd 100644 +--- a/src/functions/functions.zone ++++ b/src/functions/functions.zone +@@ -1312,8 +1312,8 @@ zone_config_settings_read() { + shift 2 + + local args +- if [ $# -eq 0 ] && [ -n "${HOOK_CONFIG_SETTINGS}" ]; then +- list_append args ${HOOK_CONFIG_SETTINGS} ++ if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS[*]}" ]; then ++ list_append args ${HOOK_SETTINGS[*]} + else + list_append args "$@" + fi +@@ -1323,7 +1323,7 @@ zone_config_settings_read() { + } + + zone_config_settings_write() { +- assert [ $# -eq 2 ] ++ assert [ $# -eq 3 ] + + local zone="${1}" + local hook="${2}" +@@ -1333,7 +1333,7 @@ zone_config_settings_write() { + + local path="${NETWORK_ZONES_DIR}/${zone}/configs/${hook}.${id}" + settings_write "${path}" \ +- --check="hook_check_config_settings" ${HOOK_CONFIG_SETTINGS[*]} ++ --check="hook_check_config_settings" HOOK ${HOOK_SETTINGS[*]} + } + + zone_config_settings_destroy() { +diff --git a/src/header-config b/src/header-config +index 4458eaa..baeca5e 100644 +--- a/src/header-config ++++ b/src/header-config +@@ -26,6 +26,9 @@ hook_new() { + local id=$(zone_config_get_new_id ${zone}) + log DEBUG "ID for the config is: ${id}" + ++ # Import all default variables ++ hook_set_defaults ++ + # Parse command line arguments + if ! hook_parse_cmdline "${id}" "$@"; then + # Return an error if the parsing of the cmd line fails +@@ -64,7 +67,7 @@ hook_edit() { + fi + fi + +- local ${HOOK_CONFIG_SETTINGS} ++ local ${HOOK_SETTINGS} + + # If reading the config fails we cannot go on + if ! zone_config_settings_read "${zone}" "${config}"; then +diff --git a/src/hooks/configs/dhcp b/src/hooks/configs/dhcp +index b643022..1ad0694 100644 +--- a/src/hooks/configs/dhcp ++++ b/src/hooks/configs/dhcp +@@ -21,11 +21,13 @@ + + . /usr/lib/network/header-config + +-HOOK_CONFIG_SETTINGS="HOOK ENABLE_IPV6 ENABLE_IPV4" ++HOOK_SETTINGS=( ++ "ENABLE_IPV6" ++ "ENABLE_IPV4" ++) + +-# Default settings. +-ENABLE_IPV6="on" +-ENABLE_IPV4="on" ++DEFAULT_ENABLE_IPV6="on" ++DEFAULT_ENABLE_IPV4="on" + + hook_check_config_settings() { + assert isset ENABLE_IPV6 +@@ -78,6 +80,9 @@ hook_new() { + local id=$(zone_config_get_new_id ${zone}) + log DEBUG "ID for the config is: ${id}" + ++ # Import defaults ++ hook_set_defaults ++ + if ! hook_parse_cmdline "${id}" "$@"; then + # Return an error if the parsing of the cmd line fails + return ${EXIT_ERROR} +diff --git a/src/hooks/configs/ipv6-auto b/src/hooks/configs/ipv6-auto +index 8796723..6fd90a5 100644 +--- a/src/hooks/configs/ipv6-auto ++++ b/src/hooks/configs/ipv6-auto +@@ -21,10 +21,12 @@ + + . /usr/lib/network/header-config + +-HOOK_CONFIG_SETTINGS="HOOK PRIVACY_EXTENSIONS" ++HOOK_SETTINGS=( ++ "PRIVACY_EXTENSIONS" ++) + + # Privacy Extensions are disabled by default +-PRIVACY_EXTENSIONS="off" ++DEFAULT_PRIVACY_EXTENSIONS="off" + + hook_check_config_settings() { + assert isbool PRIVACY_EXTENSIONS +@@ -35,17 +37,10 @@ hook_parse_cmdline() { + shift + + local arg +- + while read arg; do + case "${arg}" in + --privacy-extensions=*) +- local val="$(cli_get_val "${arg}")" +- +- if enabled val; then +- PRIVACY_EXTENSIONS="on" +- else +- PRIVACY_EXTENSIONS="off" +- fi ++ PRIVACY_EXTENSIONS="$(cli_get_bool "${arg}")" + ;; + esac + done <<< "$(args "$@")" +diff --git a/src/hooks/configs/pppoe-server b/src/hooks/configs/pppoe-server +index 6a2c014..4d79549 100644 +--- a/src/hooks/configs/pppoe-server ++++ b/src/hooks/configs/pppoe-server +@@ -21,21 +21,15 @@ + + . /usr/lib/network/header-config + +-HOOK_CONFIG_SETTINGS="HOOK DNS_SERVERS MTU SERVICE_NAME SUBNET MAX_SESSIONS" +- +-# Maximum Transmission Unit. +-MTU=1492 +- +-# Service Name. +-SERVICE_NAME= +- +-# A subnet. Addresses from this subnet will be given to the remote hosts. +-# The net address will be the gateway address for the PPPoE server. +-SUBNET= +- +-# Defines the max. number of sessions per MAC address. +-# 0 = unlimited. +-MAX_SESSIONS=0 ++HOOK_SETTINGS=( ++ "DNS_SERVERS" ++ "MTU" ++ "SERVICE_NAME" ++ "SUBNET MAX_SESSIONS" ++) ++ ++DEFAULT_MTU=1492 ++DEFAULT_MAX_SESSIONS=0 + + hook_check_config_settings() { + assert isset MTU +diff --git a/src/hooks/configs/static b/src/hooks/configs/static +index 23ae2d8..6fddc32 100644 +--- a/src/hooks/configs/static ++++ b/src/hooks/configs/static +@@ -21,7 +21,11 @@ + + . /usr/lib/network/header-config + +-HOOK_CONFIG_SETTINGS="HOOK ADDRESS PREFIX GATEWAY" ++HOOK_SETTINGS=( ++ "ADDRESS" ++ "PREFIX" ++ "GATEWAY" ++) + + hook_check_config_settings() { + local protocol="$(ip_detect_protocol "${ADDRESS}")" +-- +2.39.2 + diff --git a/network/patches/0047-dhcp-Rename-enabled-from-configuration-parameters.patch b/network/patches/0047-dhcp-Rename-enabled-from-configuration-parameters.patch new file mode 100644 index 000000000..a7bf304c6 --- /dev/null +++ b/network/patches/0047-dhcp-Rename-enabled-from-configuration-parameters.patch @@ -0,0 +1,99 @@ +From 8ece5c30bf5917d4cd6dfb460207d1e85eb5df73 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 16:57:31 +0100 +Subject: [PATCH 047/304] dhcp: Rename "enabled" from configuration parameters + +Signed-off-by: Michael Tremer +--- + src/hooks/configs/dhcp | 38 +++++++++++++++----------------------- + 1 file changed, 15 insertions(+), 23 deletions(-) + +diff --git a/src/hooks/configs/dhcp b/src/hooks/configs/dhcp +index 1ad0694..1c75193 100644 +--- a/src/hooks/configs/dhcp ++++ b/src/hooks/configs/dhcp +@@ -22,18 +22,16 @@ + . /usr/lib/network/header-config + + HOOK_SETTINGS=( +- "ENABLE_IPV6" +- "ENABLE_IPV4" ++ "IPV6" ++ "IPV4" + ) + +-DEFAULT_ENABLE_IPV6="on" +-DEFAULT_ENABLE_IPV4="on" ++DEFAULT_IPV6="on" ++DEFAULT_IPV4="on" + + hook_check_config_settings() { +- assert isset ENABLE_IPV6 +- assert isbool ENABLE_IPV6 +- assert isset ENABLE_IPV4 +- assert isbool ENABLE_IPV4 ++ assert isbool IPV6 ++ assert isbool IPV4 + } + + hook_parse_cmdline() { +@@ -42,17 +40,11 @@ hook_parse_cmdline() { + + while [ $# -gt 0 ]; do + case "${1}" in +- --enable-ipv6) +- ENABLE_IPV6="on" ++ --ipv6) ++ IPV6="$(cli_get_bool "${1}")" + ;; +- --disable-ipv6) +- ENABLE_IPV6="off" +- ;; +- --enable-ipv4) +- ENABLE_IPV4="on" +- ;; +- --disable-ipv4) +- ENABLE_IPV4="off" ++ --ipv4) ++ IPV4="$(cli_get_bool "${1}")" + ;; + *) + warning "Ignoring unknown option '${1}'" +@@ -62,8 +54,8 @@ hook_parse_cmdline() { + done + + # Check if the user disabled ipv6 and ipv4 +- if ! enabled ENABLE_IPV6 && ! enabled ENABLE_IPV4; then +- log ERROR "You disabled IPv6 and IPv4. At least one must be enabled" ++ if ! enabled IPV6 && ! enabled IPV4; then ++ error "You disabled IPv6 and IPv4. At least one must be enabled" + return ${EXIT_ERROR} + fi + } +@@ -106,12 +98,12 @@ hook_up() { + zone_config_settings_read "${zone}" "${config}" + + # Start dhclient for IPv6 on this zone if enabled. +- if enabled ENABLE_IPV6; then ++ if enabled IPV6; then + dhclient_start ${zone} ipv6 + fi + + # Start dhclient for IPv4 on this zone if enabled. +- if enabled ENABLE_IPV4; then ++ if enabled IPV4; then + dhclient_start ${zone} ipv4 + fi + +@@ -165,7 +157,7 @@ hook_status() { + + cli_print_fmt1 3 "${proto}" + +- if enabled ENABLE_${proto^^}; then ++ if enabled "${proto^^}"; then + cli_print_fmt1 4 "Status" "enabled" + + local address="$(db_get "${zone}/${_proto}/local-ip-address")" +-- +2.39.2 + diff --git a/network/patches/0048-dhcp-Fix-syntax-error-in-last-commit.patch b/network/patches/0048-dhcp-Fix-syntax-error-in-last-commit.patch new file mode 100644 index 000000000..1f085d2ed --- /dev/null +++ b/network/patches/0048-dhcp-Fix-syntax-error-in-last-commit.patch @@ -0,0 +1,30 @@ +From e80eb68607dbdad381e3bb113521609c44fa8cd6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 17:05:44 +0100 +Subject: [PATCH 048/304] dhcp: Fix syntax error in last commit + +Signed-off-by: Michael Tremer +--- + src/hooks/configs/dhcp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/hooks/configs/dhcp b/src/hooks/configs/dhcp +index 1c75193..ba5608a 100644 +--- a/src/hooks/configs/dhcp ++++ b/src/hooks/configs/dhcp +@@ -40,10 +40,10 @@ hook_parse_cmdline() { + + while [ $# -gt 0 ]; do + case "${1}" in +- --ipv6) ++ --ipv6=*) + IPV6="$(cli_get_bool "${1}")" + ;; +- --ipv4) ++ --ipv4=*) + IPV4="$(cli_get_bool "${1}")" + ;; + *) +-- +2.39.2 + diff --git a/network/patches/0049-hooks-Add-HOOK_UNIQUE-which-stops-us-from-creating-m.patch b/network/patches/0049-hooks-Add-HOOK_UNIQUE-which-stops-us-from-creating-m.patch new file mode 100644 index 000000000..d790e6c64 --- /dev/null +++ b/network/patches/0049-hooks-Add-HOOK_UNIQUE-which-stops-us-from-creating-m.patch @@ -0,0 +1,158 @@ +From fdd9ac5fdd66b6cbdf014554281a9bb11ed0379d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 17:05:58 +0100 +Subject: [PATCH 049/304] hooks: Add HOOK_UNIQUE which stops us from creating + multiple instances + +Signed-off-by: Michael Tremer +--- + src/header-config | 9 +++++++++ + src/hooks/configs/dhcp | 25 ------------------------- + src/hooks/configs/ipv6-auto | 22 ---------------------- + src/hooks/configs/pppoe-server | 22 ---------------------- + src/hooks/configs/static | 3 +++ + 5 files changed, 12 insertions(+), 69 deletions(-) + +diff --git a/src/header-config b/src/header-config +index baeca5e..c6a775c 100644 +--- a/src/header-config ++++ b/src/header-config +@@ -19,10 +19,19 @@ + # # + ############################################################################### + ++# Allow only one instance of this hook ++HOOK_UNIQUE="true" ++ + hook_new() { + local zone="${1}" + shift + ++ # Check if we are allowed to have multiple configurations of $HOOK ++ if enabled HOOK_UNIQUE && zone_config_hook_is_configured "${zone}" "${HOOK}"; then ++ error "You can only have one configuration of type ${HOOK}" ++ return ${EXIT_CONF_ERROR} ++ fi ++ + local id=$(zone_config_get_new_id ${zone}) + log DEBUG "ID for the config is: ${id}" + +diff --git a/src/hooks/configs/dhcp b/src/hooks/configs/dhcp +index ba5608a..127ce59 100644 +--- a/src/hooks/configs/dhcp ++++ b/src/hooks/configs/dhcp +@@ -60,31 +60,6 @@ hook_parse_cmdline() { + fi + } + +-hook_new() { +- local zone="${1}" +- shift +- +- if zone_config_hook_is_configured ${zone} "dhcp"; then +- log ERROR "You can configure the dhcp hook only once for a zone" +- return ${EXIT_ERROR} +- fi +- +- local id=$(zone_config_get_new_id ${zone}) +- log DEBUG "ID for the config is: ${id}" +- +- # Import defaults +- hook_set_defaults +- +- if ! hook_parse_cmdline "${id}" "$@"; then +- # Return an error if the parsing of the cmd line fails +- return ${EXIT_ERROR} +- fi +- +- zone_config_settings_write "${zone}" "${HOOK}" "${id}" +- +- exit ${EXIT_OK} +-} +- + hook_up() { + local zone=${1} + local config=${2} +diff --git a/src/hooks/configs/ipv6-auto b/src/hooks/configs/ipv6-auto +index 6fd90a5..ecfafcd 100644 +--- a/src/hooks/configs/ipv6-auto ++++ b/src/hooks/configs/ipv6-auto +@@ -46,28 +46,6 @@ hook_parse_cmdline() { + done <<< "$(args "$@")" + } + +-hook_new() { +- local zone="${1}" +- shift +- +- if zone_config_hook_is_configured ${zone} "ipv6-auto"; then +- log ERROR "You can configure the ipv6-auto hook only once for a zone" +- return ${EXIT_ERROR} +- fi +- +- local id=$(zone_config_get_new_id ${zone}) +- log DEBUG "ID for the config is: ${id}" +- +- if ! hook_parse_cmdline "${id}" "$@"; then +- # Return an error if the parsing of the cmd line fails +- return ${EXIT_ERROR} +- fi +- +- zone_config_settings_write "${zone}" "${HOOK}" "${id}" +- +- exit ${EXIT_OK} +-} +- + hook_up() { + local zone=${1} + shift +diff --git a/src/hooks/configs/pppoe-server b/src/hooks/configs/pppoe-server +index 4d79549..e800bf4 100644 +--- a/src/hooks/configs/pppoe-server ++++ b/src/hooks/configs/pppoe-server +@@ -93,28 +93,6 @@ hook_parse_cmdline() { + done + } + +-hook_new() { +- local zone=${1} +- shift +- +- if zone_config_hook_is_configured ${zone} "pppoe-server"; then +- log ERROR "You can configure the pppoe-server hook only once for a zone" +- return ${EXIT_ERROR} +- fi +- +- local id=$(zone_config_get_new_id ${zone}) +- log DEBUG "ID for the config is: ${id}" +- +- if ! hook_parse_cmdline "${id}" "$@"; then +- # Return an error if the parsing of the cmd line fails +- return ${EXIT_ERROR} +- fi +- +- zone_config_settings_write "${zone}" "${HOOK}" "${id}" +- +- exit ${EXIT_OK} +-} +- + hook_up() { + local zone=${1} + local config=${2} +diff --git a/src/hooks/configs/static b/src/hooks/configs/static +index 6fddc32..046183a 100644 +--- a/src/hooks/configs/static ++++ b/src/hooks/configs/static +@@ -21,6 +21,9 @@ + + . /usr/lib/network/header-config + ++# Allow multiple instances of this hook ++HOOK_UNIQUE="false" ++ + HOOK_SETTINGS=( + "ADDRESS" + "PREFIX" +-- +2.39.2 + diff --git a/network/patches/0050-wireless-ap-Check-that-secret-has-the-correct-length.patch b/network/patches/0050-wireless-ap-Check-that-secret-has-the-correct-length.patch new file mode 100644 index 000000000..00e9e26ba --- /dev/null +++ b/network/patches/0050-wireless-ap-Check-that-secret-has-the-correct-length.patch @@ -0,0 +1,105 @@ +From d695b280e9972311ae8c4bc688c0898ade1281e6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 18:14:07 +0100 +Subject: [PATCH 050/304] wireless-ap: Check that secret has the correct length + and no invalid characters + +Signed-off-by: Michael Tremer +--- + src/functions/functions.util | 13 +++++++++++++ + src/functions/functions.wireless | 23 +++++++++++------------ + src/hooks/ports/wireless-ap | 14 +++++++++++--- + 3 files changed, 35 insertions(+), 15 deletions(-) + +diff --git a/src/functions/functions.util b/src/functions/functions.util +index 4c1dbb4..7379a98 100644 +--- a/src/functions/functions.util ++++ b/src/functions/functions.util +@@ -745,6 +745,19 @@ contains_spaces() { + return ${EXIT_FALSE} + } + ++contains_non_ascii_characters() { ++ local value="$@" ++ ++ # Strip away all ASCII characters ++ local non_ascii="${value//[[:ascii:]]/}" ++ ++ if isset non_ascii; then ++ return ${EXIT_TRUE} ++ fi ++ ++ return ${EXIT_FALSE} ++} ++ + string_match() { + local match=${1} + local string=${2} +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 12204c0..733a356 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -397,24 +397,23 @@ wireless_set_channel() { + } + + wireless_pre_shared_key_is_valid() { +- local encryption_mode="${1}" +- local psk="${2}" ++ local psk="${1}" + + # Length of the PSK + local l="${#psk}" + +- case "${encryption_mode}" in +- # For WPA*, the key must be between 8 and 63 chars +- WPA2-PSK|WPA2-PSK-SHA256|WPA-PSK|WPA-PSK-SHA256) +- if [ ${l} -ge 8 ] && [ ${l} -le 63 ]; then +- return ${EXIT_TRUE} +- fi ++ # For WPA*, the key must be between 8 and 63 chars ++ if [ ${l} -lt 8 ] || [ ${l} -gt 63 ]; then ++ return ${EXIT_FALSE} ++ fi + +- return ${EXIT_FALSE} +- ;; +- esac ++ # Can only contain ASCII chararcters ++ if contains_non_ascii_characters "${psk}"; then ++ return ${EXIT_FALSE} ++ fi + +- return ${EXIT_ERROR} ++ # Seems OK ++ return ${EXIT_TRUE} + } + + wireless_client_is_connected() { +diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap +index 2528585..26e14d6 100644 +--- a/src/hooks/ports/wireless-ap ++++ b/src/hooks/ports/wireless-ap +@@ -156,9 +156,17 @@ hook_parse_cmdline() { + fi + + # Check if SECRET is set when WPA* is enabled +- if ! isset SECRET && (enabled WPA3_PERSONAL || enabled WPA2_PERSONAL); then +- error "Secret is not set when PSK authentication is enabled" +- return ${EXIT_ERROR} ++ if enabled WPA3_PERSONAL || enabled WPA2_PERSONAL; then ++ if ! isset SECRET; then ++ error "Secret is not set when PSK authentication is enabled" ++ return ${EXIT_ERROR} ++ fi ++ ++ # Check if SECRET is valid ++ if ! wireless_pre_shared_key_is_valid "${SECRET}"; then ++ error "The secret is in an invalid format" ++ return ${EXIT_ERROR} ++ fi + fi + + # Save address of phy do identify it again +-- +2.39.2 + diff --git a/network/patches/0051-Drop-old-locking-functions.patch b/network/patches/0051-Drop-old-locking-functions.patch new file mode 100644 index 000000000..4a0ee12cc --- /dev/null +++ b/network/patches/0051-Drop-old-locking-functions.patch @@ -0,0 +1,235 @@ +From d4564f2b7efa20ea025b6918b012656927fd342a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 18:51:13 +0100 +Subject: [PATCH 051/304] Drop old locking functions + +Signed-off-by: Michael Tremer +--- + src/functions/functions.device | 12 ++---- + src/functions/functions.editor | 51 +++++++++-------------- + src/functions/functions.firewall | 3 +- + src/functions/functions.lock | 70 -------------------------------- + 4 files changed, 26 insertions(+), 110 deletions(-) + +diff --git a/src/functions/functions.device b/src/functions/functions.device +index 48f2440..f52eee5 100644 +--- a/src/functions/functions.device ++++ b/src/functions/functions.device +@@ -997,15 +997,11 @@ device_get_link_string() { + } + + device_auto_configure_smp_affinity() { +- assert [ $# -eq 1 ] +- +- local device=${1} +- +- if lock_acquire "smp-affinity" 60; then +- device_set_smp_affinity ${device} auto ++ local device="${1}" ++ assert isset device + +- lock_release "smp-affinity" +- fi ++ lock "smp-affinity" \ ++ device_set_smp_affinity "${device}" "auto" + } + + device_set_smp_affinity() { +diff --git a/src/functions/functions.editor b/src/functions/functions.editor +index 6edac62..8f0cc0b 100644 +--- a/src/functions/functions.editor ++++ b/src/functions/functions.editor +@@ -19,17 +19,6 @@ + # # + ############################################################################### + +-editor_cleanup() { +- # Cleanup after a file was edited +- assert [ $# -eq 2 ] +- +- local file=${1} +- local temp_file=${2} +- +- lock_release "${file}.lock" +- rm -f ${temp_file} +-} +- + editor_find_best() { + # Open a file with the best available editor + assert [ $# -eq 1 ] +@@ -62,31 +51,26 @@ editor_find_best() { + } + + editor() { +- # This function open a file for editing and take care of all preperation and postprocessing +- assert [ $# -ge 1 ] ++ local file="${1}" ++ assert isset file + +- local file=${1} + if [ ! -f ${file} ] || [ ! -w ${file} ]; then + error "${file} is not valid file or is not writeable" + return ${EXIT_ERROR} + fi + +- local check_func=${2} ++ lock "${file}.lock" __editor "$@" ++} + +- # check if the file is locked +- if lock_exists "${file}.lock"; then +- error "Cannot edit ${file} because it is locked" +- return ${EXIT_ERROR} +- fi ++__editor() { ++ # This function open a file for editing and take care of all preperation and postprocessing ++ assert [ $# -ge 1 ] + +- # lock the file +- if ! lock_acquire "${file}.lock"; then +- error "Cannot lock file ${file}" +- return ${EXIT_ERROR} +- fi ++ local file="${1}" ++ local check_func="${2}" + + # create a temporary file +- local temp_file=$(mktemp) ++ local temp_file="$(mktemp)" + + if ! [ -f "${temp_file}" ]; then + error "Cannot create temporary file" +@@ -98,21 +82,26 @@ editor() { + # edit the file + if ! editor_find_best "${temp_file}"; then + error "Could not edit ${file}" +- # cleanup +- editor_cleanup "${file}" "${temp_file}" ++ ++ # Delete temporary file ++ file_delete "${temp_file}" ++ ++ return ${EXIT_ERROR} + fi + + # run the check if we have one + if isset check_func && ! editor_check "${check_func}" "${temp_file}"; then ++ # Delete temporary file ++ file_delete "${temp_file}" ++ + return ${EXIT_ERROR} + fi + + # copy the changes back + cp -f "${temp_file}" "${file}" + +- # cleanup +- editor_cleanup "${file}" "${temp_file}" +- ++ # Delete temporary file ++ file_delete "${temp_file}" + } + + editor_check() { +diff --git a/src/functions/functions.firewall b/src/functions/functions.firewall +index 347916e..e22576b 100644 +--- a/src/functions/functions.firewall ++++ b/src/functions/functions.firewall +@@ -269,7 +269,8 @@ firewall_panic() { + } + + firewall_lock_acquire() { +- lock_acquire ${RUN_DIR}/.firewall_lock ++ # XXX DEPRECATED ++ #lock_acquire ${RUN_DIR}/.firewall_lock + + # Make sure the lock is released after the firewall + # script has crashed or exited early. +diff --git a/src/functions/functions.lock b/src/functions/functions.lock +index 6295a22..fd15e5e 100644 +--- a/src/functions/functions.lock ++++ b/src/functions/functions.lock +@@ -19,16 +19,6 @@ + # # + ############################################################################### + +-__lock_path() { +- local name=${1} +- +- if [ "${name:0:1}" = "/" ]; then +- echo "${name}" +- else +- echo "${LOCK_DIR}/network-${name}" +- fi +-} +- + lock() { + local lock="${1}" + shift +@@ -65,63 +55,3 @@ lock() { + exit ${ret} + ) 9>${lock} || exit $? + } +- +-lock_exists() { +- local name=${1} +- assert isset name +- +- local lockfile=$(__lock_path ${name}) +- +- if [ -e "${lockfile}" ]; then +- return ${EXIT_TRUE} +- else +- return ${EXIT_FALSE} +- fi +-} +- +-lock_acquire() { +- local name=${1} +- assert isset name +- +- # timeout value in seconds +- local timeout=${2} +- +- if ! isset timeout; then +- timeout=0 +- fi +- +- local lockfile=$(__lock_path ${name}) +- +- timeout=$(( ${timeout} * 4 )) +- +- log DEBUG "Acquiring lock '${name}'" +- +- # Wait until lock is available +- while [ ${timeout} -gt 0 ] && [ -e "${lockfile}" ]; do +- timeout=$(( ${timeout} - 1 )) +- sleep 0.25 +- done +- +- # If another lock still exists, we return an error +- if [ -e "${lockfile}" ]; then +- error "Could not acquire lock '${name}'" +- return ${EXIT_ERROR} +- fi +- +- # Write out pid to the lockfile and make sure that +- # nobody else can access it. +- echo "$$" > ${lockfile} +- chmod 600 ${lockfile} +-} +- +-lock_release() { +- local name=${1} +- assert isset name +- +- local lockfile=$(__lock_path ${name}) +- +- log DEBUG "Releasing lock '${name}'" +- +- # Remove the lockfile (okay if it does not exist). +- rm -f ${lockfile} +-} +-- +2.39.2 + diff --git a/network/patches/0052-ip-tunnel-Enable-support-for-6in4-tunnels.patch b/network/patches/0052-ip-tunnel-Enable-support-for-6in4-tunnels.patch new file mode 100644 index 000000000..403991b84 --- /dev/null +++ b/network/patches/0052-ip-tunnel-Enable-support-for-6in4-tunnels.patch @@ -0,0 +1,26 @@ +From 55dcff454fa68dc2ff82f3dfbbafd75d3799b0ae Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 18:56:04 +0100 +Subject: [PATCH 052/304] ip-tunnel: Enable support for 6in4 tunnels + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/ip-tunnel | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hooks/zones/ip-tunnel b/src/hooks/zones/ip-tunnel +index 634154e..c4a4fb4 100644 +--- a/src/hooks/zones/ip-tunnel ++++ b/src/hooks/zones/ip-tunnel +@@ -21,7 +21,7 @@ + + . /usr/lib/network/header-zone + +-SUPPORTED_IP_TUNNEL_MODES="gre vti" ++SUPPORTED_IP_TUNNEL_MODES="gre sit vti" + + HOOK_SETTINGS=( + "MARK" +-- +2.39.2 + diff --git a/network/patches/0053-lock-Cleanup-lock-files.patch b/network/patches/0053-lock-Cleanup-lock-files.patch new file mode 100644 index 000000000..44176d537 --- /dev/null +++ b/network/patches/0053-lock-Cleanup-lock-files.patch @@ -0,0 +1,37 @@ +From 1ed79f5432d0bd4c4f0c8f8692b488c268e379a4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 30 Mar 2019 19:03:24 +0100 +Subject: [PATCH 053/304] lock: Cleanup lock files + +Signed-off-by: Michael Tremer +--- + src/functions/functions.lock | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.lock b/src/functions/functions.lock +index fd15e5e..c01fcf3 100644 +--- a/src/functions/functions.lock ++++ b/src/functions/functions.lock +@@ -29,6 +29,7 @@ lock() { + fi + + local timeout="60" ++ local ret=0 + + # Make partent directory + make_parent_directory "${lock}" +@@ -53,5 +54,10 @@ lock() { + log DEBUG "Released lock ${lock}" + + exit ${ret} +- ) 9>${lock} || exit $? ++ ) 9>${lock} || ret=$? ++ ++ # Cleanup log file ++ file_delete "${lock}" ++ ++ return ${ret} + } +-- +2.39.2 + diff --git a/network/patches/0054-hostapd-Require-MFP-for-SAE-when-it-is-enabled.patch b/network/patches/0054-hostapd-Require-MFP-for-SAE-when-it-is-enabled.patch new file mode 100644 index 000000000..2b20f4cbd --- /dev/null +++ b/network/patches/0054-hostapd-Require-MFP-for-SAE-when-it-is-enabled.patch @@ -0,0 +1,45 @@ +From 1ef692c599a77fcb0683e3196b8f4b56f52644da Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 13:10:30 +0200 +Subject: [PATCH 054/304] hostapd: Require MFP for SAE when it is enabled + +Signed-off-by: Michael Tremer +--- + src/functions/functions.hostapd | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.hostapd b/src/functions/functions.hostapd +index 095beb8..410e6e5 100644 +--- a/src/functions/functions.hostapd ++++ b/src/functions/functions.hostapd +@@ -407,6 +407,7 @@ hostapd_config_write() { + local wpa_passphrase + local sae_password + local wpa_strict_rekey ++ local sae_require_mfp + + # WPA3 Personal + if enabled WPA3_PERSONAL; then +@@ -416,6 +417,10 @@ hostapd_config_write() { + # Add WPA key management + list_append wpa_key_mgmt "SAE" + sae_password="${secret}" ++ ++ if enabled MFP; then ++ sae_require_mfp="1" ++ fi + fi + + # WPA2 Personal +@@ -441,7 +446,7 @@ hostapd_config_write() { + + local var + for var in wpa wpa_key_mgmt wpa_passphrase sae_password \ +- rsn_pairwise group_cipher wpa_strict_rekey; do ++ rsn_pairwise group_cipher wpa_strict_rekeyi sae_require_mfp; do + if [ -n "${!var}" ]; then + print "${var}=${!var}" + fi +-- +2.39.2 + diff --git a/network/patches/0055-bird-Write-IPv6-router-advertisement-configuration.patch b/network/patches/0055-bird-Write-IPv6-router-advertisement-configuration.patch new file mode 100644 index 000000000..32dc97ba2 --- /dev/null +++ b/network/patches/0055-bird-Write-IPv6-router-advertisement-configuration.patch @@ -0,0 +1,117 @@ +From 7a3747a1b0d2e219600979aa4286e8ffd96d5b59 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 14:14:55 +0200 +Subject: [PATCH 055/304] bird: Write IPv6 router advertisement configuration + +Signed-off-by: Michael Tremer +--- + src/functions/functions.bird | 89 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 89 insertions(+) + +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index c6fea32..950bb78 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -84,6 +84,9 @@ bird_generate_config() { + print "}" + print + done >> ${BIRD_CONF} ++ ++ # Write IPv6 Router Advertisement configuration ++ __bird_ipv6_radv >> ${BIRD_CONF} + } + + __bird_static_routes() { +@@ -122,3 +125,89 @@ __bird_static_routes() { + esac + done < ${NETWORK_CONFIG_ROUTES} + } ++ ++__bird_ipv6_radv() { ++ print "protocol radv {" ++ ++ local zone ++ for zone in $(zones_get_local); do ++ log DEBUG "Writing bird radv configuration for ${zone}" ++ ++ # Skip if there is no prefix or prefix is link-local. ++ local addr="$(db_get "${zone}/ipv6/local-ip-address")" ++ if [ -z "${addr}" ] || [ "${addr:0:5}" = "fe80:" ]; then ++ continue ++ fi ++ ++ # Check if the subnet is configured by the DHCP server. ++ local dhcp="false" ++ local prefix="$(ipv6_get_network "${addr}")" ++ if isset prefix && dhcpd_subnet_match ipv6 "${prefix}"; then ++ dhcp="true" ++ fi ++ ++ print " interface \"${zone}\" {" ++ # Failover to other routers within 10s ++ print " max ra interval 10;" ++ ++ # Tell clients we are running DHCP ++ if enabled dhcp; then ++ print " managed yes;" ++ print " other config yes;" ++ fi ++ ++ if device_exists "${zone}"; then ++ # Announce link MTU ++ local mtu="$(device_get_mtu "${zone}")" ++ print " link mtu ${mtu};" ++ fi ++ ++ print # empty line ++ ++ # Announce all prefixes ++ print " prefix ::/0 {" ++ ++ if enabled dhcp; then ++ print " autonomous off;" ++ fi ++ ++ print " };" ++ print " };\n" ++ done ++ ++ # Advertise any DNS servers ++ if enabled DNS_ADVERTISE_SERVERS; then ++ # Get a list of all IPv6 name servers ++ local servers=() ++ local server ++ for server in $(dns_server_list_sorted); do ++ # Skip any non-IPv6 servers ++ ipv6_is_valid "${server}" || continue ++ ++ servers+=( "${server}" ) ++ done ++ ++ if isset servers; then ++ print " rdnss {" ++ ++ local server ++ for server in ${servers}; do ++ print " ns ${server};" ++ done ++ ++ print " };" ++ fi ++ fi ++ ++ # DNS Search Domain ++ print " dnssl {" ++ ++ local domain ++ for domain in $(dns_get_search_domains); do ++ print " domain \"${domain}\";" ++ done ++ ++ print " };" ++ ++ print "}\n" ++} +-- +2.39.2 + diff --git a/network/patches/0056-Drop-code-for-radvd.patch b/network/patches/0056-Drop-code-for-radvd.patch new file mode 100644 index 000000000..52241fd28 --- /dev/null +++ b/network/patches/0056-Drop-code-for-radvd.patch @@ -0,0 +1,314 @@ +From 1cb20d39b29a1bd73cef2926cc4aae651f653ca7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 14:20:40 +0200 +Subject: [PATCH 056/304] Drop code for radvd + +This is now being replaced by bird. + +Bird is running anyways and can do this job just as well. + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 - + src/functions/functions.bird | 11 +++ + src/functions/functions.dns | 8 +- + src/functions/functions.radvd | 160 -------------------------------- + src/functions/functions.routing | 4 +- + src/network-radvd-config | 35 ------- + 6 files changed, 17 insertions(+), 203 deletions(-) + delete mode 100644 src/functions/functions.radvd + delete mode 100644 src/network-radvd-config + +diff --git a/Makefile.am b/Makefile.am +index 1b5e7e9..ce587b7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -173,7 +173,6 @@ dist_network_DATA = \ + src/functions/functions.ports \ + src/functions/functions.ppp \ + src/functions/functions.pppoe-server \ +- src/functions/functions.radvd \ + src/functions/functions.route \ + src/functions/functions.routing \ + src/functions/functions.serial \ +@@ -193,7 +192,6 @@ dist_network_DATA = \ + src/functions/functions.wireless-networks \ + src/functions/functions.wpa_supplicant \ + src/functions/functions.zone \ +- src/network-radvd-config \ + src/header-config \ + src/header-port \ + src/header-zone +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index 950bb78..55d43b5 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -33,6 +33,17 @@ bird_reload() { + service_reload "bird.service" + } + ++# Update configuration any apply it in one go ++bird_update() { ++ if ! bird_generate_config; then ++ log ERROR "Could not write Bird configuration" ++ return ${EXIT_ERROR} ++ fi ++ ++ # Reload bird ++ bird_reload ++} ++ + bird_generate_config() { + log DEBUG "Write BIRD configuration file" + +diff --git a/src/functions/functions.dns b/src/functions/functions.dns +index 890f1ac..0e058be 100644 +--- a/src/functions/functions.dns ++++ b/src/functions/functions.dns +@@ -31,8 +31,8 @@ NETWORK_SETTINGS_FILE_PARAMS="${NETWORK_SETTINGS_FILE_PARAMS} DNS_RANDOMIZE" + DNS_SEARCH_DOMAINS="" + NETWORK_SETTINGS_FILE_PARAMS="${NETWORK_SETTINGS_FILE_PARAMS} DNS_SEARCH_DOMAINS" + +-# Set this option to true if the DNS servers should be advertised by +-# radvd. ++# Set this option to true if the DNS servers should be advertised in ++# IPv6 router advertisements + DNS_ADVERTISE_SERVERS="true" + + DNS_SERVER_CONFIG_FILE="${NETWORK_CONFIG_DIR}/dns-servers" +@@ -234,8 +234,8 @@ dns_server_update() { + # Regenerate /etc/resolv.conf + dns_generate_resolvconf + +- # Restart radvd which propagates IPv6 DNS servers +- radvd_update ++ # Update bird about IPv6 DNS server changes ++ bird_update + } + + dns_generate_resolvconf() { +diff --git a/src/functions/functions.radvd b/src/functions/functions.radvd +deleted file mode 100644 +index 1c8b8d0..0000000 +--- a/src/functions/functions.radvd ++++ /dev/null +@@ -1,160 +0,0 @@ +-#!/bin/bash +-############################################################################### +-# # +-# IPFire.org - A linux based firewall # +-# Copyright (C) 2010 Michael Tremer & Christian Schmidt # +-# # +-# This program is free software: you can redistribute it and/or modify # +-# it under the terms of the GNU General Public License as published by # +-# the Free Software Foundation, either version 3 of the License, or # +-# (at your option) any later version. # +-# # +-# This program 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 General Public License for more details. # +-# # +-# You should have received a copy of the GNU General Public License # +-# along with this program. If not, see . # +-# # +-############################################################################### +- +-RADVD_CONFIGFILE="/etc/radvd.conf" +- +-radvd_update() { +- # (Re-)write the configuration file +- if radvd_write_config; then +- # Reload the radvd service if it is already running +- if service_is_active radvd; then +- service_reload radvd +- return ${EXIT_OK} +- fi +- +- # Start the radvd service +- service_start radvd +- fi +-} +- +-radvd_clear_config() { +- log DEBUG "Clearing radv daemon configuration file" +- +- config_header "radv daemon configuration file" > ${RADVD_CONFIGFILE} +- +- return ${EXIT_OK} +-} +- +-radvd_write_config() { +- radvd_clear_config +- +- # Write the configuration for all zones. +- local zone +- +- # The return value determine if radvd is started or not +- local return_value=${EXIT_FALSE} +- +- for zone in $(zones_get_local); do +- if __radvd_config_interface ${zone}; then +- # We return TRUE when __radvd_config_interface returns True +- return_value=${EXIT_TRUE} +- fi +- done >> ${RADVD_CONFIGFILE} +- +- return ${return_value} +-} +- +-# This function return ${EXIT_FALSE} if no radvd config was written and ${EXIT_TRUE} in all other cases +-__radvd_config_interface() { +- local zone=${1} +- assert isset zone +- +- log DEBUG "Writing radvd configuration for ${zone}." +- +- # If the interface does not provide any routing information, +- # we can skip this whole stuff. +- if ! db_exists "${zone}/ipv6"; then +- return ${EXIT_FALSE} +- fi +- +- # Skip if zone is not active. +- local active="$(db_get "${zone}/ipv6/active")" +- [ "${active}" = "0" ] && return ${EXIT_FALSE} +- +- # Skip if there is no prefix or prefix is link-local. +- local addr="$(db_get "${zone}/ipv6/local-ip-address")" +- if [ -z "${addr}" ] || [ "${addr:0:5}" = "fe80:" ]; then +- return ${EXIT_FALSE} +- fi +- +- # Check if the subnet is configured by the DHCP server. +- local dhcpd="false" +- local prefix="$(ipv6_get_network "${addr}")" +- if isset prefix && dhcpd_subnet_match ipv6 "${prefix}"; then +- dhcpd="true" +- fi +- +- print "interface ${zone} {" +- print " AdvSendAdvert on;" +- print " MinRtrAdvInterval 3;" +- print " MaxRtrAdvInterval 10;" +- print " IgnoreIfMissing on;" +- +- if enabled dhcpd; then +- print " AdvManagedFlag on;" +- print " AdvOtherConfigFlag on;" +- fi +- +- print +- print " prefix ::/64 {" +- print " AdvOnLink on;" +- +- if enabled dhcpd; then +- print " AdvRouterAddr off;" +- print " AdvAutonomous off;" +- else +- print " AdvRouterAddr on;" +- print " AdvAutonomous on;" +- fi +- +- print " };" +- print +- +- # Add the DNS configuration. +- __radvd_config_dns ${zone} +- +- print "};" +- print +- +- return ${EXIT_TRUE} +-} +- +-__radvd_config_dns() { +- local zone=${1} +- +- # Do nothing, when this option is not enabled. +- enabled DNS_ADVERTISE_SERVERS || return ${EXIT_OK} +- +- # XXX it is kind of difficult to announce our local +- # resolver. +- +- local server servers +- for server in $(dns_server_list_sorted); do +- # Filter out non IPv6 addresses. +- ipv6_is_valid ${server} || continue +- +- servers="${servers} ${server}" +- done +- +- # Remove whitespaces. +- servers=$(echo ${servers}) +- +- # If there are no servers to announce, we stop right here. +- if ! isset servers; then +- log DEBUG "No servers to announce." +- return ${EXIT_OK} +- fi +- +- print " RDNSS ${servers} {" +- print " # Use the defaults here." +- print " };" +- print +-} +diff --git a/src/functions/functions.routing b/src/functions/functions.routing +index c7aac09..351cc53 100644 +--- a/src/functions/functions.routing ++++ b/src/functions/functions.routing +@@ -80,8 +80,8 @@ routing_default_update() { + # Remove too much spaces. + routes=$(echo ${routes}) + +- # Reload radvd configuration +- [[ "${proto}" = "ipv6" ]] && radvd_update ++ # Reload bird configuration ++ [[ "${proto}" = "ipv6" ]] && bird_update + + # Remove all default routes. + if [ -z "${routes}" ]; then +diff --git a/src/network-radvd-config b/src/network-radvd-config +deleted file mode 100644 +index e9809e1..0000000 +--- a/src/network-radvd-config ++++ /dev/null +@@ -1,35 +0,0 @@ +-#!/bin/bash +-############################################################################### +-# # +-# IPFire.org - A linux based firewall # +-# Copyright (C) 2011 Michael Tremer & Christian Schmidt # +-# # +-# This program is free software: you can redistribute it and/or modify # +-# it under the terms of the GNU General Public License as published by # +-# the Free Software Foundation, either version 3 of the License, or # +-# (at your option) any later version. # +-# # +-# This program 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 General Public License for more details. # +-# # +-# You should have received a copy of the GNU General Public License # +-# along with this program. If not, see . # +-# # +-############################################################################### +- +-. /lib/network/functions +- +-case "${1}" in +- start) +- # Write the radvd configuration file. +- radvd_write_config +- ;; +- stop) +- # Clear all contents in the configuration file. +- radvd_clear_config +- ;; +-esac +- +-exit ${EXIT_OK} +-- +2.39.2 + diff --git a/network/patches/0057-.gitignore-Ignore-vim-s-swp-files.patch b/network/patches/0057-.gitignore-Ignore-vim-s-swp-files.patch new file mode 100644 index 000000000..4b6f140c7 --- /dev/null +++ b/network/patches/0057-.gitignore-Ignore-vim-s-swp-files.patch @@ -0,0 +1,25 @@ +From f116762cf279b39749bea053eca0e873c60e23f1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 14:21:18 +0200 +Subject: [PATCH 057/304] .gitignore: Ignore vim's swp files + +Signed-off-by: Michael Tremer +--- + .gitignore | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.gitignore b/.gitignore +index a6df183..36c85a1 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -20,6 +20,7 @@ + *.lo + *.o + *.stamp ++*.swp + *.trs + *~ + .deps +-- +2.39.2 + diff --git a/network/patches/0058-bird-Make-sure-the-daemon-is-always-running.patch b/network/patches/0058-bird-Make-sure-the-daemon-is-always-running.patch new file mode 100644 index 000000000..f8c7758fc --- /dev/null +++ b/network/patches/0058-bird-Make-sure-the-daemon-is-always-running.patch @@ -0,0 +1,73 @@ +From 39beacd0549be57fde9eb350c2c9292094537629 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 14:28:44 +0200 +Subject: [PATCH 058/304] bird: Make sure the daemon is always running + +Signed-off-by: Michael Tremer +--- + src/functions/functions.bird | 14 ++++++++++++++ + src/functions/functions.route | 7 ++----- + src/network | 4 ++-- + 3 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index 55d43b5..1bbac8c 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -33,6 +33,20 @@ bird_reload() { + service_reload "bird.service" + } + ++bird_enable() { ++ # Generate configuration file ++ if ! bird_generate_config; then ++ log ERROR "Could not write Bird configuration" ++ return ${EXIT_ERROR} ++ fi ++ ++ # Enable the service to be automatically started next time ++ service_enable "bird.service" ++ ++ # Start it now ++ bird_start ++} ++ + # Update configuration any apply it in one go + bird_update() { + if ! bird_generate_config; then +diff --git a/src/functions/functions.route b/src/functions/functions.route +index e6ea244..b833822 100644 +--- a/src/functions/functions.route ++++ b/src/functions/functions.route +@@ -393,11 +393,8 @@ route_parse_line() { + } + + route_apply() { +- # Re-generate BIRD configuration +- bird_generate_config +- +- # Reload the daemon +- bird_reload ++ # Update bird ++ bird_update + } + + route_entry_add() { +diff --git a/src/network b/src/network +index 300ba94..be06d8a 100644 +--- a/src/network ++++ b/src/network +@@ -1381,8 +1381,8 @@ case "${action}" in + # Update resolv.conf(5) when initializing the network + dns_generate_resolvconf + +- # Update bird configuration +- bird_generate_config ++ # Make sure bird is running ++ bird_enable + + # Also execute all triggers + triggers_execute_all "init" +-- +2.39.2 + diff --git a/network/patches/0059-configure-Require-asciidoc.patch b/network/patches/0059-configure-Require-asciidoc.patch new file mode 100644 index 000000000..93e95bae8 --- /dev/null +++ b/network/patches/0059-configure-Require-asciidoc.patch @@ -0,0 +1,28 @@ +From 57496df2abdaa620e8ce68abfa5ad65b211a3484 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 26 Sep 2018 22:14:27 +0200 +Subject: [PATCH 059/304] configure: Require asciidoc + +Signed-off-by: Michael Tremer +--- + configure.ac | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 08e9089..117850f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -143,6 +143,10 @@ PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) + + # ------------------------------------------------------------------------------ + ++AC_CHECK_PROGS(ASCIIDOC, [asciidoc]) ++ ++# ------------------------------------------------------------------------------ ++ + AC_CONFIG_HEADERS(config.h) + AC_CONFIG_FILES([ + Makefile +-- +2.39.2 + diff --git a/network/patches/0060-man-Add-test-page-for-asciidoc.patch b/network/patches/0060-man-Add-test-page-for-asciidoc.patch new file mode 100644 index 000000000..c50e1903e --- /dev/null +++ b/network/patches/0060-man-Add-test-page-for-asciidoc.patch @@ -0,0 +1,94 @@ +From 8f591cfc10d1876523d608d9643f0a82517c2add Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 26 Sep 2018 22:42:36 +0200 +Subject: [PATCH 060/304] man: Add test page for asciidoc + +Signed-off-by: Michael Tremer +--- + Makefile.am | 14 +++++++++++--- + man/.gitignore | 1 + + man/test.txt | 11 +++++++++++ + 3 files changed, 23 insertions(+), 3 deletions(-) + create mode 100644 man/test.txt + +diff --git a/Makefile.am b/Makefile.am +index ce587b7..d01e223 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -89,6 +89,10 @@ INSTALL_EXEC_HOOKS += \ + + # ------------------------------------------------------------------------------ + ++AM_V_ASCIIDOC = $(AM_V_ASCIIDOC_$(V)) ++AM_V_ASCIIDOC_ = $(AM_V_ASCIIDOC_$(AM_DEFAULT_VERBOSITY)) ++AM_V_ASCIIDOC_0 = @echo " ASCIIDOC" $@; ++ + AM_V_DOWNLOAD = $(AM_V_DOWNLOAD_$(V)) + AM_V_DOWNLOAD_ = $(AM_V_DOWNLOAD_$(AM_DEFAULT_VERBOSITY)) + AM_V_DOWNLOAD_0 = @echo " LOAD " $@; +@@ -449,6 +453,7 @@ INSTALL_DIRS += \ + # ------------------------------------------------------------------------------ + + MANPAGES = \ ++ man/test.8 \ + man/firewall-settings.8 \ + man/network.8 \ + man/network-color.8 \ +@@ -472,8 +477,8 @@ MANPAGES = \ + man/network-zone-pppoe.8 \ + man/network-zone-wireless.8 + +-MANPAGES_XML = $(patsubst %.8,%.xml,$(MANPAGES)) +-MANPAGES_HTML = $(patsubst %.xml,%.html,$(MANPAGES_XML)) ++MANPAGES_TXT = $(patsubst %.8,%.txt,$(MANPAGES)) ++MANPAGES_HTML = $(patsubst %.txt,%.html,$(MANPAGES)) + + .PHONY: man + man: $(MANPAGES) $(MANPAGES_HTML) +@@ -489,7 +494,7 @@ CLEANFILES += \ + $(MANPAGES_HTML) + + EXTRA_DIST += \ +- $(MANPAGES_XML) \ ++ $(MANPAGES_TXT) \ + man/custom-html.xsl + + XSLTPROC_FLAGS = \ +@@ -507,6 +512,9 @@ XSLTPROC_COMMAND_MAN = \ + XSLTPROC_COMMAND_HTML = \ + $(AM_V_XSLT)$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< + ++man/%.xml: man/%.txt ++ $(AM_V_ASCIIDOC)$(ASCIIDOC) -d manpage -b docbook -o $@ $< ++ + man/%.8: man/%.xml + $(XSLTPROC_COMMAND_MAN) + +diff --git a/man/.gitignore b/man/.gitignore +index 237049a..f891826 100644 +--- a/man/.gitignore ++++ b/man/.gitignore +@@ -1,2 +1,3 @@ + /*.[13578] + /*.html ++/*.xml +diff --git a/man/test.txt b/man/test.txt +new file mode 100644 +index 0000000..4c9d35d +--- /dev/null ++++ b/man/test.txt +@@ -0,0 +1,11 @@ ++test(8) ++======= ++ ++NAME ++---- ++test - Hello World! ++ ++SYNOPSIS ++-------- ++[verse] ++'hello world' [] +-- +2.39.2 + diff --git a/network/patches/0061-man-Use-asciidoc-to-generate-HTML-pages-directly.patch b/network/patches/0061-man-Use-asciidoc-to-generate-HTML-pages-directly.patch new file mode 100644 index 000000000..fd2e569ec --- /dev/null +++ b/network/patches/0061-man-Use-asciidoc-to-generate-HTML-pages-directly.patch @@ -0,0 +1,86 @@ +From a7d2fef75b529c8cc10c4d22fca3114e30542394 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 26 Sep 2018 23:04:35 +0200 +Subject: [PATCH 061/304] man: Use asciidoc to generate HTML pages directly + +Signed-off-by: Michael Tremer +--- + Makefile.am | 10 +++------- + man/custom-html.xsl | 31 ------------------------------- + 2 files changed, 3 insertions(+), 38 deletions(-) + delete mode 100644 man/custom-html.xsl + +diff --git a/Makefile.am b/Makefile.am +index d01e223..c4f8b45 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -494,8 +494,7 @@ CLEANFILES += \ + $(MANPAGES_HTML) + + EXTRA_DIST += \ +- $(MANPAGES_TXT) \ +- man/custom-html.xsl ++ $(MANPAGES_TXT) + + XSLTPROC_FLAGS = \ + --nonet \ +@@ -509,17 +508,14 @@ XSLTPROC_COMMAND_MAN = \ + $(AM_V_XSLT)$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +-XSLTPROC_COMMAND_HTML = \ +- $(AM_V_XSLT)$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< +- + man/%.xml: man/%.txt + $(AM_V_ASCIIDOC)$(ASCIIDOC) -d manpage -b docbook -o $@ $< + + man/%.8: man/%.xml + $(XSLTPROC_COMMAND_MAN) + +-man/%.html: man/%.xml man/custom-html.xsl +- $(XSLTPROC_COMMAND_HTML) ++man/%.html: man/%.txt ++ $(AM_V_ASCIIDOC)$(ASCIIDOC) -b html5 -a icons -a theme=flask -o $@ $< + + # ------------------------------------------------------------------------------ + +diff --git a/man/custom-html.xsl b/man/custom-html.xsl +deleted file mode 100644 +index fe2b54e..0000000 +--- a/man/custom-html.xsl ++++ /dev/null +@@ -1,31 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- .html +- +- +- +- +- +- +- +- +- +- index.html +- +- Index +- +-
+-
+- +- +- +- +-
+-- +2.39.2 + diff --git a/network/patches/0062-man-Add-asciidoc-configuration-file.patch b/network/patches/0062-man-Add-asciidoc-configuration-file.patch new file mode 100644 index 000000000..3183ec913 --- /dev/null +++ b/network/patches/0062-man-Add-asciidoc-configuration-file.patch @@ -0,0 +1,62 @@ +From baf429f17d664bbc6d141c13ce6ed52091803c3b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 27 Sep 2018 00:22:59 +0200 +Subject: [PATCH 062/304] man: Add asciidoc configuration file + +This adds a short command to link to other man pages + +Signed-off-by: Michael Tremer +--- + Makefile.am | 12 ++++++++---- + man/asciidoc.conf | 12 ++++++++++++ + 2 files changed, 20 insertions(+), 4 deletions(-) + create mode 100644 man/asciidoc.conf + +diff --git a/Makefile.am b/Makefile.am +index c4f8b45..ebf3be7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -508,14 +508,18 @@ XSLTPROC_COMMAND_MAN = \ + $(AM_V_XSLT)$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +-man/%.xml: man/%.txt +- $(AM_V_ASCIIDOC)$(ASCIIDOC) -d manpage -b docbook -o $@ $< ++man/%.xml: man/%.txt man/asciidoc.conf ++ $(AM_V_ASCIIDOC)$(ASCIIDOC) \ ++ -f man/asciidoc.conf \ ++ -d manpage -b docbook -o $@ $< + + man/%.8: man/%.xml + $(XSLTPROC_COMMAND_MAN) + +-man/%.html: man/%.txt +- $(AM_V_ASCIIDOC)$(ASCIIDOC) -b html5 -a icons -a theme=flask -o $@ $< ++man/%.html: man/%.txt man/asciidoc.conf ++ $(AM_V_ASCIIDOC)$(ASCIIDOC) \ ++ -f man/asciidoc.conf \ ++ -b html5 -a icons -a theme=flask -o $@ $< + + # ------------------------------------------------------------------------------ + +diff --git a/man/asciidoc.conf b/man/asciidoc.conf +new file mode 100644 +index 0000000..243f81f +--- /dev/null ++++ b/man/asciidoc.conf +@@ -0,0 +1,12 @@ ++ifdef::backend-docbook[] ++[link-inlinemacro] ++{0%{target}} ++{0#} ++{0#{target}{0}} ++{0#} ++endif::backend-docbook[] ++ ++ifdef::backend-html5[] ++[link-inlinemacro] ++{target}{0?({0})} ++endif::backend-html5[] +-- +2.39.2 + diff --git a/network/patches/0063-man-Convert-network-8-from-docbook-to-asciidoc.patch b/network/patches/0063-man-Convert-network-8-from-docbook-to-asciidoc.patch new file mode 100644 index 000000000..e5341d529 --- /dev/null +++ b/network/patches/0063-man-Convert-network-8-from-docbook-to-asciidoc.patch @@ -0,0 +1,503 @@ +From 44d5ffe94daa496c95bf91860a5211272d8f3ff1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 27 Sep 2018 00:25:12 +0200 +Subject: [PATCH 063/304] man: Convert network(8) from docbook to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network.txt | 107 ++++++++++++++ + man/network.xml | 368 ------------------------------------------------ + 2 files changed, 107 insertions(+), 368 deletions(-) + create mode 100644 man/network.txt + delete mode 100644 man/network.xml + +diff --git a/man/network.txt b/man/network.txt +new file mode 100644 +index 0000000..569449e +--- /dev/null ++++ b/man/network.txt +@@ -0,0 +1,107 @@ ++network(8) ++========== ++ ++NAME ++---- ++network - IPFire Network Configuration Program ++ ++SYNOPSIS ++-------- ++[verse] ++'network' [] ... ++ ++DESCRIPTION ++----------- ++The 'network' command is a tool which configures the network on every IPFire ++system. It is a fast and versatile way to create, edit and remove configurations, ++review the status of the network and it is working in the background of the ++system make sure that things are running smoothly. ++ ++OPTIONS ++------- ++-d:: ++--debug:: ++ Enabled debugging mode. ++ In this mode, there wll be debug output on the console and written to ++ the log. ++ The debugging mode can be permanently enabled by setting 'DEBUG=1'. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'start' [ZONE]:: ++ Starts a zone. That means the zone is being created and brought up. ++ If one or more zones are passed to the command, only these will be ++ started. ++ ++'stop' [ZONE]:: ++ Stops a zone. This is the inverse of the 'start' command. ++ ++'restart' [ZONE]:: ++ Restarts a zone. ++ ++'status' [ZONE]:: ++ Shows an overview of the status of the zone. ++ ++'zone' ...:: ++ Commands to configure zones. See link:network-zone[8] for details. ++ ++'port' ...:: ++ Commands to configure ports. See link:network-port[8] for details. ++ ++'device' ...:: ++ See the status or execute commands to network devices. ++ See link:network-device[8] for details. ++ ++'hostname' [HOSTNAME]:: ++ Without the optional 'HOSTNAME' argument, this command will print ++ the configured hostname. ++ Passing 'HOSTNAME' will set it as the new hostname. ++ ++'settings' ...:: ++ Shows and alters global configuration parameters. ++ See link:network-settings[8] for details. ++ ++'dns-server' ...:: ++ This command allows to configure DNS servers. ++ See link::network-dns-server[8] for details. ++ ++'route' ...:: ++ This command allows managing static routes. ++ See link:network-route[8] for details. ++ ++'vpn' ...:: ++ The command allows managing VPN connections. ++ See link:network-vpn[8] for details. ++ ++'reset':: ++ This command will reset all network configuration. ++ All zones, ports and other settings will be removed. ++ ++'help' ...:: ++ Shows this man page. ++ ++EXIT CODES ++---------- ++The 'network' command will normally exit with code zero. ++If there has been aproblem and the requested action could not be performed, ++the exit code is unequal to zero. ++ ++BUGS ++---- ++Please report all bugs to the bugtracker at https://bugzilla.ipfire.org/. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network-settings[8] ++link:network-device[8] ++link:network-dns-server[8] ++link:network-performance-tuning[8] ++link:network-port[8] ++link:network-quick-start[8] ++link:network-zone[8] +diff --git a/man/network.xml b/man/network.xml +deleted file mode 100644 +index 0a97453..0000000 +--- a/man/network.xml ++++ /dev/null +@@ -1,368 +0,0 @@ +- +- +- +- +- +- network +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network +- 8 +- +- +- +- network +- Network Configuration Control Program +- +- +- +- +- network +- OPTIONS +- COMMAND +- +- +- +- +- Description +- +- +- The network command is a tool which configures +- the network on every IPFire system. It is a fast and versatile +- way to create, edit and remove configurations, review the status +- of the network and it is working in the background of the system +- making sure that things are running smoothly. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- +- +- +- Enables the debugging mode. +- In this mode, there will be debug output on +- the console and written to the log. +- +- +- The debugging mode can be permanently enabled by setting +- DEBUG=1 +- +- +- +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- start ZONE-NAME... +- +- +- +- +- Starts a zone. That means the network zone will be created +- and brought up. +- If one or more zone names are passed to the command, only +- these will be started. +- +- +- +- +- +- +- stop ZONE-NAME... +- +- +- +- +- Stops a zone. This is the inverse of the start +- command. +- +- +- +- +- +- +- restart ZONE-NAME... +- +- +- +- +- Restarts a zone. +- +- +- +- +- +- +- status ZONE-NAME... +- +- +- +- +- Shows a human-readable overview of the status +- of the network zone. +- +- +- +- +- +- +- zone ... +- +- +- +- +- Configure a zone or show status information. +- See +- network-zone +- 8 +- for details. +- +- +- +- +- +- +- port ... +- +- +- +- +- Configure a port or show status information. +- See +- network-port +- 8 +- for details. +- +- +- +- +- +- +- device ... +- +- +- +- +- Show status information about network devices. +- See +- network-device +- 8 +- for details. +- +- +- +- +- +- +- config KEY=VALUE +- +- +- +- +- Shows and alters global configuration parameters. +- See +- network-settings +- 8 +- for details. +- +- +- +- +- +- +- help [TYPE +- HOOK|TYPE list-hooks] +- +- +- +- +- Calling network help without any +- arguments will show you this man page. +- +- +- network help TYPE list-hooks +- will print a list of all hooks of TYPE. +- +- +- You may optionally pass two arguments, to view the help +- of a certain hook. +- The type of the hook TYPE +- needs to be passed as well as the name of the hook +- HOOK. +- +- +- +- +- +- +- hostname HOSTNAME +- +- +- +- +- The hostname command will return the +- currently configured hostname of the system. +- +- +- If a new hostname is added to the command line, +- it will be configured, but will be set after the next +- reboot. +- +- +- +- +- +- +- dns-server ... +- +- +- +- +- The dns-server command will help you +- configuring the local DNS servers. +- See +- network-dns-server +- 8 +- for details. +- +- +- +- +- +- +- route ... +- +- +- +- +- The route command allows managing static routes. +- See +- network-route +- 8 +- for details. +- +- +- +- +- +- +- vpn ... +- +- +- +- +- The vpn allows managing VPN connections. +- See +- network-vpn +- 8 +- for details. +- +- +- +- +- +- +- reset +- +- +- +- +- The reset command will reset all +- network configuration. That means all zone configurations +- will be removed and there will be no networking after the +- next reboot. +- +- +- +- +- +- +- +- Exit Codes +- +- +- The network command will normally exit with code 0. +- If there has been a problem and the requested action could not be done, +- the exit code is unequal to zero. +- +- +- +- +- Bugs +- +- +- Please report all bugs to the official bugtracker at +- http://bugs.ipfire.org/. +- +- +- +- +- See Also +- +- +- +- network-settings +- 8 +- , +- +- network-device +- 8 +- , +- +- network-dns-server +- 8 +- , +- +- network-performance-tuning +- 8 +- , +- +- network-port +- 8 +- , +- +- network-quick-start +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0064-man-Convert-network-color-8-to-asciidoc.patch b/network/patches/0064-man-Convert-network-color-8-to-asciidoc.patch new file mode 100644 index 000000000..ff765aa14 --- /dev/null +++ b/network/patches/0064-man-Convert-network-color-8-to-asciidoc.patch @@ -0,0 +1,152 @@ +From b2f5dc13f74d0b740885f99a7d1408480da582cf Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 27 Sep 2018 00:34:35 +0200 +Subject: [PATCH 064/304] man: Convert network-color(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-color.txt | 33 ++++++++++++++++ + man/network-color.xml | 91 ------------------------------------------- + 2 files changed, 33 insertions(+), 91 deletions(-) + create mode 100644 man/network-color.txt + delete mode 100644 man/network-color.xml + +diff --git a/man/network-color.txt b/man/network-color.txt +new file mode 100644 +index 0000000..7c95e18 +--- /dev/null ++++ b/man/network-color.txt +@@ -0,0 +1,33 @@ ++network-color(8) ++================ ++ ++NAME ++---- ++network-color - IPFire Network Configuration Control Program ++ ++DESCRIPTION ++----------- ++The 'color' command helps to manage colors for zones and ports. ++The color is being used to make identification of a zone or port easier on the ++command line and web user interface. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'set' [AABBCC]:: ++ The color of a zone or port is set with the 'set' command. ++ It is required to pass a color in hex formatting. ++ ++'reset':: ++ Resets the color of a zone or port to blank. ++ ++AUTHOR ++------ ++Jonatan Schlag ++ ++SEE ALSO ++-------- ++link:network[8] ++link:network-zone[8] ++link:network-port[8] +diff --git a/man/network-color.xml b/man/network-color.xml +deleted file mode 100644 +index caf2349..0000000 +--- a/man/network-color.xml ++++ /dev/null +@@ -1,91 +0,0 @@ +- +- +- +- +- +- networ-color +- network +- +- +- +- Developer +- Jonatan +- Schlag +- jonatan.schlag@ipfire.org +- +- +- +- +- +- network-color +- 8 +- +- +- +- network-color +- Network Configuration Control Program +- +- +- +- Description +- +- +- The color helps to manage colors for zone and ports. +- The color is used to make identification of a zone or port easier on the +- command line or web user interface. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- set 00AABB +- +- +- +- +- The color of a zone or port is set with the set command. +- It is always required to pass a valid color hex value (e.g. 880400). +- +- +- +- +- +- reset +- +- +- +- +- This command resets the color of a zone or port to blank. +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- , +- +- network-port +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0065-man-Drop-test-page.patch b/network/patches/0065-man-Drop-test-page.patch new file mode 100644 index 000000000..5dd0ddc36 --- /dev/null +++ b/network/patches/0065-man-Drop-test-page.patch @@ -0,0 +1,44 @@ +From 91305dee4f83ca35758e756903e3324117a26a7d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 27 Sep 2018 00:36:02 +0200 +Subject: [PATCH 065/304] man: Drop test page + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 - + man/test.txt | 11 ----------- + 2 files changed, 12 deletions(-) + delete mode 100644 man/test.txt + +diff --git a/Makefile.am b/Makefile.am +index ebf3be7..55d5d18 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -453,7 +453,6 @@ INSTALL_DIRS += \ + # ------------------------------------------------------------------------------ + + MANPAGES = \ +- man/test.8 \ + man/firewall-settings.8 \ + man/network.8 \ + man/network-color.8 \ +diff --git a/man/test.txt b/man/test.txt +deleted file mode 100644 +index 4c9d35d..0000000 +--- a/man/test.txt ++++ /dev/null +@@ -1,11 +0,0 @@ +-test(8) +-======= +- +-NAME +----- +-test - Hello World! +- +-SYNOPSIS +--------- +-[verse] +-'hello world' [] +-- +2.39.2 + diff --git a/network/patches/0066-man-network-color-Add-synopsis.patch b/network/patches/0066-man-network-color-Add-synopsis.patch new file mode 100644 index 000000000..6097f2a90 --- /dev/null +++ b/network/patches/0066-man-network-color-Add-synopsis.patch @@ -0,0 +1,32 @@ +From 62191ec375cf7fc957690d88c663ae7ad479a1a4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 27 Sep 2018 00:47:19 +0200 +Subject: [PATCH 066/304] man: network-color: Add synopsis + +Signed-off-by: Michael Tremer +--- + man/network-color.txt | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/man/network-color.txt b/man/network-color.txt +index 7c95e18..f3be474 100644 +--- a/man/network-color.txt ++++ b/man/network-color.txt +@@ -3,7 +3,13 @@ network-color(8) + + NAME + ---- +-network-color - IPFire Network Configuration Control Program ++network-color - Allows assigning a color to a zone or port ++ ++SYNOPSIS ++-------- ++[verse] ++'network' [zone ZONE|port PORT] color set AABBCC ++'network' [zone ZONE|port PORT] reset + + DESCRIPTION + ----------- +-- +2.39.2 + diff --git a/network/patches/0067-man-Convert-firewall-settings-to-asciidoc.patch b/network/patches/0067-man-Convert-firewall-settings-to-asciidoc.patch new file mode 100644 index 000000000..8751171af --- /dev/null +++ b/network/patches/0067-man-Convert-firewall-settings-to-asciidoc.patch @@ -0,0 +1,409 @@ +From 66fe74f95f4da254fc1162c591a40012c17aab07 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 21:16:10 +0200 +Subject: [PATCH 067/304] man: Convert firewall-settings to asciidoc + +Signed-off-by: Michael Tremer +--- + man/firewall-settings.txt | 97 +++++++++++++ + man/firewall-settings.xml | 284 -------------------------------------- + 2 files changed, 97 insertions(+), 284 deletions(-) + create mode 100644 man/firewall-settings.txt + delete mode 100644 man/firewall-settings.xml + +diff --git a/man/firewall-settings.txt b/man/firewall-settings.txt +new file mode 100644 +index 0000000..20038e3 +--- /dev/null ++++ b/man/firewall-settings.txt +@@ -0,0 +1,97 @@ ++firewall-settings(8) ++==================== ++ ++NAME ++---- ++firewall-settings - Global firewall settings ++ ++SYNOPSIS ++-------- ++[verse] ++'firewall settings' ++'firewall settings' KEY=VALUE ... ++ ++DESCRIPTION ++----------- ++This command is used to set global firewall settings. ++Please have a look at the individual man pages for more options. ++ ++COMMANDS ++-------- ++If no argument is given, the configuration will be dumped to the console. ++ ++You may set a new value by adding the variable name and the new value to ++the command line. ++ ++SETTINGS ++-------- ++=== CONNTRACK_MAX_CONNECTIONS = 16384 ++Limits the max. number of simultaneous connections. ++ ++Modify this if you want to handle a larger number of concurrent ++connections. Every connection will use approx. 16 kBytes of memory. ++ ++=== CONNTRACK_UDP_TIMEOUT = 60 ++Defines the timeout (in seconds) the kernel will wait until ++a half-assured UDP connection is fully established. ++ ++=== FIREWALL_ACCEPT_ICMP_REDIRECTS = [true|false] ++Enable if you want to accept ICMP redirect messages. ++ ++=== FIREWALL_CLAMP_PATH_MTU = [true|false] ++If Path MTU Discovery does not work well, enable this option. ++ ++It sets the MSS value of a packet so that the remote site would ++never send a packet bigger than the MSS value. ++ ++No ICMP packets are needed to make this work, so use this on ++networks with broken ICMP filtering. ++ ++=== FIREWALL_DEFAULT_TTL = 64 ++Here you can change the default TTL used for sending packets. ++ ++The given value must be between 10 and 255. ++Don't mess with this unless you know what you are doing. ++ ++=== FIREWALL_LOG_BAD_TCP_FLAGS = [true|false] ++Enable this to log TCP packets with bad flags or options. ++ ++=== FIREWALL_LOG_INVALID_ICMP = [true|false] ++Enable this to log INVALID ICMP packets. ++ ++=== FIREWALL_LOG_INVALID_TCP = [true|false] ++Enable this to log INVALID TCP packets. ++ ++=== FIREWALL_LOG_INVALID_UDP = [true|false] ++Enable this to log INVALID UDP packets. ++ ++=== FIREWALL_LOG_MARTIANS = [true|false] ++Enable this to log packets with impossible addresses. ++ ++=== FIREWALL_LOG_STEALTH_SCANS = [true|false] ++Enable this to log all stealth scans. ++ ++=== FIREWALL_PMTU_DISCOVERY = [true|false] ++Enables Path MTU Discovery. ++ ++=== FIREWALL_RP_FILTER = [true|false] ++Enable to drop connection from non-routable IPs, ++e.g. prevent source routing. ++ ++=== FIREWALL_SYN_COOKIES = [true|false] ++Enable for SYN-flood protection. ++ ++=== FIREWALL_USE_ECN = [true|false] ++Enables the ECN (Explicit Congestion Notification) TCP flag. ++ ++Some routers on the Internet still do not support ECN properly. ++When this setting is disabled, ECN is only advertised ++when asked for. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:firewall[8] +diff --git a/man/firewall-settings.xml b/man/firewall-settings.xml +deleted file mode 100644 +index 7357f4c..0000000 +--- a/man/firewall-settings.xml ++++ /dev/null +@@ -1,284 +0,0 @@ +- +- +- +- +- +- firewall-settings +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- firewall-settings +- 8 +- +- +- +- firewall-settings +- Firewall Configuration Control Program +- +- +- +- +- firewall-settings +- +- +- +- firewall-settings KEY=VALUE +- +- +- +- +- Description +- +- +- The firewall-settings command may be used to set +- global firewall settingsuration options. +- +- +- Please have a look at the individual man pages for more options. +- +- +- +- +- Commands +- +- +- If no additional argument is given, running the command will +- dump a list of all settingsuration variables and their current values. +- +- +- +- You may set a new value by adding the variable name and the new +- value to the command line. +- +- +- +- +- Variables +- +- +- +- +- CONNTRACK_MAX_CONNECTIONS = 16384 +- +- +- +- +- Limits the max. number of simultaneous connections. +- +- +- Modify this if you want to handle a larger number of concurrent +- connections. Every connection will use approx. 16 kBytes of memory. +- +- +- +- +- +- +- CONNTRACK_UDP_TIMEOUT = 60 +- +- +- +- +- Defines the timeout (in seconds) the kernel will wait until +- a half-assured UDP connection is fully established. +- +- +- +- +- +- +- FIREWALL_ACCEPT_ICMP_REDIRECTS = [true|false] +- +- +- +- +- Enable if you want to accept ICMP redirect messages. +- +- +- +- +- +- +- FIREWALL_CLAMP_PATH_MTU = [true|false] +- +- +- +- +- If Path MTU Discovery does not work well, enable this option. +- It sets the MSS value of a packet so that the remote site would +- never send a packet bigger than the MSS value. +- +- +- No ICMP packets are needed to make this work, so use this on +- networks with broken ICMP filtering. +- +- +- +- +- +- +- FIREWALL_DEFAULT_TTL = 64 +- +- +- +- +- Here you can change the default TTL used for sending packets. +- +- +- The given value must be between 10 and 255. +- Don't mess with this unless you know what you are doing. +- +- +- +- +- +- +- FIREWALL_LOG_BAD_TCP_FLAGS = [true|false] +- +- +- +- +- Enable this to log TCP packets with bad flags or options. +- +- +- +- +- +- +- FIREWALL_LOG_INVALID_ICMP = [true|false] +- +- +- +- +- Enable this to log INVALID ICMP packets. +- +- +- +- +- +- +- FIREWALL_LOG_INVALID_TCP = [true|false] +- +- +- +- +- Enable this to log INVALID TCP packets. +- +- +- +- +- +- +- FIREWALL_LOG_INVALID_UDP = [true|false] +- +- +- +- +- Enable this to log INVALID UDP packets. +- +- +- +- +- +- +- FIREWALL_LOG_MARTIANS = [true|false] +- +- +- +- +- Enable this to log packets with impossible addresses. +- +- +- +- +- +- +- FIREWALL_LOG_STEALTH_SCANS = [true|false] +- +- +- +- +- Enable this to log all stealth scans. +- +- +- +- +- +- +- FIREWALL_PMTU_DISCOVERY = [true|false] +- +- +- +- +- Enables Path MTU Discovery. +- +- +- +- +- +- +- FIREWALL_RP_FILTER = [true|false] +- +- +- +- +- Enable to drop connection from non-routable IPs, +- e.g. prevent source routing. +- +- +- +- +- +- +- FIREWALL_SYN_COOKIES = [true|false] +- +- +- +- +- Enable for SYN-flood protection. +- +- +- +- +- +- +- FIREWALL_USE_ECN = [true|false] +- +- +- +- +- Enables the ECN (Explicit Congestion Notification) TCP flag. +- +- +- Some routers on the Internet still do not support ECN properly, +- so this is not enabled by default. +- When this setting is disabled, ECN is only advertised +- when asked for. +- +- +- +- +- +- +- +- See Also +- +- +- +- firewall +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0068-man-Convert-network-description-8-to-asciidoc.patch b/network/patches/0068-man-Convert-network-description-8-to-asciidoc.patch new file mode 100644 index 000000000..4c993a4b7 --- /dev/null +++ b/network/patches/0068-man-Convert-network-description-8-to-asciidoc.patch @@ -0,0 +1,144 @@ +From c601b69e5d8db595fee00241702ee8bd2689c49e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 21:24:48 +0200 +Subject: [PATCH 068/304] man: Convert network-description(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 - + man/include-description.txt | 11 +++++ + man/network-description.xml | 92 ------------------------------------- + 3 files changed, 11 insertions(+), 93 deletions(-) + create mode 100644 man/include-description.txt + delete mode 100644 man/network-description.xml + +diff --git a/Makefile.am b/Makefile.am +index 55d5d18..287a111 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -456,7 +456,6 @@ MANPAGES = \ + man/firewall-settings.8 \ + man/network.8 \ + man/network-color.8 \ +- man/network-description.8 \ + man/network-device.8 \ + man/network-dhcp.8 \ + man/network-dns-server.8 \ +diff --git a/man/include-description.txt b/man/include-description.txt +new file mode 100644 +index 0000000..a39ba55 +--- /dev/null ++++ b/man/include-description.txt +@@ -0,0 +1,11 @@ ++'description edit':: ++ This command opens an editor and allows you to edit title and description. ++ ++ NOTE: The formation of the description is similar to a git commit. ++ Every description has a title, the first line of the description. ++ The title is shown on the status page and in the web user interface. ++ It should be something short like "Office Lan" or "DMZ". ++ After the title can follow a longer description. ++ ++'description show':: ++ Prints the description. +diff --git a/man/network-description.xml b/man/network-description.xml +deleted file mode 100644 +index f1722b4..0000000 +--- a/man/network-description.xml ++++ /dev/null +@@ -1,92 +0,0 @@ +- +- +- +- +- +- networ-color +- network +- +- +- +- Developer +- Jonatan +- Schlag +- jonatan.schlag@ipfire.org +- +- +- +- +- +- network-description +- 8 +- +- +- +- network-description +- Network Configuration Control Program +- +- +- +- Description +- +- +- The description command make it possible to add descriptions to zone and ports. +- A description is similar to a git commit. Every description has a title, the first line of the describtion file. +- The title is shown on the status page and in the webinterface. It should be something short like Office Lan or DMZ. +- After the title can follow a longer description. You can write whatever you want. +- This longer description is shown via the show command +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- edit +- +- +- +- +- This command opens an editor and allows you to edit title and description. +- +- +- +- +- +- show +- +- +- +- +- This command prints title and the longer description in a nice way. +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- , +- +- network-port +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0069-man-Convert-network-device-8-to-asciidoc.patch b/network/patches/0069-man-Convert-network-device-8-to-asciidoc.patch new file mode 100644 index 000000000..1cdc8b87d --- /dev/null +++ b/network/patches/0069-man-Convert-network-device-8-to-asciidoc.patch @@ -0,0 +1,254 @@ +From 9d2265232d8a1c399617e347bda66a8019d8b36d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 21:40:53 +0200 +Subject: [PATCH 069/304] man: Convert network-device(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-device.txt | 61 +++++++++++++++ + man/network-device.xml | 165 ----------------------------------------- + 2 files changed, 61 insertions(+), 165 deletions(-) + create mode 100644 man/network-device.txt + delete mode 100644 man/network-device.xml + +diff --git a/man/network-device.txt b/man/network-device.txt +new file mode 100644 +index 0000000..33fcefa +--- /dev/null ++++ b/man/network-device.txt +@@ -0,0 +1,61 @@ ++network(8) ++========== ++ ++NAME ++---- ++network-device - Controls network devices ++ ++SYNOPSIS ++-------- ++[verse] ++'network device' [] ... ++ ++DESCRIPTION ++----------- ++The 'network device' command shows low-level status information ++of network devices and other things. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'list':: ++ This command shows a list of all device that are currently present ++ on this system. This includes PHYs and serial devices as well. ++ ++'DEVICE discover':: ++ Runs a discovery for many hooks on the given device. ++ ++ This will check if the hook can find for example a DHCP server or ++ DSLAM and thus predict for what the device should be used. ++ ++'DEVICE identify':: ++ This command only works for Ethernet adapters and will make those ++ that support this feature flash for a few seconds. ++ ++ It is handy to find the right device to put the cable in. ++ ++'DEVICE monitor':: ++ This command creates a monitor interface for wireless modules. ++ ++ An instance of link:tcpdump[8] will be started and show all ++ frames that are sent or received on the 802.11 layer (layer 2). ++ ++'DEVICE status':: ++ This will show you very detailed information about the given device. ++ ++'DEVICE unlock':: ++ This command will unlock the SIM card in a modem. ++ Only serial devices are supported which are the most 4G or 3G modems. ++ ++ For the PIN or PUK code, the user will be prompted. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8] ++link:network-port[8] ++link:network-zone[8] +diff --git a/man/network-device.xml b/man/network-device.xml +deleted file mode 100644 +index 11dc04e..0000000 +--- a/man/network-device.xml ++++ /dev/null +@@ -1,165 +0,0 @@ +- +- +- +- +- +- network-device +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-device +- 8 +- +- +- +- network-device +- Network Configuration Control Program +- +- +- +- +- network device COMMAND +- +- +- +- +- Description +- +- +- With help of the device subcommands, it is very easy +- to get status information about network devices and to do some more +- things. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- list +- +- +- +- +- The list command will show a list +- of all devices that are currently plugged in or active +- on the system. +- This includes PHYs and serial devices as well. +- +- +- +- +- +- +- DEVICE status +- +- +- +- +- This will show you very detailed information about the given +- device. +- +- +- This is all about the ethernet parts of the device and +- does not contain any IP information as this is defined +- as a zone ( +- network-zone +- 8 +- ). +- +- +- +- +- +- +- DEVICE identify +- +- +- +- +- This command only works for Ethernet adapters and will +- make those that support this feature flash for a few +- seconds. +- It is handy to find the right device to put the cable in. +- +- +- +- +- +- +- DEVICE discover +- +- +- +- +- Runs a discovery for many hooks on the given device. +- This will check if the hook can find for example a DHCP +- server or DSLAM and thus predict for what the device +- should be used. +- +- +- +- +- +- +- DEVICE unlock +- +- +- +- +- This command will unlock the SIM card in a modem. +- Only serial devices are supported which are the most +- UMTS or 3G modems. +- +- +- For the PIN or PUK code, the user will be prompted. +- +- +- +- +- +- +- DEVICE monitor +- +- +- +- +- The monitor command is used to +- create a monitor interface for wireless modules. +- An instance of tcpdump will be started and show +- all frames that are sent or received on the 802.11 +- layer (layer 2) of the wireless network. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0070-man-Convert-network-dhcp-8-to-asciidoc.patch b/network/patches/0070-man-Convert-network-dhcp-8-to-asciidoc.patch new file mode 100644 index 000000000..95cd6ce5e --- /dev/null +++ b/network/patches/0070-man-Convert-network-dhcp-8-to-asciidoc.patch @@ -0,0 +1,217 @@ +From c6e12dc53a1e65a0089ee0ddb0573a29bc2acd8a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 21:46:49 +0200 +Subject: [PATCH 070/304] man: Convert network-dhcp(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-dhcp.txt | 44 +++++++++++++ + man/network-dhcp.xml | 145 ------------------------------------------- + 2 files changed, 44 insertions(+), 145 deletions(-) + create mode 100644 man/network-dhcp.txt + delete mode 100644 man/network-dhcp.xml + +diff --git a/man/network-dhcp.txt b/man/network-dhcp.txt +new file mode 100644 +index 0000000..a448619 +--- /dev/null ++++ b/man/network-dhcp.txt +@@ -0,0 +1,44 @@ ++network(8) ++========== ++ ++NAME ++---- ++network-dhcp - Controls the DHCP Server ++ ++SYNOPSIS ++-------- ++[verse] ++'network dhcpv6' ... ++'network dhcpv4' ... ++ ++DESCRIPTION ++----------- ++With help of the DHCP commands it is possible to configure DHCP ++servers for IPv6 and IPv4. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'start':: ++ Starts the DHCP server. ++ ++'stop':: ++ Stops the DHCP server. ++ ++'restart':: ++ Restarts the DHCP server. ++ ++'reload':: ++ Reload the DHCP server configuration. ++ ++'subnet ...':: ++ TODO ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8] +diff --git a/man/network-dhcp.xml b/man/network-dhcp.xml +deleted file mode 100644 +index cc081bb..0000000 +--- a/man/network-dhcp.xml ++++ /dev/null +@@ -1,145 +0,0 @@ +- +- +- +- +- +- network-dhcp +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-dhcp +- 8 +- +- +- +- network-dhcp +- Network Configuration Control Program +- +- +- +- +- network [dhcpv6|dhcpv4] command ... +- +- +- +- +- Description +- +- +- With help of the dhcp commands it is possible to +- configure DHCP servers for IPv6 and IPv4. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- start +- +- +- +- +- Starts the DHCP service. +- +- +- +- +- +- +- stop +- +- +- +- +- Stops the DHCP service. +- +- +- +- +- +- +- restart +- +- +- +- +- Restarts the DHCP service immediately. +- +- +- +- +- +- +- reload +- +- +- +- +- Reload the DHCP service configuration. +- +- +- +- +- +- +- show +- +- +- +- +- Shows the DHCP configuration. +- +- +- +- +- +- +- subnet ... +- +- +- +- +- Use this command to manage subnets. +- See +- network-dhcp-subnet +- 8 +- for details. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-dhcp-subnet +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0071-man-Convert-network-dns-server-8-to-asciidoc.patch b/network/patches/0071-man-Convert-network-dns-server-8-to-asciidoc.patch new file mode 100644 index 000000000..a8f55a10b --- /dev/null +++ b/network/patches/0071-man-Convert-network-dns-server-8-to-asciidoc.patch @@ -0,0 +1,306 @@ +From 063089cbdb2745248bd8556e87de4a0d2bc8091d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 21:59:01 +0200 +Subject: [PATCH 071/304] man: Convert network-dns-server(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-dns-server.txt | 75 ++++++++++++++ + man/network-dns-server.xml | 203 ------------------------------------- + 2 files changed, 75 insertions(+), 203 deletions(-) + create mode 100644 man/network-dns-server.txt + delete mode 100644 man/network-dns-server.xml + +diff --git a/man/network-dns-server.txt b/man/network-dns-server.txt +new file mode 100644 +index 0000000..bd01ca7 +--- /dev/null ++++ b/man/network-dns-server.txt +@@ -0,0 +1,75 @@ ++network-dns-server(8) ++===================== ++ ++NAME ++---- ++network-dns-server - Controls the DNS settings ++ ++SYNOPSIS ++-------- ++[verse] ++'network dns-server' add SERVER [PRIORITY] ++'network dns-server' remove SERVER ++'network dns-server' list ++'network dns-server' update ++ ++DESCRIPTION ++----------- ++With this command, you will be able to configure the local DNS ++configuration. ++ ++You may add and remove DNS servers as well as view the settings. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'add' SERVER [PRIORITY]:: ++ A new DNS server may be added to the list by the ++ 'add' command. ++ A priority that will rank the server my optionally be given. ++ ++ NOTE: SERVER must be a valid IP address and PRIORITY ++ must be a positive number. ++ The smaller this number, the higher is is the rank of ++ the server. ++ ++'remove' SERVER:: ++ The given server will be removed from the list of DNS servers. ++ ++'list':: ++ Shows a list of all servers that are currently in use. ++ ++'update':: ++ This command will re-create the system's configuration ++ files. It should not be required to use this command ++ very often. ++ ++SETTINGS ++-------- ++The following settings may be set using link:network-settings[8]: ++ ++'DNS_USE_LOCAL_RESOLVER = [true|false]':: ++ This option defines whether the local DNS resolver should ++ be used or not. ++ ++ Basically, the option adds localhost to the list of nameservers ++ in link:resolv.conf[5]. ++ ++'DNS_SEARCH_DOMAINS =':: ++ This setting configures the search domains for DNS queries ++ made by the local system. ++ ++'DNS_RANDOMIZE = [true|false]':: ++ This option will break the DNS server ranks and will query ++ them in a random order which is useful to load-balance ++ multiple DNS servers. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8], ++link:network-settings[8] +diff --git a/man/network-dns-server.xml b/man/network-dns-server.xml +deleted file mode 100644 +index aec52d4..0000000 +--- a/man/network-dns-server.xml ++++ /dev/null +@@ -1,203 +0,0 @@ +- +- +- +- +- +- network-dns-server +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-dns-server +- 8 +- +- +- +- network-dns-server +- Network Configuration Control Program +- +- +- +- +- network dns-server [add|remove] SERVER [PRIORITY] +- +- +- +- network dns-server [list|update] +- +- +- +- +- Description +- +- +- With help of the dns-server subcommand, you will +- be able to configure the local DNS configuration. +- DNS is short for Domain Name System. +- +- +- You may add and remove DNS servers as well as view the settings. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- +- add +- SERVER +- [PRIORITY] +- +- +- +- +- +- A new DNS server may be added to the list by the +- add command. A priority that will +- rank the server my optionally be given. +- +- +- SERVER must be a valid IP address +- and PRIORITY must be a positive +- integer number. The smaller this number, the higher is +- is the rank of the server. +- +- +- +- +- +- +- +- remove +- SERVER +- +- +- +- +- +- The given server will be removed from the list of +- DNS servers. +- +- +- +- +- +- +- list +- +- +- +- +- Shows a list of all servers that are currently in use. +- +- +- +- +- +- +- update +- +- +- +- +- This command will re-create the system's configuration +- files. It should not be required to use this command +- very often. +- +- +- +- +- +- +- +- Variables +- +- +- These variables may be set by using the +- network-settings +- 8 +- command. +- +- +- +- +- +- DNS_USE_LOCAL_RESOLVER=[true|false] +- +- +- +- +- This option defines whether the local DNS resolver should +- be used or not. +- +- +- Basically, the option adds localhost to the list of +- nameservers in +- resolv.conf +- 5 +- . +- +- +- +- +- +- +- DNS_SEARCH_DOMAINS= +- +- +- +- +- This setting configures the search domains for DNS queries +- made by the local system. +- +- +- +- +- +- +- DNS_RANDOMIZE=[true|false] +- +- +- +- +- This option will break the DNS server ranks and will query +- them in a random order which is useful to load-balance +- multiple DNS servers. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-settings +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0072-man-Convert-network-performance-tuning-8-to-asciidoc.patch b/network/patches/0072-man-Convert-network-performance-tuning-8-to-asciidoc.patch new file mode 100644 index 000000000..dd508342b --- /dev/null +++ b/network/patches/0072-man-Convert-network-performance-tuning-8-to-asciidoc.patch @@ -0,0 +1,135 @@ +From c20f292770a6423c112b7f96d724bb13c4019d2a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:04:08 +0200 +Subject: [PATCH 072/304] man: Convert network-performance-tuning(8) to + asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-performance-tuning.txt | 33 ++++++++++++++ + man/network-performance-tuning.xml | 73 ------------------------------ + 2 files changed, 33 insertions(+), 73 deletions(-) + create mode 100644 man/network-performance-tuning.txt + delete mode 100644 man/network-performance-tuning.xml + +diff --git a/man/network-performance-tuning.txt b/man/network-performance-tuning.txt +new file mode 100644 +index 0000000..763ee21 +--- /dev/null ++++ b/man/network-performance-tuning.txt +@@ -0,0 +1,33 @@ ++network-performance-tuning(8) ++============================= ++ ++NAME ++---- ++network-performance-tuning - Performance Tuning for Networking ++ ++DESCRIPTION ++----------- ++This page contains a summary of some performance tuning techniques ++that this system is using. ++ ++=== SMP Affinity ++ ++This system is automatically using SMP affinity for every physical ++network controller, if supported. ++ ++A processor core is assigned to handle all interrupts of a certain ++network controller which will result in minimising cache misses, ++reducing network latency and quite possibly increasing throughput. ++ ++The algorithm is trying to balance all network controllers across ++all processors. ++ ++See /proc/interrups for the distribution of interrupts. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8] +diff --git a/man/network-performance-tuning.xml b/man/network-performance-tuning.xml +deleted file mode 100644 +index 898f142..0000000 +--- a/man/network-performance-tuning.xml ++++ /dev/null +@@ -1,73 +0,0 @@ +- +- +- +- +- +- network-performance-tuning +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-performance-tuning +- 8 +- +- +- +- network-performance-tuning +- Network Configuration Control Program +- +- +- +- Description +- +- +- This page contains a summary of some performance tuning techniques +- that this system is using. +- +- +- +- +- SMP Affinity +- +- +- This system is automatically using SMP affinity for every physical +- network controller, if supported. +- +- +- +- A processor core is assigned to handle all interrupts of a certain +- network controller which will result in minimising cache misses, +- reducing network latency and quite possibly increasing throughput. +- +- +- +- The algorithm is trying to balance all network controllers across +- all processors. +- +- +- +- See /proc/interrups for the distribution of interrupts. +- +- +- +- +- See Also +- +- +- +- network +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0073-man-Convert-network-port-8-to-asciidoc.patch b/network/patches/0073-man-Convert-network-port-8-to-asciidoc.patch new file mode 100644 index 000000000..d892b4ff7 --- /dev/null +++ b/network/patches/0073-man-Convert-network-port-8-to-asciidoc.patch @@ -0,0 +1,370 @@ +From 065346332054e3b2be85bee3f6d71a3dc34d6275 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:27:40 +0200 +Subject: [PATCH 073/304] man: Convert network-port(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-port.txt | 97 +++++++++++++++++ + man/network-port.xml | 245 ------------------------------------------- + 2 files changed, 97 insertions(+), 245 deletions(-) + create mode 100644 man/network-port.txt + delete mode 100644 man/network-port.xml + +diff --git a/man/network-port.txt b/man/network-port.txt +new file mode 100644 +index 0000000..08b9e90 +--- /dev/null ++++ b/man/network-port.txt +@@ -0,0 +1,97 @@ ++network-port(8) ++=============== ++ ++NAME ++---- ++network-port - Controls Network Ports ++ ++SYNOPSIS ++-------- ++[verse] ++'network port' new HOOK ... ++'network port' destroy PORT ++'network port' PORT color ++'network port' PORT create ++'network port' PORT description edit ++'network port' PORT description show ++'network port' PORT down ++'network port' PORT edit ... ++'network port' PORT identify ++'network port' PORT remove ++'network port' PORT status ++'network port' PORT up ++ ++DESCRIPTION ++----------- ++This command creates, deletes, changes and views the configuration ++and status of ports. ++ ++NOTE: A port is a physical or virtual device that is directly connected ++to an other network. It connects those and zones together. ++The 'network device' command shows status information of network devices ++and other things. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'new' HOOK ...:: ++ A new port may be created with this command. ++ HOOK must be a valid hook which may require more options. ++ ++'destroy' PORT:: ++ Destroys the port PORT. ++ The port is removed from any zones it is attached to and shut down. ++ ++For all other commands, the name of the port needs to be passed first: ++ ++'color':: ++ This command allows settings a color for a port. ++ See link:network-color[8] for more information. ++ ++'create':: ++ This will create devices for the existing port PORT. ++ ++ This does not create a new port. It will just create the (possibly ++ virtual) interface this port (i.e. create an interface for a WiFi ++ module or a VLAN device). ++ ++ The interface is not brought up. Use the 'up' command to do that. ++ ++include::include-description.txt[] ++ ++'down':: ++ Shuts down the port. ++ ++'edit':: ++ This command can be used to alter the configuration of a port. ++ Consult the documentation of the port hook to find out what is supported. ++ ++'identify':: ++ This command will make the port flash for a few seconds ++ so that you can identify the correct network adapters ++ in the system. ++ ++ This is not supported by all network adapters. ++ ++'remove':: ++ This will remove an existing PORT. ++ ++ This does not destroy the port. It inverses the operation performed ++ by the 'create' command. ++ ++'status':: ++ This will show some detailed information about the status ++ of the specified port. ++ ++'up':: ++ Brings up the port. It has to be created first. ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-port.xml b/man/network-port.xml +deleted file mode 100644 +index 5c0a8ae..0000000 +--- a/man/network-port.xml ++++ /dev/null +@@ -1,245 +0,0 @@ +- +- +- +- +- +- network-port +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-port +- 8 +- +- +- +- network-port +- Network Configuration Control Program +- +- +- +- +- network port [new|destroy] PORT ... +- +- +- +- network port PORT command ... +- +- +- +- +- Description +- +- +- With help of the port command, you can create, delete, +- change and view the configuration and status of ports. +- +- +- +- A port is a physical or virtual device that is directly connected +- to an other network. If connects those and zones together. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- new HOOK ARGUMENTS +- +- +- +- +- A new port may be created by the new +- command. +- +- +- HOOK must be a valid +- hook which may require more ARGUMENTS. +- +- +- +- +- +- +- destroy PORT +- +- +- +- +- A port can be destroyed with this command. +- +- +- The port is removed from any zones it is attached +- to and shut down. +- +- +- +- +- +- +- For all other commands, the name of the port needs to be passed first: +- +- +- +- +- +- PORT create +- +- +- +- +- This will create an existing PORT. +- +- +- This does not create a new port. It will just create the (possibly +- virtual) interface this port (i.e. create an interface for a WiFi +- module or a VLAN device). +- +- +- The interface is not brought up. Use the up command +- to do that. +- +- +- +- +- +- +- PORT remove +- +- +- +- +- This will remove an existing PORT. +- +- +- This does not destroy the port. It inverses the operation performed +- by the create command. +- +- +- +- +- +- +- PORT [up|down] +- +- +- +- +- These commands will bring the port up or down. It has to be +- created first. +- +- +- +- +- +- PORT color +- +- +- +- +- This command allows settings a color for a port. +- See +- +- network-color +- 8 +- +- for more information. +- +- +- +- +- +- PORTdescription +- +- +- +- +- This command allows you to add a description to a port. +- See +- +- network-description +- 8, +- +- for more information. +- +- +- +- +- +- PORT edit ARGUMENTS +- +- +- +- +- The edit command can be used to alter +- the configuration of a port. Consult the documentation of the +- port hook to find out which ARGUMENTS +- are supported. +- +- +- +- +- +- +- PORT status +- +- +- +- +- This will show some detailed information about the state +- if the specified port. +- +- +- +- +- +- +- PORT identify +- +- +- +- +- This command will make the port flash for a few seconds +- so that you can identify the correct network adapters +- in the system. +- +- +- This is not supported by all network adapters. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8, +- +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0074-man-Converting-network-quick-start-8-to-asciidoc.patch b/network/patches/0074-man-Converting-network-quick-start-8-to-asciidoc.patch new file mode 100644 index 000000000..8f99ad13a --- /dev/null +++ b/network/patches/0074-man-Converting-network-quick-start-8-to-asciidoc.patch @@ -0,0 +1,275 @@ +From 27b9807e568edee69afa758481be164662770901 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:40:35 +0200 +Subject: [PATCH 074/304] man: Converting network-quick-start(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-quick-start.txt | 92 +++++++++++++++++++++ + man/network-quick-start.xml | 155 ------------------------------------ + 2 files changed, 92 insertions(+), 155 deletions(-) + create mode 100644 man/network-quick-start.txt + delete mode 100644 man/network-quick-start.xml + +diff --git a/man/network-quick-start.txt b/man/network-quick-start.txt +new file mode 100644 +index 0000000..02ebfe0 +--- /dev/null ++++ b/man/network-quick-start.txt +@@ -0,0 +1,92 @@ ++network-quick-start(8) ++====================== ++ ++NAME ++---- ++network-quick-start - Quick Start Guide for Networking ++ ++DESCRIPTION ++----------- ++The link:network[8] is a very powerful command that allows you to configure ++the entire networking stack. ++Unfortunately that makes it quite complicated to use as well. ++ ++This guide tries to be a good starting point to set up basic networking with ++the 'network' command. ++ ++=== Adding an Uplink Zone ++ ++The first step is to create a new uplink zone with name 'upl0'. ++ ++This zone will be of the link:network-zone-bridge[8] type which is the default ++for all local networks. ++ ++------------ ++# network zone new upl0 bridge ++------------ ++ ++The zone will be created and brought up immediately. ++ ++=== Attaching Ports ++ ++To connect the zone to the physical world outside of our box we will need ++to attach ports to the zone. That is done with a single command. ++To execute this command, we will need to know which ports are available. ++One of the easiest way to find out about that is to use the auto-completion ++feature of the shell like this: ++ ++------------ ++# network zone upl0 port attach [TAB] [TAB] ++------------ ++ ++That will list all not yet attached ports. The following command will actually ++attach the port (which is 'p0' in this example). ++ ++----------- ++# network zone upl0 port attach p0 ++----------- ++ ++You can as well get a list of all detected devices, zones and ports by running: ++ ++----------- ++# network device list ++----------- ++ ++To a zone of the 'bridge' type you may attach more than just one port if you ++wish to. ++ ++=== IP Connectivity ++ ++After a zone has been created and ports have been attached, you are now ++able to add IP connectivity. ++ ++The easiest way to do that is using DHCP which can be enabled by this simple command: ++ ++------------ ++# network zone upl0 config new dhcp ++------------ ++ ++=== Debugging ++ ++You may see the current status of the network by running this command: ++ ++------------ ++# network status ++------------ ++ ++The entire network can be restarted by running: ++ ++------------ ++# network restart ++------------ ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8], ++link:network-device[8], ++link:network-port[8], ++link:network-zone[8] +diff --git a/man/network-quick-start.xml b/man/network-quick-start.xml +deleted file mode 100644 +index ea79700..0000000 +--- a/man/network-quick-start.xml ++++ /dev/null +@@ -1,155 +0,0 @@ +- +- +- +- +- +- network-quick-start +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-quick-start +- 8 +- +- +- +- network-quick-start +- Network Configuration Control Program +- +- +- +- Quick Start Guide +- +- +- The network is a very powerful command that allows +- you to configure the entire networking stack. Unfortunately that makes +- it quite complicated to use as well. +- This guide tries to be a good starting point to set up basic networking +- with the network command. +- +- +- +- +- Add an uplink zone +- +- +- The first step is to create a new uplink zone with name +- upl0. +- This zone will be of the bridge type which is +- the default for all local networks. +- +- +- # network zone new upl0 bridge +- +- +- The zone will be created and brought up immediately. +- +- +- +- +- Attaching ports +- +- +- To connect the zone to the physical world outside of our box we will need +- to attach ports to the zone. +- That is done with a single command. +- To execute this command, we will need to know which ports are available. +- One of the easiest way to find out about that is to use the auto-completion +- feature of the shell like this: +- +- +- # network zone upl0 port attach [TAB] [TAB] +- +- +- That will list all not yet attached ports. +- The following command will actually attach the port +- (which is p0 in this example). +- +- +- # network zone upl0 port attach p0 +- +- +- You can as well get a list of all detected devices, +- zones and ports by running: +- +- +- # network device list +- +- +- To a zone of the bridge type you may attach more +- than just one port if you wish so. +- +- +- +- +- IP connectivity +- +- +- After a zone has been created and ports have been attached, you are now +- able to add IP connectivity. +- The easiest way to do that is using DHCP which can be enabled by this +- simple command: +- +- +- # network zone upl0 config new ipv6-dhcp +- +- +- And for IPv4: +- +- +- # network zone upl0 config new ipv4-dhcp +- +- +- +- Debugging +- +- +- You may see the current status of the network by running this command: +- +- +- # network status +- +- +- The entire network can be restarted by running: +- +- +- # network restart +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-config +- 8 +- , +- +- network-device +- 8 +- , +- +- network-port +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0075-man-Use-include-for-color-commands.patch b/network/patches/0075-man-Use-include-for-color-commands.patch new file mode 100644 index 000000000..eccd76aec --- /dev/null +++ b/network/patches/0075-man-Use-include-for-color-commands.patch @@ -0,0 +1,55 @@ +From d28ccf91678256bc299fed2c10b066682487b1e9 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:53:20 +0200 +Subject: [PATCH 075/304] man: Use include for color commands + +Signed-off-by: Michael Tremer +--- + man/include-color.txt | 9 +++++++++ + man/network-port.txt | 7 +++---- + 2 files changed, 12 insertions(+), 4 deletions(-) + create mode 100644 man/include-color.txt + +diff --git a/man/include-color.txt b/man/include-color.txt +new file mode 100644 +index 0000000..073c01b +--- /dev/null ++++ b/man/include-color.txt +@@ -0,0 +1,9 @@ ++'color set ':: ++ The color is set with this command and required to be passed in ++ RGB hex formatting ++ ++ NOTE: The color is being used to make identification of network devices ++ easier on the command line and web user interface. ++ ++'color reset':: ++ Resets the color to blank. +diff --git a/man/network-port.txt b/man/network-port.txt +index 08b9e90..0c26f33 100644 +--- a/man/network-port.txt ++++ b/man/network-port.txt +@@ -10,7 +10,8 @@ SYNOPSIS + [verse] + 'network port' new HOOK ... + 'network port' destroy PORT +-'network port' PORT color ++'network port' PORT color set ++'network port' PORT color reset + 'network port' PORT create + 'network port' PORT description edit + 'network port' PORT description show +@@ -45,9 +46,7 @@ The following commands are understood: + + For all other commands, the name of the port needs to be passed first: + +-'color':: +- This command allows settings a color for a port. +- See link:network-color[8] for more information. ++include::include-color.txt[] + + 'create':: + This will create devices for the existing port PORT. +-- +2.39.2 + diff --git a/network/patches/0076-man-Drop-old-network-color-8-man-page.patch b/network/patches/0076-man-Drop-old-network-color-8-man-page.patch new file mode 100644 index 000000000..a670acfb6 --- /dev/null +++ b/network/patches/0076-man-Drop-old-network-color-8-man-page.patch @@ -0,0 +1,72 @@ +From 7c329515f1e23231c315d41b55c4d9bea58c7d1c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:54:02 +0200 +Subject: [PATCH 076/304] man: Drop old network-color(8) man page + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 - + man/network-color.txt | 39 --------------------------------------- + 2 files changed, 40 deletions(-) + delete mode 100644 man/network-color.txt + +diff --git a/Makefile.am b/Makefile.am +index 287a111..26f2e9c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -455,7 +455,6 @@ INSTALL_DIRS += \ + MANPAGES = \ + man/firewall-settings.8 \ + man/network.8 \ +- man/network-color.8 \ + man/network-device.8 \ + man/network-dhcp.8 \ + man/network-dns-server.8 \ +diff --git a/man/network-color.txt b/man/network-color.txt +deleted file mode 100644 +index f3be474..0000000 +--- a/man/network-color.txt ++++ /dev/null +@@ -1,39 +0,0 @@ +-network-color(8) +-================ +- +-NAME +----- +-network-color - Allows assigning a color to a zone or port +- +-SYNOPSIS +--------- +-[verse] +-'network' [zone ZONE|port PORT] color set AABBCC +-'network' [zone ZONE|port PORT] reset +- +-DESCRIPTION +------------ +-The 'color' command helps to manage colors for zones and ports. +-The color is being used to make identification of a zone or port easier on the +-command line and web user interface. +- +-COMMANDS +--------- +-The following commands are understood: +- +-'set' [AABBCC]:: +- The color of a zone or port is set with the 'set' command. +- It is required to pass a color in hex formatting. +- +-'reset':: +- Resets the color of a zone or port to blank. +- +-AUTHOR +------- +-Jonatan Schlag +- +-SEE ALSO +--------- +-link:network[8] +-link:network-zone[8] +-link:network-port[8] +-- +2.39.2 + diff --git a/network/patches/0077-man-Fix-page-headers.patch b/network/patches/0077-man-Fix-page-headers.patch new file mode 100644 index 000000000..ccf34d48b --- /dev/null +++ b/network/patches/0077-man-Fix-page-headers.patch @@ -0,0 +1,38 @@ +From ec3a18b8cf262977d6fd73cee231338ce1b96ffd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 30 Sep 2018 22:55:51 +0200 +Subject: [PATCH 077/304] man: Fix page headers + +Signed-off-by: Michael Tremer +--- + man/network-device.txt | 4 ++-- + man/network-dhcp.txt | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/man/network-device.txt b/man/network-device.txt +index 33fcefa..4f1c1b0 100644 +--- a/man/network-device.txt ++++ b/man/network-device.txt +@@ -1,5 +1,5 @@ +-network(8) +-========== ++network-device(8) ++================= + + NAME + ---- +diff --git a/man/network-dhcp.txt b/man/network-dhcp.txt +index a448619..bcb768e 100644 +--- a/man/network-dhcp.txt ++++ b/man/network-dhcp.txt +@@ -1,5 +1,5 @@ +-network(8) +-========== ++network-dhcp(8) ++=============== + + NAME + ---- +-- +2.39.2 + diff --git a/network/patches/0078-man-Convert-network-route-8-to-asciidoc.patch b/network/patches/0078-man-Convert-network-route-8-to-asciidoc.patch new file mode 100644 index 000000000..b2030772a --- /dev/null +++ b/network/patches/0078-man-Convert-network-route-8-to-asciidoc.patch @@ -0,0 +1,157 @@ +From 70172845e300fb2bf491d471224bd087b0c4e0f4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 15:08:46 +0200 +Subject: [PATCH 078/304] man: Convert network-route(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-route.txt | 32 ++++++++++++++ + man/network-route.xml | 97 ------------------------------------------- + 2 files changed, 32 insertions(+), 97 deletions(-) + create mode 100644 man/network-route.txt + delete mode 100644 man/network-route.xml + +diff --git a/man/network-route.txt b/man/network-route.txt +new file mode 100644 +index 0000000..bf3ddb4 +--- /dev/null ++++ b/man/network-route.txt +@@ -0,0 +1,32 @@ ++network-route(8) ++================ ++ ++NAME ++---- ++network-route - Manage Routing ++ ++SYNOPSIS ++-------- ++[verse] ++'network route' COMMAND ... ++ ++DESCRIPTION ++----------- ++This command helps to manage routes. ++ ++COMMANDS ++-------- ++The following commands are understood: ++ ++'static' ...:: ++ Static routes are managed by the 'static' command followed by the options ++ for static routes which are described in link:network-route-static[8] ++ ++AUTHORS ++------- ++Michael Tremer ++ ++SEE ALSO ++-------- ++link:network[8], ++link:network-route-static[8] +diff --git a/man/network-route.xml b/man/network-route.xml +deleted file mode 100644 +index 207a5ce..0000000 +--- a/man/network-route.xml ++++ /dev/null +@@ -1,97 +0,0 @@ +- +- +- +- +- +- network-route +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-route +- 8 +- +- +- +- network-route +- Network Configuration Control Program +- +- +- +- +- network route COMMAND +- +- +- +- +- Description +- +- +- The route helps to manage routes. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- static +- +- +- +- +- Static routes are managed by the static command +- followed by the options for static routes which are described in: +- +- network-route-static +- 8 +- +- +- +- +- +- +- +- +- Route Types +- +- +- static +- +- +- A static route is a route which does not change when the network changes. +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-route-static +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0079-.gitignore-Ignore-DS_Store.patch b/network/patches/0079-.gitignore-Ignore-DS_Store.patch new file mode 100644 index 000000000..010ed44d1 --- /dev/null +++ b/network/patches/0079-.gitignore-Ignore-DS_Store.patch @@ -0,0 +1,26 @@ +From 82003431a4998e04e0e67f12ee6c3b6e5e802901 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 15:10:49 +0200 +Subject: [PATCH 079/304] .gitignore: Ignore DS_Store + +Signed-off-by: Michael Tremer +--- + .gitignore | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.gitignore b/.gitignore +index 36c85a1..bb093d3 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -14,6 +14,8 @@ + /*.tar.bz2 + /*.tar.gz + /*.tar.xz ++.DS_Store ++._.DS_Store + *.log + *.cache + *.la +-- +2.39.2 + diff --git a/network/patches/0080-man-Convert-network-route-static-8-to-asciidoc.patch b/network/patches/0080-man-Convert-network-route-static-8-to-asciidoc.patch new file mode 100644 index 000000000..8d2f01413 --- /dev/null +++ b/network/patches/0080-man-Convert-network-route-static-8-to-asciidoc.patch @@ -0,0 +1,280 @@ +From d715390e9b1c4cc72bd22b915a842acc96912108 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 15:34:19 +0200 +Subject: [PATCH 080/304] man: Convert network-route-static(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-route-static.txt | 69 +++++++++++++ + man/network-route-static.xml | 183 ----------------------------------- + 2 files changed, 69 insertions(+), 183 deletions(-) + create mode 100644 man/network-route-static.txt + delete mode 100644 man/network-route-static.xml + +diff --git a/man/network-route-static.txt b/man/network-route-static.txt +new file mode 100644 +index 0000000..d4774b2 +--- /dev/null ++++ b/man/network-route-static.txt +@@ -0,0 +1,69 @@ ++= network-route-static(8) ++Michael Tremer ++ ++== NAME ++network-route - Manage Static Routing ++ ++== SYNOPSIS ++[verse] ++'network route static' COMMAND ... ++'network route static add' NETWORK [--gateway=GATEWAY,--unreachable,--prohibit,--blackhole] [--mtu=MTU] ++'network route static remove' NETWORK ++'network route static list' [--protocol=ipv6|ipv4] ++ ++== DESCRIPTION ++This command helps to manage routes. ++ ++== COMMANDS ++The following commands are understood: ++ ++'add' NETWORK ...:: ++ A new route may be added by the 'add' command. It is required to pass a ++ valid network prefix NETWORK, which can be either IPv6 or IPv4. ++ + ++ For unicast routes, the '--gateway=GATEWAY' option must be passed, where ++ GATEWAY is a valid IP address of the same protocol type as the network ++ prefix is. ++ + ++ Use '--unreachable', '--prohibit', '--blackhole' can be used to create of ++ that type. See ROUTE TYPES below for more information about these options. ++ + ++ The optional '--mtu=MTU' parameter defines the MTU along the path to the ++ destination and must be an integer number. This will show you very ++ detailed information about the given device. ++ ++'remove' NETWORK:: ++ A route can be removed with this command. ++ + ++ NETWORK is the network prefix of an existing route. ++ ++'list':: ++ Shows a list of all configured routes. ++ + ++ Output can be filtered by passing --protocol=[ipv6|ipv4]. ++ ++== ROUTE TYPES ++ ++[horizontal] ++'unicast':: ++ A unicast route is the most common route in routing tables. It is a route to ++ a destination network address, which describes the path to the destination. ++ Use the '--gateway=GATEWAY' option to create such a route. ++ ++'unreachable':: ++ When a route is determined and the routing decision process returns a ++ destination with an unreachable route type, an ICMP unreachable message is ++ generated and returned to the source address. ++ ++'prohibit':: ++ This works like an _unreachable_ route, but the returned ICMP message is an ++ ICMP prohibited message. ++ ++'blackhole':: ++ Packets matching this kind of route are silently discarded. ++ There will be no ICMP message sent to the source and no packet be forwarded. ++ ++== SEE ALSO ++link:network[8], ++link:network-route[8], ++link:ip-route[8] +diff --git a/man/network-route-static.xml b/man/network-route-static.xml +deleted file mode 100644 +index d43eb62..0000000 +--- a/man/network-route-static.xml ++++ /dev/null +@@ -1,183 +0,0 @@ +- +- +- +- +- +- network-route-static +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-route-static +- 8 +- +- +- +- network-route-static +- Network Configuration Control Program +- +- +- +- +- network route static COMMAND +- +- +- +- +- Description +- +- +- The route static helps to manage static routes. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- add NETWORK [, , , ] [] +- +- +- +- +- A new route may be added by the add command. +- It is always required to pass a valid network prefix +- NETWORK, which can be either +- IPv6 or IPv4. +- +- +- For unicast routes, the +- option must be passed, where GATEWAY +- is a valid IP address of the same protocol type as the +- network prefix is. +- +- +- Use , , +- can be used to create of that +- type. See ROUTE TYPES below for more +- information about these options. +- +- +- The optional parameter defines the +- MTU along the path to the destination and must be an integer +- number. This will show you very detailed information about +- the given device. +- +- +- +- +- +- +- remove NETWORK +- +- +- +- +- A route can be removed with the command. +- +- +- NETWORK is the network prefix +- of an existing route. +- +- +- +- +- +- +- list [] +- +- +- +- +- Shows a list of all configured routes. +- +- +- Pass the protocol option to filter the output only for the +- given protocol. +- +- +- +- +- +- +- +- Route Types +- +- +- unicast +- +- +- A unicast route is the most common route in routing tables. +- It is a route to a destination network address, which describes +- the path to the destination. +- Use the option to create such +- a route. +- +- +- +- +- unreachable +- +- +- When a route is determined and the routing decision process +- returns a destination with an unreachable route type, an ICMP +- unreachable message is generated and returned to the source +- address. +- +- +- +- +- prohibit +- +- +- This works like an unreachable route, but +- the returned ICMP message is an ICMP prohibited message. +- +- +- +- +- blackhole +- +- +- Packets matching this kind of route are silently discarded. +- There will be no ICMP message sent to the source and no packet +- be forwarded. +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-route +- 8 +- , +- +- ip-route +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0081-man-Convert-network-settings-8-to-asciidoc.patch b/network/patches/0081-man-Convert-network-settings-8-to-asciidoc.patch new file mode 100644 index 000000000..f0e629f46 --- /dev/null +++ b/network/patches/0081-man-Convert-network-settings-8-to-asciidoc.patch @@ -0,0 +1,190 @@ +From daebec37ca3cd19e000d1a9c1a77448d8c155fcd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 15:47:14 +0200 +Subject: [PATCH 081/304] man: Convert network-settings(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-settings.txt | 44 +++++++++++++++ + man/network-settings.xml | 118 --------------------------------------- + 2 files changed, 44 insertions(+), 118 deletions(-) + create mode 100644 man/network-settings.txt + delete mode 100644 man/network-settings.xml + +diff --git a/man/network-settings.txt b/man/network-settings.txt +new file mode 100644 +index 0000000..e77f038 +--- /dev/null ++++ b/man/network-settings.txt +@@ -0,0 +1,44 @@ ++= network-settings(8) ++Michael Tremer ++ ++== NAME ++network-settings - Change global network settings ++ ++== SYNOPSIS ++'network settings' ++'network settings' KEY=VALUE ++ ++== DESCRIPTION ++The 'network settings' command may be used to set global settings. ++ ++Please have a look at the individual man pages for more options. ++ ++== COMMANDS ++If no additional argument is given, running the command will dump a list of ++all settings variables and their current values. ++ ++You may set a new value by adding the variable name and the new ++value to the command line. ++ ++== VARIABLES ++ ++'DEBUG=[true|_false_]':: ++ The DEBUG will control whether debug logging is enabled or not. ++ Additionally to writing debug log messages to the log files, the messages ++ will be displayed on the console as well. ++ ++'WIRELESS_REGULATORY_DOMAIN=_00_':: ++ The wireless regulatory domain is set globally for the entire system with ++ the WIRELESS_REGULATORY_DOMAIN setting. ++ + ++ The default is '00' which is the _world_ setting. ++ + ++ Valid values are country codes for countries which have their own ++ regulatory domain. ++ ++== AUTHORS ++Michael Tremer ++ ++== SEE ALSO ++link:network[8], ++link:network-dns-server[8] +diff --git a/man/network-settings.xml b/man/network-settings.xml +deleted file mode 100644 +index 7d1c70d..0000000 +--- a/man/network-settings.xml ++++ /dev/null +@@ -1,118 +0,0 @@ +- +- +- +- +- +- network-settings +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-settings +- 8 +- +- +- +- network-settings +- Network Configuration Control Program +- +- +- +- +- network settings +- +- +- +- network settings KEY=VALUE +- +- +- +- +- Description +- +- +- The network settings command may be used to set +- global settingsuration options. +- +- +- Please have a look at the individual man pages for more options. +- +- +- +- +- Commands +- +- +- If no additional argument is given, running the command will +- dump a list of all settingsuration variables and their current values. +- +- +- +- You may set a new value by adding the variable name and the new +- value to the command line. +- +- +- +- +- Variables +- +- +- +- +- DEBUG=[0|1] +- +- +- +- +- The DEBUG will control whether debug +- logging is enabled or not. Additionally to writing debug +- log messages to the log files, the messages will be displayed +- on the console as well. +- +- +- +- +- +- +- WIRELESS_REGULATORY_DOMAIN=00 +- +- +- +- +- The wireless regulatory domain is set globally for the +- entire system with the WIRELESS_REGULATORY_DOMAIN +- setting. The default is 00 which +- is the world setting. +- Valid values are country codes for countries which have their +- own regulatory domain. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-dns-server +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0082-man-Convert-network-vpn-8-to-asciidoc.patch b/network/patches/0082-man-Convert-network-vpn-8-to-asciidoc.patch new file mode 100644 index 000000000..b284f76dc --- /dev/null +++ b/network/patches/0082-man-Convert-network-vpn-8-to-asciidoc.patch @@ -0,0 +1,135 @@ +From 9848b81e6e8c2732920d9a7a115110723e2b07bb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 15:59:21 +0200 +Subject: [PATCH 082/304] man: Convert network-vpn(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-vpn.txt | 26 +++++++++++++++ + man/network-vpn.xml | 81 --------------------------------------------- + 2 files changed, 26 insertions(+), 81 deletions(-) + create mode 100644 man/network-vpn.txt + delete mode 100644 man/network-vpn.xml + +diff --git a/man/network-vpn.txt b/man/network-vpn.txt +new file mode 100644 +index 0000000..5a905db +--- /dev/null ++++ b/man/network-vpn.txt +@@ -0,0 +1,26 @@ ++= network-vpn(8) ++Michael Tremer ++ ++== NAME ++network-vpn - Configure Virtual Private Networks ++ ++== SYNOPSIS ++'network vpn' COMMAND ... ++ ++== DESCRIPTION ++The 'vpn' command allows to create, delete, edit and show the status of VPN ++connections and the configuration around it. ++ ++== COMMANDS ++The following commands are understood: ++ ++'security-policies' ...:: ++ Use this command to manage security policies. ++ + ++ See link:network-vpn-security-policies[8] for details. ++ ++== AUTHORS ++Michael Tremer ++ ++== SEE ALSO ++link:network[8] +diff --git a/man/network-vpn.xml b/man/network-vpn.xml +deleted file mode 100644 +index d71d14a..0000000 +--- a/man/network-vpn.xml ++++ /dev/null +@@ -1,81 +0,0 @@ +- +- +- +- +- +- network-vpn +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-vpn +- 8 +- +- +- +- network-vpn +- Network Configuration Control Program +- +- +- +- +- network vpn command ... +- +- +- +- +- Description +- +- +- The vpn command allows to create, delete, edit +- and show the status of VPN connections and the configuration around it. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- security-policies ... +- +- +- +- +- Use this command to manage security policies. +- See +- network-vpn-security-policies +- 8 +- for details. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0083-man-Convert-network-vpn-security-policies-8-to-ascii.patch b/network/patches/0083-man-Convert-network-vpn-security-policies-8-to-ascii.patch new file mode 100644 index 000000000..6aa5702e5 --- /dev/null +++ b/network/patches/0083-man-Convert-network-vpn-security-policies-8-to-ascii.patch @@ -0,0 +1,453 @@ +From 0a31681e96ee9ed656bf5ce531d4057079a897be Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 16:30:26 +0200 +Subject: [PATCH 083/304] man: Convert network-vpn-security-policies(8) to + asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-vpn-security-policies.txt | 111 +++++++++ + man/network-vpn-security-policies.xml | 313 -------------------------- + 2 files changed, 111 insertions(+), 313 deletions(-) + create mode 100644 man/network-vpn-security-policies.txt + delete mode 100644 man/network-vpn-security-policies.xml + +diff --git a/man/network-vpn-security-policies.txt b/man/network-vpn-security-policies.txt +new file mode 100644 +index 0000000..f9dc91a +--- /dev/null ++++ b/man/network-vpn-security-policies.txt +@@ -0,0 +1,111 @@ ++= network-vpn-security-policies(8) ++Michael Tremer ++ ++== NAME ++network-vpn-security-policies - Configure VPN Security Policies ++ ++== SYNOPSIS ++[verse] ++'network vpn security-policies [new|destroy]' NAME... ++'network vpn security-policies' NAME COMMAND ... ++ ++== DESCRIPTION ++With help of the 'vpn security-policies', it is possible to create, destroy ++and edit VPN security policies. ++ ++A security policy is a definition of ciphers and algorithms for integrity ++and key-exchanges for VPN connections. ++ ++== COMMANDS ++The following commands are understood: ++ ++'new NAME':: ++ A new security policy may be created with the 'new' command. ++ + ++ NAME does not allow any spaces. ++ ++'destroy NAME':: ++ A security policy can be destroyed with this command. ++ + ++ If the policy is still in use, it cannot be deleted. ++ ++For all other commands, the name of the security policy needs to be passed first: ++ ++'NAME show':: ++ Shows the configuration of the security policy. ++ ++'NAME key-exchange' [IKEv2|IKEv1]:: ++ Defines the key exchange algorithm that should be used to initiate an ++ IPsec VPN connection. ++ ++'NAME ciphers' [CIPHER-LIST|+CIPHER ...|-CIPHER ...]:: ++ This command allows modifying the cipher list. ++ A new CIPHER-LIST can be passed which will replace the current configuration. ++ Alternatively, new ciphers can be added by prepending a + sign to the cipher ++ name and can removed likewise using -. ++ + ++ A cipher is an algorithm that encrypts and decrypts data to be able to ++ transmit it over an insecure channel. ++ ++'NAME integrities' [INTEGRITY-LIST|+INTEGRITY ...|-INTEGRITY ...]:: ++ This command allows modifying the integrity list similar to the ++ 'ciphers' command. ++ + ++ Integrity algorithms are used to be able to determine if data has been ++ altered when being transferred over an untrusted channel. ++ ++'NAME pseudo-random-functions' [PSEUDO-RANDOM-FUNCTION-LIST|+PSEUDO-RANDOM-FUNCTION...|-PSEUDO-RANDOM-FUNCTION]:: ++ This command allows modifying the list of pseudo random functions ++ similar to the 'ciphers' command. ++ + ++ These functions are used in combination with an AEAD cipher only. ++ ++'NAME group-types' [GROUP-TYPES-LIST|+GROUP-TYPE ...|-GROUP-TYPE]:: ++ This command allows modifying the list of group types similar to the ++ 'ciphers' command. ++ + ++ These algorithms are used to negotiate a shared secret of an insecure channel. ++ ++'NAME pfs' [on|off]:: ++ This command allows to enable or disable Perfect Forward Secrecy (PFS). ++ If PFS is enabled, the encrypted channels of a VPN connection will be ++ renegotiated regularly to avoid that the same keys are used for too long. ++ If an attacker is able to obtain a key that was used to encrypt the ++ data, it is only possible to decrypt a certain amount of data. ++ + ++ It is strongly recommended to enable PFS at all times. ++ ++'NAME lifetime' LIFETIME:: ++ This command allows to define how often the VPN connection is ++ renegotiated if PFS is enabled. ++ ++'NAME compression' [on|off]:: ++ This command allows to enable or disable compression. ++ If compression is enabled, all data is being compressed before being ++ sent through the VPN. ++ This setting is ignored if the peer does not support this. ++ ++== System Policies ++ ++The system comes with builtin policies that cannot be modified by the user. ++They are intended to provide good defaults for various situations. ++ ++[horizontal] ++'system':: ++ This policy is the default for every VPN connection and allows using ++ all ciphers, integrity and key-exchange algorithms that are recommended ++ to use and have not been proven or assumed to be broken, yet. ++ + ++ Over time, this policy will change whenever an algorithm has been broken ++ and is not recommended to be used any more. ++ ++'performance':: ++ This policy is recommended to be used on systems that are not very powerful. ++ Algorithms with smaller key lengths, but still considered to be secure ++ are being used. ++ ++System policies cannot be deleted. ++ ++== SEE ALSO ++link:network[8], ++link:network-vpn[8] +diff --git a/man/network-vpn-security-policies.xml b/man/network-vpn-security-policies.xml +deleted file mode 100644 +index 40e6213..0000000 +--- a/man/network-vpn-security-policies.xml ++++ /dev/null +@@ -1,313 +0,0 @@ +- +- +- +- +- +- network-vpn-security-policies +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-vpn-security-policies +- 8 +- +- +- +- network-vpn-security-policies +- Network Configuration Control Program +- +- +- +- +- network vpn security-policies [new|destroy] NAME ... +- +- +- +- network vpn security-policies NAME command ... +- +- +- +- +- Description +- +- +- With help of the vpn security-policies, it is possible +- to create, destroy and edit VPN security policies. +- +- +- A security policy is a definition of ciphers and algorithms for integrity +- and key-exchanges for VPN connections. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- new NAME +- +- +- +- +- A new security policy may be created with the +- new command. +- +- +- +- NAME does not allow any spaces. +- +- +- +- +- +- +- destroy NAME +- +- +- +- +- A security policy can be destroyed with this command. +- +- +- If the policy is still in use, it cannot be deleted. +- +- +- +- +- +- +- For all other commands, the name of the security policy needs to be passed first: +- +- +- +- +- +- NAME show +- +- +- +- +- Shows the configuration of the security policy. +- +- +- +- +- +- +- NAME key-exchange [IKEv2|IKEv1] +- +- +- +- +- Defines the key exchange algorithm that should be used to +- initiate an IPsec VPN connection. +- +- +- +- +- +- +- NAME ciphers [CIPHER-LIST|+CIPHER ...|-CIPHER ...] +- +- +- +- +- This command allows modifying the cipher list. +- +- +- +- A new CIPHER-LIST can be passed +- which will replace the current configuration. +- Alternatively, new ciphers can be added by prepending a +- + sign to the cipher name and can removed likewise +- using -. +- +- +- +- A cipher is an algorithm that encrypts and decrypts data +- to be able to transmit it over an insecure channel. +- +- +- +- +- +- +- NAME integrities [INTEGRITY-LIST|+INTEGRITY ...|-INTEGRITY ...] +- +- +- +- +- This command allows modifying the integrity list +- similar to the ciphers command. +- +- +- +- Integrity algorithms are used to be able to determine +- if data has been altered when being transfered over +- an untrusted channel. +- +- +- +- +- +- +- NAME pseudo-random-functions [PSEUDO-RANDOM-FUNCTION-LIST|+PSEUDO-RANDOM-FUNCTION...|-PSEUDO-RANDOM-FUNCTION] +- +- +- +- +- +- This command allows modifying the list of pseudo random functions +- similar to the ciphers command. +- +- +- +- These functions are used in combination with an AEAD cipher only. +- +- +- +- +- +- +- NAME group-types [GROUP-TYPES-LIST|+GROUP-TYPE ...|-GROUP-TYPE] +- +- +- +- +- +- This command allows modifying the list of group types +- similar to the ciphers command. +- +- +- +- These algorithms are used to negotiate a shared secret +- of an insecure channel. +- +- +- +- +- +- +- NAME pfs [on|off] +- +- +- +- +- This command allows to enable or disable Perfect Forward Secrecy (PFS). +- +- +- +- If PFS is enabled, the encrypted channels of a VPN connection will be +- renegotiated regularly to avoid that the same keys are used for too long. +- If an attacker is able to obtain a key that was used to encrypt the +- data, it is only possible to decrypt a certain amount of data. +- +- +- +- It is strongly recommended to enable PFS at all times. +- +- +- +- +- +- +- NAME lifetime LIFETIME +- +- +- +- +- This command allows to define how often the VPN connection is +- renegotiated if PFS is enabled. +- +- +- +- +- +- +- NAME compression [on|off] +- +- +- +- +- This command allows to enable or disable compression. +- +- +- +- If compression is enabled, all data is being compressed before being +- sent through the VPN. +- This setting is ignored if the peer does not support this. +- +- +- +- +- +- +- +- System Policies +- +- +- The system comes with builtin policies that cannot be modified by the user. +- They are intended to provide good defaults for various situations. +- +- +- +- system +- +- +- This policy is the default for every VPN connection and allows using +- all ciphers, integrity and key-exchange algorithms that are recommended +- to use and have not been proven or assumed to be broken, yet. +- +- +- +- Over time, this policy will change whenever an algorithm has been broken +- and is not recommended to be used any more. +- +- +- +- +- performance +- +- +- This policy is recommended to be used on systems that are not very powerful. +- Algorithms with smaller key lengths, but still considered to be secure +- are being used. +- +- +- +- +- System policies cannot be deleted. +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-vpn +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0084-man-Convert-network-zone-8-to-asciidoc.patch b/network/patches/0084-man-Convert-network-zone-8-to-asciidoc.patch new file mode 100644 index 000000000..0edf995fa --- /dev/null +++ b/network/patches/0084-man-Convert-network-zone-8-to-asciidoc.patch @@ -0,0 +1,375 @@ +From 357723e90cb0f700c4315b6016543db4230df5fb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 16:46:07 +0200 +Subject: [PATCH 084/304] man: Convert network-zone(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/include-color.txt | 2 +- + man/include-description.txt | 2 +- + man/network-zone.txt | 73 +++++++++++ + man/network-zone.xml | 247 ------------------------------------ + 4 files changed, 75 insertions(+), 249 deletions(-) + create mode 100644 man/network-zone.txt + delete mode 100644 man/network-zone.xml + +diff --git a/man/include-color.txt b/man/include-color.txt +index 073c01b..4b417a5 100644 +--- a/man/include-color.txt ++++ b/man/include-color.txt +@@ -1,7 +1,7 @@ + 'color set ':: + The color is set with this command and required to be passed in + RGB hex formatting +- ++ + + NOTE: The color is being used to make identification of network devices + easier on the command line and web user interface. + +diff --git a/man/include-description.txt b/man/include-description.txt +index a39ba55..49bac64 100644 +--- a/man/include-description.txt ++++ b/man/include-description.txt +@@ -1,6 +1,6 @@ + 'description edit':: + This command opens an editor and allows you to edit title and description. +- ++ + + NOTE: The formation of the description is similar to a git commit. + Every description has a title, the first line of the description. + The title is shown on the status page and in the web user interface. +diff --git a/man/network-zone.txt b/man/network-zone.txt +new file mode 100644 +index 0000000..88a1988 +--- /dev/null ++++ b/man/network-zone.txt +@@ -0,0 +1,73 @@ ++= network-zone(8) ++Michael Tremer ++ ++== NAME ++network-zone - Manage network zones ++ ++== SYNOPSIS ++[verse] ++'network zone [new|destroy]' ZONE ++'network zone' ZONE ... ++ ++== DESCRIPTION ++With help of the 'zone' command, it is very easy to configure network zones. ++ ++It is possible to create zones and remove them. Zones may also be brought up ++and down and reconfigured. Their status may be viewed as well. ++ ++== COMMANDS ++The following commands are understood: ++ ++'new ZONE HOOK OPTIONS':: ++ A new zone may be created by the 'create' command. ++ There are at least two arguments required. ++ + ++ ZONE must be valid name for a zone which does not already exist. ++ HOOK is a valid zone hook which may require additional options. ++ ++'destroy ZONE':: ++ A zone can be destroyed with this command. ++ + ++ There are two possible ways to remove a zone. The case is when the zone is ++ not up. Then, it will be removed immediately. When the zone is current up ++ and used, it will tagged to be remove later, after it has been brought down. ++ ++For all other commands, the name of the zone needs to be passed first: ++ ++'edit OPTIONS':: ++ The settings of a zone may be edited after it has been created. ++ The options that can be passed depend on the hook that is used for the zone. ++ Run 'network zone ZONE edit --help' to learn more about that. ++ + ++ It usually is required to restart/reload the zone until the new settings ++ are taken into account. ++ ++'[up|down]':: ++ These commands will bring the zone up/down. This is done without control ++ of systemd, therefore not intended to be done in a productive environment. ++ However, these commands may be used for debugging. ++ ++'[enable|disable]':: ++ These commands will enable or disable the zone. An enabled zone will ++ automatically be started either during the boot process or a hotplug event ++ of an associated port or other device. ++ ++'status':: ++ This will show some detailed information about the state if the specified zone. ++ ++include::include-color.txt[] ++ ++include::include-description.txt[] ++ ++'identify':: ++ This command will make all ports of the zone flash for a few seconds so ++ that you can identify the correct network adapters in the system. ++ ++'rename' NAME:: ++ Renames the zone to NAME. ++ + ++ The command will shut down the zone if it is up and start it again with ++ the new name. If the zone is not up it won't be started. ++ ++== SEE ALSO ++link:network[8] +diff --git a/man/network-zone.xml b/man/network-zone.xml +deleted file mode 100644 +index 99fa8b8..0000000 +--- a/man/network-zone.xml ++++ /dev/null +@@ -1,247 +0,0 @@ +- +- +- +- +- +- network-zone +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone +- 8 +- +- +- +- network-zone +- Network Configuration Control Program +- +- +- +- +- network zone [new|destroy] ZONE ... +- +- +- +- network zone ZONE command ... +- +- +- +- +- Description +- +- +- With help of the zone command, it is very easy to +- configure network zones. +- +- +- It is possible to create zones and remove them. Zones may also +- be brought up and down and reconfigured. Their status may be viewed +- as well. +- +- +- +- +- Commands +- +- +- The following commands are understood: +- +- +- +- +- +- new ZONE HOOK OPTIONS +- +- +- +- +- A new zone may be created by the create +- command. There are at least two arguments required. +- +- +- ZONE must be valid name for a +- zone which does not already exist. +- HOOK is a valid zone hook which +- may require additional options. +- +- +- +- +- +- +- destroy ZONE +- +- +- +- +- A zone can be destroyed with this command. +- +- +- There are two possible ways to remove a zone. The case +- is when the zone is not up. Then, it will be removed +- immediately. When the zone is current up and used, it +- will tagged to be remove later, after it has been brought +- down. +- +- +- +- +- +- +- For all other commands, the name of the zone needs to be passed first: +- +- +- +- +- +- ZONE edit OPTIONS +- +- +- +- +- The settings of a zone may be edited after it has been created. +- The options that can be passed depend on the hook that is used +- for the zone. +- Run network zone ZONE edit --help +- to learn more about that. +- +- +- It usually is required to restart/reload the zone until +- the new settings are taken into account. +- +- +- +- +- +- +- ZONE [up|down] +- +- +- +- +- These commands will bring the zone up/down. This is done +- without control of systemd, therefore not intended to be +- done in a productive environment. +- However, these commands may be used for debugging. +- +- +- +- +- +- +- ZONE [enable|disable] +- +- +- +- +- These commands will enable or disable the zone. An enabled +- zone will automatically be started either during the boot process +- or a hotplug event of an associated port or other device. +- +- +- +- +- +- +- ZONE status +- +- +- +- +- This will show some detailed information about the state +- if the specified zone. +- +- +- +- +- +- ZONE color +- +- +- +- +- This command allows settings a color for a zone. +- See +- +- network-color +- 8 +- +- for more information. +- +- +- +- +- +- ZONEdescription +- +- +- +- +- This command make is possible to add a description to a zone. +- See +- +- network-description +- 8, +- +- for more information. +- +- +- +- +- +- ZONE identify +- +- +- +- +- This command will make all ports of the zone flash for +- a few seconds so that you can identify the correct network +- adapters in the system. +- +- +- +- +- +- +- ZONE rename NAME +- +- +- +- +- Renames the zone to NAME. +- +- +- The command will shut down the zone if it is up and +- start it again with the new name. If the zone is not +- up it won't be started. +- +- +- Zones that are marked to be destroyed cannot be renamed. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0085-man-Convert-network-zone-bridge-8-to-asciidoc.patch b/network/patches/0085-man-Convert-network-zone-bridge-8-to-asciidoc.patch new file mode 100644 index 000000000..6d114cd02 --- /dev/null +++ b/network/patches/0085-man-Convert-network-zone-bridge-8-to-asciidoc.patch @@ -0,0 +1,255 @@ +From 010f24cfc6e363815ae6a408a16e8b07c069c1a7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 16:59:10 +0200 +Subject: [PATCH 085/304] man: Convert network-zone-bridge(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-bridge.txt | 55 ++++++++++++ + man/network-zone-bridge.xml | 172 ------------------------------------ + 2 files changed, 55 insertions(+), 172 deletions(-) + create mode 100644 man/network-zone-bridge.txt + delete mode 100644 man/network-zone-bridge.xml + +diff --git a/man/network-zone-bridge.txt b/man/network-zone-bridge.txt +new file mode 100644 +index 0000000..2e4f839 +--- /dev/null ++++ b/man/network-zone-bridge.txt +@@ -0,0 +1,55 @@ ++= network-zone-bridge(8) ++Michael Tremer ++ ++== NAME ++network-zone-bridge - Manage network zones ++ ++== SYNOPSIS ++[verse] ++'network zone new ZONE bridge' ... ++'network zone ZONE edit' ... ++ ++== DESCRIPTION ++The bridge hook creates an ethernet bridge which acts as an unmanaged network ++switch. It contains one or multiple physical network interfaces or virtual ++devices which will be connected to each other. ++ ++The bridge hook is the preferred hook for local area network zones which are ++connected to an ethernet network. ++ ++== OPTIONS ++The following options are understood: ++ ++'--address=ADDRESS':: ++ By this option, you may define the MAC address of the bridge. If this option ++ is missing, a random MAC address will be generated. ++ ++'--mtu=MTU':: ++ Sets the default MTU of the bridge. ++ All ports in the bridge must support this MTU value. ++ ++'--stp=[_on_|off]':: ++ This option enables or disables use of the _Spanning Tree Protocol_ (STP). ++ This protocol is used to avoid loops in networks by dynamically disabling ++ packet forwarding on links. ++ + ++ It is highly recommended to leave this option enabled when you add more ++ than one device to the zone. Read below how the behaviour of STP can be changed. ++ ++Spanning Tree Protocol (802.1D) configuration options: ++ ++'--stp-forward-delay=_0_':: ++ This sets the default time the interfaces are hold off after they have been ++ added to a bridge. The default value is 0. ++ ++'--stp-hello=_2_':: ++ This option defines how often a hello message should be sent. The value is ++ given in seconds and the default is 2. ++ ++'--stp-priority=512':: ++ The STP priority sets the ranking of this network device within the network. ++ The bridge with the best rank (0 is best) will become the root bridge. ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-zone-bridge.xml b/man/network-zone-bridge.xml +deleted file mode 100644 +index a77118b..0000000 +--- a/man/network-zone-bridge.xml ++++ /dev/null +@@ -1,172 +0,0 @@ +- +- +- +- +- +- network-zone-bridge +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-bridge +- 8 +- +- +- +- network-zone-bridge +- Network Configuration Control Program +- +- +- +- +- network zone new ZONE bridge ... +- +- +- +- network zone ZONE edit ... +- +- +- +- +- Description +- +- +- The bridge hook creates an ethernet bridge which acts as an unmanaged network +- switch. It contains one or multiple phyisical network interfaces or virtual +- devices which will be connected to each other. +- +- +- The bridge hook is the prefered hook for local area network zones which are +- connected to an ethernet network. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- This option enables or disable the use of the +- Spanning Tree Protocol (STP). +- This protocol is used to avoid loops in networks by +- dynamically disabling packet forwarding on links. +- +- +- It is highly recommended to leave this option enabled +- when you add more than one device to the zone. +- Read below how the behaviour of STP can be changed. +- +- +- +- +- +- +- +- +- +- +- +- Sets the default MTU of the bridge. +- All ports in the bridge must support this MTU value. +- +- +- +- +- +- +- +- +- +- +- +- By this option, you may define the MAC address of the +- bridge. If this option is missing, a random MAC address +- will be generated. +- +- +- +- +- +- +- Spanning Tree Protocol (802.1D) configuration options: +- +- +- +- +- +- +- +- +- +- +- This sets the default time the interfaces are hold off +- after they have been added to a bridge. +- The default value is 0. +- +- +- +- +- +- +- +- +- +- +- +- This option defines how often a hello message should be +- sent. The value is given in seconds and the default is 2. +- +- +- +- +- +- +- +- +- +- +- +- The STP priority sets the ranking of this network device +- within the network. The bridge with the best rank +- (0 is best) will become the root bridge. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0086-man-Convert-network-zone-config-pppoe-server-8-to-as.patch b/network/patches/0086-man-Convert-network-zone-config-pppoe-server-8-to-as.patch new file mode 100644 index 000000000..3afd01e9a --- /dev/null +++ b/network/patches/0086-man-Convert-network-zone-config-pppoe-server-8-to-as.patch @@ -0,0 +1,222 @@ +From 718371b565fdb93719f68b5a2dcf719dd57a4e93 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 17:15:50 +0200 +Subject: [PATCH 086/304] man: Convert network-zone-config-pppoe-server(8) to + asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-config-pppoe-server.txt | 50 ++++++++ + man/network-zone-config-pppoe-server.xml | 143 ----------------------- + 2 files changed, 50 insertions(+), 143 deletions(-) + create mode 100644 man/network-zone-config-pppoe-server.txt + delete mode 100644 man/network-zone-config-pppoe-server.xml + +diff --git a/man/network-zone-config-pppoe-server.txt b/man/network-zone-config-pppoe-server.txt +new file mode 100644 +index 0000000..72dff8e +--- /dev/null ++++ b/man/network-zone-config-pppoe-server.txt +@@ -0,0 +1,50 @@ ++= network-zone-config-pppoe-server(8) ++ ++== NAME ++network-zone-config-pppoe-server - PPPoE Server Settings ++ ++== SYNOPSIS ++[verse] ++`network zone ZONE config create pppoe-server ...` ++`network zone ZONE config pppoe-server edit ...` ++ ++== DESCRIPTION ++This configuration hook enables a **PPPoE Server** on a zone. ++ ++== OPTIONS ++The following options are understood: ++ ++`--subnet=SUBNET`:: ++ The `--subnet` option defines an IPv4 pool of which IP addresses are ++ assigned to the remote hosts. The first address of the subnet will be used ++ for the gateway which is the PPPoE server itself. ++ + ++ The subnet must at least have two IP addresses. ++ ++`--mtu=MTU`:: ++ Set the required MTU (Maximum Transmission Unit) for the PPP connection. ++ The default value is 1492 bytes which is a common MTU for DSL connections. ++ ++`--service-name=SERVICE NAME`:: ++ This option receives a string which will be used as the service name. The ++ service name is sent out to the clients and used for identification but ++ not authorisation purposes. ++ + ++ The default is an empty value. ++ ++`--max-sessions=0`:: ++ Limit the number of sessions that may be established by the same MAC address. ++ This must be a positive number. ++ 0 permits an unlimited number of sessions per MAC address. ++ ++== EXAMPLES ++ ++This command creates a PPPoE server that will assign an IP address from the ++192.168.0.0/16 subnet: ++ ++ network zone net0 config create pppoe-server --subnet=192.168.0.0/16 ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8], ++link:network-zone-config[8] +diff --git a/man/network-zone-config-pppoe-server.xml b/man/network-zone-config-pppoe-server.xml +deleted file mode 100644 +index e6d497e..0000000 +--- a/man/network-zone-config-pppoe-server.xml ++++ /dev/null +@@ -1,143 +0,0 @@ +- +- +- +- +- +- network-zone-config-pppoe-server +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-config-pppoe-server +- 8 +- +- +- +- network-zone-config-pppoe-server +- Network Configuration Control Program +- +- +- +- +- network zone ZONE config create pppoe-server ... +- +- +- +- +- Description +- +- +- This configuration hook enables a PPPoE server +- functionality to a zone which is of an ethernet-like type. +- +- +- The PPPoE server is mostly for development purpose and performs pretty +- well. However, it is not recommended to use it in production environments. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- The option defines an IPv4 pool +- of which IP addresses are assigned to the remote hosts. +- The first address of the subnet will be used for the +- gateway which is the PPPoE server itself. +- +- +- The subnet must at least have two IP addresses. +- Broadcast and network addresses will be used as well. +- +- +- +- +- +- +- +- +- +- +- +- Set the required MTU (Maximum Transmission Unit) for +- the PPP connection. +- +- +- The default value is 1492 bytes which is a common MTU for +- DSL connections. +- +- +- +- +- +- +- +- +- +- +- +- This options receives a string which will be used as the +- service name. The service name is sent out to the clients +- and used for identification but not authorization purposes. +- +- +- The default is an empty value. +- +- +- +- +- +- +- +- +- +- +- +- Limit the max. number of sessions that may be established +- by the same MAC address. +- +- +- This must be a positive number. 0 permits an unlimited +- number of sessions per MAC address. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone-config +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0087-man-Convert-network-zone-ip-tunnel-8-to-asciidoc.patch b/network/patches/0087-man-Convert-network-zone-ip-tunnel-8-to-asciidoc.patch new file mode 100644 index 000000000..ce05d4197 --- /dev/null +++ b/network/patches/0087-man-Convert-network-zone-ip-tunnel-8-to-asciidoc.patch @@ -0,0 +1,184 @@ +From 6e94de3efa35088eb322ced2653efeec5f5c29fd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 17:23:07 +0200 +Subject: [PATCH 087/304] man: Convert network-zone-ip-tunnel(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-ip-tunnel.txt | 35 ++++++++++ + man/network-zone-ip-tunnel.xml | 121 --------------------------------- + 2 files changed, 35 insertions(+), 121 deletions(-) + create mode 100644 man/network-zone-ip-tunnel.txt + delete mode 100644 man/network-zone-ip-tunnel.xml + +diff --git a/man/network-zone-ip-tunnel.txt b/man/network-zone-ip-tunnel.txt +new file mode 100644 +index 0000000..cb30731 +--- /dev/null ++++ b/man/network-zone-ip-tunnel.txt +@@ -0,0 +1,35 @@ ++= network-zone-ip-tunnel(8) ++Michael Tremer ++ ++== NAME ++network-zone-ip-tunnel - Manage IP Tunnels ++ ++== SYNOPSIS ++[verse] ++`network zone new ZONE ip-tunnel ...` ++`network zone ZONE edit ...` ++ ++== DESCRIPTION ++The ip-tunnel hook is used to create IP tunnels that use protocols like GRE to ++encapsulate IP packets. ++ ++== OPTIONS ++The following options are understood: ++ ++`--mode=MODE`:: ++ Sets the protocol that is being used to encapsulate IP packets. ++ Currently only **GRE** is supported. ++ ++`--peer=PEER`:: ++ The address of the peer that terminates the remote end of this tunnel. ++ + ++ If left empty, connections from any IP address will be accepted. ++ ++`--local-address=LOCAL-ADDRESS`:: ++ The local IP address the tunnel originates from. ++ + ++ This is optional and if unset a useful default will be used. ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-zone-ip-tunnel.xml b/man/network-zone-ip-tunnel.xml +deleted file mode 100644 +index a1cc257..0000000 +--- a/man/network-zone-ip-tunnel.xml ++++ /dev/null +@@ -1,121 +0,0 @@ +- +- +- +- +- +- network-zone-ip-tunnel +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-ip-tunnel +- 8 +- +- +- +- network-zone-ip-tunnel +- Network Configuration Control Program +- +- +- +- +- network zone new ZONE ip-tunnel ... +- +- +- +- network zone ZONE edit ... +- +- +- +- +- Description +- +- +- The ip-tunnel hook is used to create IP tunnels that use protocols +- like GRE to encapsulate IP packets. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- Sets the protocol that is being used to encapsulate +- IP packets. +- Currently only gre is supported. +- +- +- +- +- +- +- +- +- +- +- +- The address of the peer that terminates the remote +- end of this tunnel. +- +- +- +- If left empty, connections from any IP address will +- be accepted. +- +- +- +- +- +- +- +- +- +- +- +- The local IP address the tunnel originates from. +- +- +- +- This is optional and if unset a useful default will be used. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0088-man-Convert-network-zone-modem-8-to-asciidoc.patch b/network/patches/0088-man-Convert-network-zone-modem-8-to-asciidoc.patch new file mode 100644 index 000000000..d140ce3f8 --- /dev/null +++ b/network/patches/0088-man-Convert-network-zone-modem-8-to-asciidoc.patch @@ -0,0 +1,329 @@ +From 23eec7d08e289749759927bcf4c2387cbfcbdce2 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 17:34:10 +0200 +Subject: [PATCH 088/304] man: Convert network-zone-modem(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-modem.txt | 66 +++++++++++ + man/network-zone-modem.xml | 235 ------------------------------------- + 2 files changed, 66 insertions(+), 235 deletions(-) + create mode 100644 man/network-zone-modem.txt + delete mode 100644 man/network-zone-modem.xml + +diff --git a/man/network-zone-modem.txt b/man/network-zone-modem.txt +new file mode 100644 +index 0000000..6b09622 +--- /dev/null ++++ b/man/network-zone-modem.txt +@@ -0,0 +1,66 @@ ++= network-zone-modem(8) ++Michael Tremer ++ ++== NAME ++network-zone-modem - Configure serial modems ++ ++== SYNOPSIS ++[verse] ++`network zone new ZONE modem ...` ++ ++== DESCRIPTION ++The modem hook uses a serial interface to establish a PPP session to an Internet ++Service Provider. This method is used by 56k modems and mobile networks like ++LTE, GSM and 3G. ++ ++== OPTIONS ++The following options are understood: ++ ++`--device=DEVICE`:: ++ Sets the serial device that is used to connect. Example: /dev/ttyUSB0 ++ ++`--monitor-device=DEVICE`:: ++ The optional monitor device is used to collect status information like ++ signal strength and link quality while the connection is established. ++ ++`--imsi=IMSI`:: ++ Set the IMSI of the SIM card inside the wireless modem to identify it when ++ it is plugged in at runtime. ++ ++`--pin=PIN`:: ++ The PIN number of the SIM card. ++ This will be used to unlock the SIM card when it is locked. ++ ++`--apn=APN`:: ++ Sets the Access Point Name (APN) that the modem connects to. ++ ++`--phone-number=PHONE-NUMBER`:: ++ Sets the phone number that is dialled by the modem when the connection is ++ to be established. ++ ++`--username=USERNAME`:: ++ Sets the username for authentication. ++ ++`--password=PASSWORD`:: ++ Sets the password for authentication. ++ + ++ Use the `--auth=` option to transmit it in a secure manner to the provider. ++ ++`--baudrate=921600`:: ++ The baudrate for the serial link to the modem. ++ ++`--mtu=N`:: ++ Sets the default MTU of the PPP connection. ++ ++`--auth=[chap|pap]`:: ++ Define the authentication method that is used to authenticate against your ++ provider. The default is to use the provider's preference. ++ ++ * _Challange-Handshake Authentication Protocol_ (`chap`) is the preferred, ++ secure method. ++ * _Password Authentication Protocol_ (`pap`) sends the plaintext password ++ to the authentication server which is the reason why it should be avoided. ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-zone-modem.xml b/man/network-zone-modem.xml +deleted file mode 100644 +index 97a1d35..0000000 +--- a/man/network-zone-modem.xml ++++ /dev/null +@@ -1,235 +0,0 @@ +- +- +- +- +- +- network-zone-modem +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-modem +- 8 +- +- +- +- network-zone-modem +- Network Configuration Control Program +- +- +- +- +- network zone new ZONE modem ... +- +- +- +- +- Description +- +- +- The modem hook uses a serial interface to establish a PPP session to an +- Internet Service Provider. This method is used by 56k modems and mobile +- networks like LTE, GSM and 3G. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- Sets the serial device that is used to connect. +- +- +- Example: /dev/ttyUSB0 +- +- +- +- +- +- +- +- +- +- +- +- The optional monitor device is used to collect status +- information like signal strength and link quality while +- the connection is established. +- +- +- +- +- +- +- +- +- +- +- +- Set the IMSI of the SIM card inside the wireless modem +- to identify it when it is plugged in at runtime. +- +- +- +- +- +- +- +- +- +- +- +- The PIN number of the SIM card. +- +- +- This will be used to unlock the SIM card when it +- is locked. +- +- +- +- +- +- +- +- +- +- +- +- Sets the Access Point Name (APN) +- that the modem connects to. +- +- +- +- +- +- +- +- +- +- +- +- Sets the phone number that is dialed by the modem when +- the connection is to be established. +- +- +- +- +- +- +- +- +- +- +- +- Sets the username for authentication. +- +- +- +- +- +- +- +- +- +- +- +- Sets the password for authentication. +- +- +- Use the option to transmit it +- in a secure manner to the provider. +- +- +- +- +- +- +- +- +- +- +- +- The baudrate for the serial link to the modem. +- +- +- +- +- +- +- +- +- +- +- +- Sets the default MTU of the PPP connection. +- +- +- +- +- +- +- +- +- +- +- +- Define the authentication method that is used to +- authenticate against your provider. +- The default is to use the provider's preference. +- +- +- +- +- Challange-Handshake Authentication Protocol +- (chap) is the preferred secure method. +- +- +- +- +- Password Authentication Protocol +- (pap) sends the plaintext password to the authentication +- server which is the reason why it should be avoided to use PAP. +- +- +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0089-man-Convert-network-zone-pppoe-8-to-asciidoc.patch b/network/patches/0089-man-Convert-network-zone-pppoe-8-to-asciidoc.patch new file mode 100644 index 000000000..191195159 --- /dev/null +++ b/network/patches/0089-man-Convert-network-zone-pppoe-8-to-asciidoc.patch @@ -0,0 +1,266 @@ +From d4f0a25cd61fe6a7d0cb711e269e9b75925edf23 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 17:42:10 +0200 +Subject: [PATCH 089/304] man: Convert network-zone-pppoe(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-pppoe.txt | 52 +++++++++++ + man/network-zone-pppoe.xml | 186 ------------------------------------- + 2 files changed, 52 insertions(+), 186 deletions(-) + create mode 100644 man/network-zone-pppoe.txt + delete mode 100644 man/network-zone-pppoe.xml + +diff --git a/man/network-zone-pppoe.txt b/man/network-zone-pppoe.txt +new file mode 100644 +index 0000000..93b55f2 +--- /dev/null ++++ b/man/network-zone-pppoe.txt +@@ -0,0 +1,52 @@ ++= network-zone-pppoe(8) ++Michael Tremer ++ ++== NAME ++network-zone-pppoe - PPP over Ethernet ++ ++== SYNOPSIS ++[verse] ++`network zone new ZONE pppoe ...` ++ ++== DESCRIPTION ++The `pppoe` hook creates a PPPoE connection to your ISP. ++ ++== OPTIONS ++The following options are understood: ++ ++`--username=USERNAME`:: ++ Sets the username for authentication. ++ ++`--password=PASSWORD`:: ++ Sets the password for authentication. ++ + ++ Use the `--auth=` option to transmit it in a secure manner to the provider. ++ ++`--mtu=N`:: ++ Sets the default MTU of the PPP connection. ++ ++`--auth=[chap|pap]`:: ++ Define the authentication method that is used to authenticate against your ++ provider. The default is to use the provider's preference. ++ ++ * _Challange-Handshake Authentication Protocol_ (`chap`) is the preferred, ++ secure method. ++ * _Password Authentication Protocol_ (`pap`) sends the plaintext password ++ to the authentication server which is the reason why it should be avoided. ++ ++`--access-concentrator=STRING`:: ++ By this option, you may define the name of the access concentrator. ++ ++`--service-name=STRING`:: ++ By this option, you may define the service name. ++ ++`--ipv6=[on|off]`:: ++ By this option, you may enable or disable IPv6. ++ ++`--prefix-delegation=[on|off]`:: ++ By this option, you may enable or disable the delegation through your ++ provider of one IPv6 prefix to your system. ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-zone-pppoe.xml b/man/network-zone-pppoe.xml +deleted file mode 100644 +index 36c4d0e..0000000 +--- a/man/network-zone-pppoe.xml ++++ /dev/null +@@ -1,186 +0,0 @@ +- +- +- +- +- +- network-zone-pppoe +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-pppoe +- 8 +- +- +- +- network-zone-pppoe +- Network Configuration Control Program +- +- +- +- +- network zone new ZONE pppoe ... +- +- +- +- +- Description +- +- +- The pppoe hook creates a PPPoE connection to your ISP. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- +- Sets the username for authentication. +- +- +- +- +- +- +- +- +- +- +- +- Sets the password for authentication. +- +- +- Use the option to transmit it +- in a secure manner to the provider. +- +- +- +- +- +- +- +- +- +- +- +- Sets the default MTU of the PPP connection. +- +- +- +- +- +- +- +- +- +- +- +- Define the authentication method that is used to +- authenticate against your provider. +- The default is to use the provider's preference. +- +- +- +- +- Challange-Handshake Authentication Protocol +- (chap) is the preferred secure method. +- +- +- +- +- Password Authentication Protocol +- (pap) sends the plaintext password to the authentication +- server which is the reason why it should be avoided to use PAP. +- +- +- +- +- +- +- +- +- +- +- +- +- +- By this option, you may define the name of the access concentrator. +- +- +- +- +- +- +- +- +- +- +- +- By this option, you may define the service name. +- +- +- +- +- +- +- +- +- +- +- +- By this option, you may enable or disable IPv6 +- +- +- +- +- +- +- +- +- +- +- By this option, you may enable or disable the delegation through your provider of one IPv6 prefix to your system. +- +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0090-man-Convert-network-zone-wireless-8-to-asciidoc.patch b/network/patches/0090-man-Convert-network-zone-wireless-8-to-asciidoc.patch new file mode 100644 index 000000000..e5c9cf7ff --- /dev/null +++ b/network/patches/0090-man-Convert-network-zone-wireless-8-to-asciidoc.patch @@ -0,0 +1,167 @@ +From bc2b9c75cd5b73e1c2de5463fc1c0bc94b6dad93 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 17:53:20 +0200 +Subject: [PATCH 090/304] man: Convert network-zone-wireless(8) to asciidoc + +Signed-off-by: Michael Tremer +--- + man/network-zone-wireless.txt | 32 ++++++++++ + man/network-zone-wireless.xml | 107 ---------------------------------- + 2 files changed, 32 insertions(+), 107 deletions(-) + create mode 100644 man/network-zone-wireless.txt + delete mode 100644 man/network-zone-wireless.xml + +diff --git a/man/network-zone-wireless.txt b/man/network-zone-wireless.txt +new file mode 100644 +index 0000000..368ac2a +--- /dev/null ++++ b/man/network-zone-wireless.txt +@@ -0,0 +1,32 @@ ++= network-zone-wireless(8) ++Michael Tremer ++ ++== NAME ++network-zone-wireless - Wireless Networks ++ ++== SYNOPSIS ++[verse] ++`network zone new ZONE wireless ...` ++ ++== DESCRIPTION ++The wireless hook uses a WiFi interface and connects to a wireless access point ++in station mode. ++ ++Configuration and credentials for any wireless networks to connect to can be ++configured by using link:network-wireless-network[8]. ++ ++== OPTIONS ++The following options are understood: ++ ++`--phy=PHY`:: ++ Takes the MAC address or name of the physical layer that is used to create ++ a virtual wireless interface. ++ ++`--address=ADDRESS`:: ++ Define a MAC address that is used for the virtual wireless device. This ++ parameter is optional and a random MAC address will be generated when ++ omitted. ++ ++== SEE ALSO ++link:network[8], ++link:network-zone[8] +diff --git a/man/network-zone-wireless.xml b/man/network-zone-wireless.xml +deleted file mode 100644 +index 0931245..0000000 +--- a/man/network-zone-wireless.xml ++++ /dev/null +@@ -1,107 +0,0 @@ +- +- +- +- +- +- network-zone-wireless +- network +- +- +- +- Developer +- Michael +- Tremer +- michael.tremer@ipfire.org +- +- +- +- +- +- network-zone-wireless +- 8 +- +- +- +- network-zone-wireless +- Network Configuration Control Program +- +- +- +- +- network zone new ZONE wireless ... +- +- +- +- +- Description +- +- +- The wireless hook uses a WiFi interface and connects to a +- wireless access point in station mode. +- +- +- +- Configuration and credentials for any wireless networks to +- connect to can be configured by using the +- network wireless network command. +- +- See +- network-wireless-networks +- 8, +- for details. +- +- +- +- +- Options +- +- +- The following options are understood: +- +- +- +- +- +- +- +- +- +- +- Takes the MAC address or name of the physical layer +- that is used to create a virtual wireless interface. +- +- +- +- +- +- +- +- +- +- +- +- Define a MAC address that is used for the virtual +- wireless device. This parameter is optional and +- a random MAC address will be generated when omitted. +- +- +- +- +- +- +- +- See Also +- +- +- +- network +- 8 +- , +- +- network-zone +- 8 +- +- +- +- +-- +2.39.2 + diff --git a/network/patches/0091-man-Cleanup-XML-files.patch b/network/patches/0091-man-Cleanup-XML-files.patch new file mode 100644 index 000000000..3cda095e2 --- /dev/null +++ b/network/patches/0091-man-Cleanup-XML-files.patch @@ -0,0 +1,43 @@ +From d746901bf5d4b4eb7591d1e009fad2960647e034 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 20:01:00 +0200 +Subject: [PATCH 091/304] man: Cleanup XML files + +Signed-off-by: Michael Tremer +--- + Makefile.am | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 26f2e9c..d79b0f2 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -475,7 +475,8 @@ MANPAGES = \ + man/network-zone-wireless.8 + + MANPAGES_TXT = $(patsubst %.8,%.txt,$(MANPAGES)) +-MANPAGES_HTML = $(patsubst %.txt,%.html,$(MANPAGES)) ++MANPAGES_HTML = $(patsubst %.txt,%.html,$(MANPAGES_TXT)) ++MANPAGES_XML = $(patsubst %.txt,%.xml,$(MANPAGES_TXT)) + + .PHONY: man + man: $(MANPAGES) $(MANPAGES_HTML) +@@ -484,11 +485,13 @@ man_MANS = \ + $(MANPAGES) + + noinst_DATA += \ +- $(MANPAGES_HTML) ++ $(MANPAGES_HTML) \ ++ $(MANPAGES_XML) + + CLEANFILES += \ + $(man_MANS) \ +- $(MANPAGES_HTML) ++ $(MANPAGES_HTML) \ ++ $(MANPAGES_XML) + + EXTRA_DIST += \ + $(MANPAGES_TXT) +-- +2.39.2 + diff --git a/network/patches/0092-man-Make-distcheck-happy.patch b/network/patches/0092-man-Make-distcheck-happy.patch new file mode 100644 index 000000000..18d763532 --- /dev/null +++ b/network/patches/0092-man-Make-distcheck-happy.patch @@ -0,0 +1,54 @@ +From 5d881996d1a5cf6211ae1fa0d4c4cd6fe6867f79 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 20:08:00 +0200 +Subject: [PATCH 092/304] man: Make distcheck happy + +Signed-off-by: Michael Tremer +--- + Makefile.am | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index d79b0f2..0257b02 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -494,6 +494,7 @@ CLEANFILES += \ + $(MANPAGES_XML) + + EXTRA_DIST += \ ++ man/asciidoc.conf \ + $(MANPAGES_TXT) + + XSLTPROC_FLAGS = \ +@@ -505,20 +506,23 @@ XSLTPROC_FLAGS = \ + --stringparam man.copyright.section.enabled 1 + + XSLTPROC_COMMAND_MAN = \ +- $(AM_V_XSLT)$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) \ ++ $(AM_V_XSLT)$(MKDIR_P) $(dir $@) && \ ++ $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + + man/%.xml: man/%.txt man/asciidoc.conf +- $(AM_V_ASCIIDOC)$(ASCIIDOC) \ +- -f man/asciidoc.conf \ ++ $(AM_V_ASCIIDOC)$(MKDIR_P) $(dir $@) && \ ++ $(ASCIIDOC) \ ++ -f $(abs_srcdir)/man/asciidoc.conf \ + -d manpage -b docbook -o $@ $< + + man/%.8: man/%.xml + $(XSLTPROC_COMMAND_MAN) + + man/%.html: man/%.txt man/asciidoc.conf +- $(AM_V_ASCIIDOC)$(ASCIIDOC) \ +- -f man/asciidoc.conf \ ++ $(AM_V_ASCIIDOC)$(MKDIR_P) $(dir $@) && \ ++ $(ASCIIDOC) \ ++ -f $(abs_srcdir)/man/asciidoc.conf \ + -b html5 -a icons -a theme=flask -o $@ $< + + # ------------------------------------------------------------------------------ +-- +2.39.2 + diff --git a/network/patches/0093-man-Include-include-files-in-tarball.patch b/network/patches/0093-man-Include-include-files-in-tarball.patch new file mode 100644 index 000000000..7270d85bc --- /dev/null +++ b/network/patches/0093-man-Include-include-files-in-tarball.patch @@ -0,0 +1,28 @@ +From ff43523863b7ad7f50f5dfd4fdf80251ef01fa51 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 20:14:34 +0200 +Subject: [PATCH 093/304] man: Include include files in tarball + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 0257b02..6b77f0a 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -474,6 +474,10 @@ MANPAGES = \ + man/network-zone-pppoe.8 \ + man/network-zone-wireless.8 + ++EXTRA_DIST += \ ++ man/include-color.txt \ ++ man/include-description.txt ++ + MANPAGES_TXT = $(patsubst %.8,%.txt,$(MANPAGES)) + MANPAGES_HTML = $(patsubst %.txt,%.html,$(MANPAGES_TXT)) + MANPAGES_XML = $(patsubst %.txt,%.xml,$(MANPAGES_TXT)) +-- +2.39.2 + diff --git a/network/patches/0094-man-network-route-static-Fix-name.patch b/network/patches/0094-man-network-route-static-Fix-name.patch new file mode 100644 index 000000000..c13af1a79 --- /dev/null +++ b/network/patches/0094-man-network-route-static-Fix-name.patch @@ -0,0 +1,26 @@ +From 71bdead694bdae2e40e8a9f99403b4ec2db77914 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 31 Mar 2019 20:17:09 +0200 +Subject: [PATCH 094/304] man: network-route-static: Fix name + +Signed-off-by: Michael Tremer +--- + man/network-route-static.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/network-route-static.txt b/man/network-route-static.txt +index d4774b2..c6c3fea 100644 +--- a/man/network-route-static.txt ++++ b/man/network-route-static.txt +@@ -2,7 +2,7 @@ + Michael Tremer + + == NAME +-network-route - Manage Static Routing ++network-route-static - Manage Static Routing + + == SYNOPSIS + [verse] +-- +2.39.2 + diff --git a/network/patches/0095-Makefile-Add-target-to-upload-HTML-man-pages.patch b/network/patches/0095-Makefile-Add-target-to-upload-HTML-man-pages.patch new file mode 100644 index 000000000..b6f262fdb --- /dev/null +++ b/network/patches/0095-Makefile-Add-target-to-upload-HTML-man-pages.patch @@ -0,0 +1,28 @@ +From 2d2e96269516032b3bc4f2222067f6b82398a70a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Apr 2019 12:31:53 +0200 +Subject: [PATCH 095/304] Makefile: Add target to upload HTML man pages + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 6b77f0a..955f2b7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -529,6 +529,10 @@ man/%.html: man/%.txt man/asciidoc.conf + -f $(abs_srcdir)/man/asciidoc.conf \ + -b html5 -a icons -a theme=flask -o $@ $< + ++.PHONY: upload-man ++upload-man: $(MANPAGES_HTML) ++ rsync -avHz --delete --progress $(MANPAGES_HTML) ms@people.ipfire.org:/pub/man-pages/$(PACKAGE_NAME)/ ++ + # ------------------------------------------------------------------------------ + + substitutions = \ +-- +2.39.2 + diff --git a/network/patches/0096-man-Do-not-generate-HTML-documentation-in-normal-bui.patch b/network/patches/0096-man-Do-not-generate-HTML-documentation-in-normal-bui.patch new file mode 100644 index 000000000..b1c34b320 --- /dev/null +++ b/network/patches/0096-man-Do-not-generate-HTML-documentation-in-normal-bui.patch @@ -0,0 +1,29 @@ +From 95556ed6aa03a160df0ed6e929389c3d7283b87b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Apr 2019 12:45:55 +0200 +Subject: [PATCH 096/304] man: Do not generate HTML documentation in normal + build + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 955f2b7..4c26a9d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -488,10 +488,6 @@ man: $(MANPAGES) $(MANPAGES_HTML) + man_MANS = \ + $(MANPAGES) + +-noinst_DATA += \ +- $(MANPAGES_HTML) \ +- $(MANPAGES_XML) +- + CLEANFILES += \ + $(man_MANS) \ + $(MANPAGES_HTML) \ +-- +2.39.2 + diff --git a/network/patches/0097-man-Fix-authorship-warnings.patch b/network/patches/0097-man-Fix-authorship-warnings.patch new file mode 100644 index 000000000..317a63569 --- /dev/null +++ b/network/patches/0097-man-Fix-authorship-warnings.patch @@ -0,0 +1,205 @@ +From 6b1e747472ac60192146fc5ddba12b4a5d021194 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Apr 2019 12:47:02 +0200 +Subject: [PATCH 097/304] man: Fix authorship warnings + +Signed-off-by: Michael Tremer +--- + man/network-route-static.txt | 4 +++- + man/network-settings.txt | 1 - + man/network-vpn-security-policies.txt | 4 +++- + man/network-zone-bridge.txt | 4 +++- + man/network-zone-config-pppoe-server.txt | 3 +++ + man/network-zone-ip-tunnel.txt | 4 +++- + man/network-zone-modem.txt | 4 +++- + man/network-zone-pppoe.txt | 4 +++- + man/network-zone-wireless.txt | 4 +++- + man/network-zone.txt | 4 +++- + 10 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/man/network-route-static.txt b/man/network-route-static.txt +index c6c3fea..4ba97eb 100644 +--- a/man/network-route-static.txt ++++ b/man/network-route-static.txt +@@ -1,5 +1,4 @@ + = network-route-static(8) +-Michael Tremer + + == NAME + network-route-static - Manage Static Routing +@@ -63,6 +62,9 @@ The following commands are understood: + Packets matching this kind of route are silently discarded. + There will be no ICMP message sent to the source and no packet be forwarded. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-route[8], +diff --git a/man/network-settings.txt b/man/network-settings.txt +index e77f038..a1c1ae3 100644 +--- a/man/network-settings.txt ++++ b/man/network-settings.txt +@@ -1,5 +1,4 @@ + = network-settings(8) +-Michael Tremer + + == NAME + network-settings - Change global network settings +diff --git a/man/network-vpn-security-policies.txt b/man/network-vpn-security-policies.txt +index f9dc91a..3c843d7 100644 +--- a/man/network-vpn-security-policies.txt ++++ b/man/network-vpn-security-policies.txt +@@ -1,5 +1,4 @@ + = network-vpn-security-policies(8) +-Michael Tremer + + == NAME + network-vpn-security-policies - Configure VPN Security Policies +@@ -106,6 +105,9 @@ They are intended to provide good defaults for various situations. + + System policies cannot be deleted. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-vpn[8] +diff --git a/man/network-zone-bridge.txt b/man/network-zone-bridge.txt +index 2e4f839..46c78a6 100644 +--- a/man/network-zone-bridge.txt ++++ b/man/network-zone-bridge.txt +@@ -1,5 +1,4 @@ + = network-zone-bridge(8) +-Michael Tremer + + == NAME + network-zone-bridge - Manage network zones +@@ -50,6 +49,9 @@ Spanning Tree Protocol (802.1D) configuration options: + The STP priority sets the ranking of this network device within the network. + The bridge with the best rank (0 is best) will become the root bridge. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-zone-config-pppoe-server.txt b/man/network-zone-config-pppoe-server.txt +index 72dff8e..7d83bd1 100644 +--- a/man/network-zone-config-pppoe-server.txt ++++ b/man/network-zone-config-pppoe-server.txt +@@ -44,6 +44,9 @@ This command creates a PPPoE server that will assign an IP address from the + + network zone net0 config create pppoe-server --subnet=192.168.0.0/16 + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8], +diff --git a/man/network-zone-ip-tunnel.txt b/man/network-zone-ip-tunnel.txt +index cb30731..8e2f30a 100644 +--- a/man/network-zone-ip-tunnel.txt ++++ b/man/network-zone-ip-tunnel.txt +@@ -1,5 +1,4 @@ + = network-zone-ip-tunnel(8) +-Michael Tremer + + == NAME + network-zone-ip-tunnel - Manage IP Tunnels +@@ -30,6 +29,9 @@ The following options are understood: + + + This is optional and if unset a useful default will be used. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-zone-modem.txt b/man/network-zone-modem.txt +index 6b09622..082bb21 100644 +--- a/man/network-zone-modem.txt ++++ b/man/network-zone-modem.txt +@@ -1,5 +1,4 @@ + = network-zone-modem(8) +-Michael Tremer + + == NAME + network-zone-modem - Configure serial modems +@@ -61,6 +60,9 @@ The following options are understood: + * _Password Authentication Protocol_ (`pap`) sends the plaintext password + to the authentication server which is the reason why it should be avoided. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-zone-pppoe.txt b/man/network-zone-pppoe.txt +index 93b55f2..1a1c4f3 100644 +--- a/man/network-zone-pppoe.txt ++++ b/man/network-zone-pppoe.txt +@@ -1,5 +1,4 @@ + = network-zone-pppoe(8) +-Michael Tremer + + == NAME + network-zone-pppoe - PPP over Ethernet +@@ -47,6 +46,9 @@ The following options are understood: + By this option, you may enable or disable the delegation through your + provider of one IPv6 prefix to your system. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-zone-wireless.txt b/man/network-zone-wireless.txt +index 368ac2a..531f8ff 100644 +--- a/man/network-zone-wireless.txt ++++ b/man/network-zone-wireless.txt +@@ -1,5 +1,4 @@ + = network-zone-wireless(8) +-Michael Tremer + + == NAME + network-zone-wireless - Wireless Networks +@@ -27,6 +26,9 @@ The following options are understood: + parameter is optional and a random MAC address will be generated when + omitted. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-zone.txt b/man/network-zone.txt +index 88a1988..2c2c6f0 100644 +--- a/man/network-zone.txt ++++ b/man/network-zone.txt +@@ -1,5 +1,4 @@ + = network-zone(8) +-Michael Tremer + + == NAME + network-zone - Manage network zones +@@ -69,5 +68,8 @@ include::include-description.txt[] + The command will shut down the zone if it is up and start it again with + the new name. If the zone is not up it won't be started. + ++== AUTHORS ++Michael Tremer ++ + == SEE ALSO + link:network[8] +-- +2.39.2 + diff --git a/network/patches/0098-man-Make-syntax-format-more-similar-across-files.patch b/network/patches/0098-man-Make-syntax-format-more-similar-across-files.patch new file mode 100644 index 000000000..5752c844c --- /dev/null +++ b/network/patches/0098-man-Make-syntax-format-more-similar-across-files.patch @@ -0,0 +1,583 @@ +From 39cfece88a2978f946e1713fbf1e2be3faf124d6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 1 Apr 2019 19:49:01 +0200 +Subject: [PATCH 098/304] man: Make syntax format more similar across files + +Signed-off-by: Michael Tremer +--- + man/firewall-settings.txt | 29 +++++------ + man/network-device.txt | 37 ++++++-------- + man/network-dhcp.txt | 35 ++++++-------- + man/network-dns-server.txt | 50 ++++++++----------- + man/network-performance-tuning.txt | 17 +++---- + man/network-port.txt | 77 ++++++++++++++---------------- + man/network-quick-start.txt | 15 ++---- + man/network-route-static.txt | 18 +++---- + 8 files changed, 116 insertions(+), 162 deletions(-) + +diff --git a/man/firewall-settings.txt b/man/firewall-settings.txt +index 20038e3..81c9bd9 100644 +--- a/man/firewall-settings.txt ++++ b/man/firewall-settings.txt +@@ -1,30 +1,25 @@ +-firewall-settings(8) +-==================== ++= firewall-settings(8) + +-NAME +----- ++== NAME + firewall-settings - Global firewall settings + +-SYNOPSIS +--------- ++== SYNOPSIS + [verse] +-'firewall settings' +-'firewall settings' KEY=VALUE ... ++`firewall settings` ++`firewall settings` KEY=VALUE ... + +-DESCRIPTION +------------ ++== DESCRIPTION + This command is used to set global firewall settings. + Please have a look at the individual man pages for more options. + +-COMMANDS +--------- ++== COMMANDS + If no argument is given, the configuration will be dumped to the console. + + You may set a new value by adding the variable name and the new value to + the command line. + +-SETTINGS +--------- ++== SETTINGS ++ + === CONNTRACK_MAX_CONNECTIONS = 16384 + Limits the max. number of simultaneous connections. + +@@ -88,10 +83,8 @@ Some routers on the Internet still do not support ECN properly. + When this setting is disabled, ECN is only advertised + when asked for. + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:firewall[8] +diff --git a/man/network-device.txt b/man/network-device.txt +index 4f1c1b0..d70536e 100644 +--- a/man/network-device.txt ++++ b/man/network-device.txt +@@ -1,61 +1,54 @@ +-network-device(8) +-================= ++= network-device(8) + +-NAME +----- ++== NAME + network-device - Controls network devices + +-SYNOPSIS +--------- ++== SYNOPSIS + [verse] +-'network device' [] ... ++`network device` COMMAND ... + +-DESCRIPTION +------------ +-The 'network device' command shows low-level status information ++== DESCRIPTION ++The `network device` command shows low-level status information + of network devices and other things. + +-COMMANDS +--------- ++== COMMANDS + The following commands are understood: + +-'list':: ++`list`:: + This command shows a list of all device that are currently present + on this system. This includes PHYs and serial devices as well. + +-'DEVICE discover':: ++`DEVICE discover`:: + Runs a discovery for many hooks on the given device. + + This will check if the hook can find for example a DHCP server or + DSLAM and thus predict for what the device should be used. + +-'DEVICE identify':: ++`DEVICE identify`:: + This command only works for Ethernet adapters and will make those + that support this feature flash for a few seconds. + + It is handy to find the right device to put the cable in. + +-'DEVICE monitor':: ++`DEVICE monitor`:: + This command creates a monitor interface for wireless modules. + + An instance of link:tcpdump[8] will be started and show all + frames that are sent or received on the 802.11 layer (layer 2). + +-'DEVICE status':: ++`DEVICE status`:: + This will show you very detailed information about the given device. + +-'DEVICE unlock':: ++`DEVICE unlock`:: + This command will unlock the SIM card in a modem. + Only serial devices are supported which are the most 4G or 3G modems. + + For the PIN or PUK code, the user will be prompted. + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8] + link:network-port[8] + link:network-zone[8] +diff --git a/man/network-dhcp.txt b/man/network-dhcp.txt +index bcb768e..11e5fb4 100644 +--- a/man/network-dhcp.txt ++++ b/man/network-dhcp.txt +@@ -1,44 +1,37 @@ +-network-dhcp(8) +-=============== ++= network-dhcp(8) + +-NAME +----- ++== NAME + network-dhcp - Controls the DHCP Server + +-SYNOPSIS +--------- ++== SYNOPSIS + [verse] +-'network dhcpv6' ... +-'network dhcpv4' ... ++`network dhcpv6` COMMAND ... ++`network dhcpv4` COMMAND ... + +-DESCRIPTION +------------ ++== DESCRIPTION + With help of the DHCP commands it is possible to configure DHCP + servers for IPv6 and IPv4. + +-COMMANDS +--------- ++== COMMANDS + The following commands are understood: + +-'start':: ++`start`:: + Starts the DHCP server. + +-'stop':: ++`stop`:: + Stops the DHCP server. + +-'restart':: ++`restart`:: + Restarts the DHCP server. + +-'reload':: ++`reload`:: + Reload the DHCP server configuration. + +-'subnet ...':: ++`subnet ...`:: + TODO + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8] +diff --git a/man/network-dns-server.txt b/man/network-dns-server.txt +index bd01ca7..f5019ce 100644 +--- a/man/network-dns-server.txt ++++ b/man/network-dns-server.txt +@@ -1,75 +1,67 @@ +-network-dns-server(8) +-===================== ++= network-dns-server(8) + +-NAME +----- ++== NAME + network-dns-server - Controls the DNS settings + +-SYNOPSIS +--------- ++== SYNOPSIS + [verse] +-'network dns-server' add SERVER [PRIORITY] +-'network dns-server' remove SERVER +-'network dns-server' list +-'network dns-server' update ++`network dns-server add` SERVER [PRIORITY] ++`network dns-server remove` SERVER ++`network dns-server list` ++`network dns-server update` + +-DESCRIPTION +------------ ++== DESCRIPTION + With this command, you will be able to configure the local DNS + configuration. + + You may add and remove DNS servers as well as view the settings. + +-COMMANDS +--------- ++== COMMANDS + The following commands are understood: + +-'add' SERVER [PRIORITY]:: ++`add SERVER [PRIORITY]`:: + A new DNS server may be added to the list by the + 'add' command. + A priority that will rank the server my optionally be given. +- ++ + + NOTE: SERVER must be a valid IP address and PRIORITY + must be a positive number. + The smaller this number, the higher is is the rank of + the server. + +-'remove' SERVER:: ++`remove SERVER`:: + The given server will be removed from the list of DNS servers. + +-'list':: ++`list`:: + Shows a list of all servers that are currently in use. + +-'update':: ++`update`:: + This command will re-create the system's configuration + files. It should not be required to use this command + very often. + +-SETTINGS +--------- ++== SETTINGS + The following settings may be set using link:network-settings[8]: + +-'DNS_USE_LOCAL_RESOLVER = [true|false]':: ++`DNS_USE_LOCAL_RESOLVER = [true|false]`:: + This option defines whether the local DNS resolver should + be used or not. +- ++ + + Basically, the option adds localhost to the list of nameservers + in link:resolv.conf[5]. + +-'DNS_SEARCH_DOMAINS =':: ++`DNS_SEARCH_DOMAINS =`:: + This setting configures the search domains for DNS queries + made by the local system. + +-'DNS_RANDOMIZE = [true|false]':: ++`DNS_RANDOMIZE = [true|false]`:: + This option will break the DNS server ranks and will query + them in a random order which is useful to load-balance + multiple DNS servers. + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8], + link:network-settings[8] +diff --git a/man/network-performance-tuning.txt b/man/network-performance-tuning.txt +index 763ee21..4672bbc 100644 +--- a/man/network-performance-tuning.txt ++++ b/man/network-performance-tuning.txt +@@ -1,12 +1,9 @@ +-network-performance-tuning(8) +-============================= ++= network-performance-tuning(8) + +-NAME +----- ++== NAME + network-performance-tuning - Performance Tuning for Networking + +-DESCRIPTION +------------ ++== DESCRIPTION + This page contains a summary of some performance tuning techniques + that this system is using. + +@@ -22,12 +19,10 @@ reducing network latency and quite possibly increasing throughput. + The algorithm is trying to balance all network controllers across + all processors. + +-See /proc/interrups for the distribution of interrupts. ++See /proc/interrupts for the distribution of interrupts. + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8] +diff --git a/man/network-port.txt b/man/network-port.txt +index 0c26f33..54cd58c 100644 +--- a/man/network-port.txt ++++ b/man/network-port.txt +@@ -1,29 +1,25 @@ +-network-port(8) +-=============== ++= network-port(8) + +-NAME +----- ++== NAME + network-port - Controls Network Ports + +-SYNOPSIS +--------- ++== SYNOPSIS + [verse] +-'network port' new HOOK ... +-'network port' destroy PORT +-'network port' PORT color set +-'network port' PORT color reset +-'network port' PORT create +-'network port' PORT description edit +-'network port' PORT description show +-'network port' PORT down +-'network port' PORT edit ... +-'network port' PORT identify +-'network port' PORT remove +-'network port' PORT status +-'network port' PORT up +- +-DESCRIPTION +------------ ++`network port new HOOK ...` ++`network port destroy PORT` ++`network port PORT color set COLOR` ++`network port PORT color reset` ++`network port PORT create` ++`network port PORT description edit` ++`network port PORT description show` ++`network port PORT down` ++`network port PORT edit ...` ++`network port PORT identify` ++`network port PORT remove` ++`network port PORT status` ++`network port PORT up` ++ ++== DESCRIPTION + This command creates, deletes, changes and views the configuration + and status of ports. + +@@ -32,15 +28,14 @@ to an other network. It connects those and zones together. + The 'network device' command shows status information of network devices + and other things. + +-COMMANDS +--------- ++== COMMANDS + The following commands are understood: + +-'new' HOOK ...:: ++`new HOOK ...`:: + A new port may be created with this command. + HOOK must be a valid hook which may require more options. + +-'destroy' PORT:: ++`destroy PORT`:: + Destroys the port PORT. + The port is removed from any zones it is attached to and shut down. + +@@ -48,49 +43,47 @@ For all other commands, the name of the port needs to be passed first: + + include::include-color.txt[] + +-'create':: ++`create`:: + This will create devices for the existing port PORT. +- ++ + + This does not create a new port. It will just create the (possibly + virtual) interface this port (i.e. create an interface for a WiFi + module or a VLAN device). +- +- The interface is not brought up. Use the 'up' command to do that. ++ + ++ The interface is not brought up. Use the `up` command to do that. + + include::include-description.txt[] + +-'down':: ++`down`:: + Shuts down the port. + +-'edit':: ++`edit`:: + This command can be used to alter the configuration of a port. + Consult the documentation of the port hook to find out what is supported. + +-'identify':: ++`identify`:: + This command will make the port flash for a few seconds + so that you can identify the correct network adapters + in the system. +- ++ + + This is not supported by all network adapters. + +-'remove':: ++`remove`:: + This will remove an existing PORT. +- ++ + + This does not destroy the port. It inverses the operation performed + by the 'create' command. + +-'status':: ++`status`:: + This will show some detailed information about the status + of the specified port. + +-'up':: ++`up`:: + Brings up the port. It has to be created first. + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8], + link:network-zone[8] +diff --git a/man/network-quick-start.txt b/man/network-quick-start.txt +index 02ebfe0..1ab5866 100644 +--- a/man/network-quick-start.txt ++++ b/man/network-quick-start.txt +@@ -1,12 +1,9 @@ +-network-quick-start(8) +-====================== ++= network-quick-start(8) + +-NAME +----- ++== NAME + network-quick-start - Quick Start Guide for Networking + +-DESCRIPTION +------------ ++== DESCRIPTION + The link:network[8] is a very powerful command that allows you to configure + the entire networking stack. + Unfortunately that makes it quite complicated to use as well. +@@ -80,12 +77,10 @@ The entire network can be restarted by running: + # network restart + ------------ + +-AUTHORS +-------- ++== AUTHORS + Michael Tremer + +-SEE ALSO +--------- ++== SEE ALSO + link:network[8], + link:network-device[8], + link:network-port[8], +diff --git a/man/network-route-static.txt b/man/network-route-static.txt +index 4ba97eb..43a1277 100644 +--- a/man/network-route-static.txt ++++ b/man/network-route-static.txt +@@ -5,10 +5,10 @@ network-route-static - Manage Static Routing + + == SYNOPSIS + [verse] +-'network route static' COMMAND ... +-'network route static add' NETWORK [--gateway=GATEWAY,--unreachable,--prohibit,--blackhole] [--mtu=MTU] +-'network route static remove' NETWORK +-'network route static list' [--protocol=ipv6|ipv4] ++`network route static COMMAND ...` ++`network route static add NETWORK [--gateway=GATEWAY,--unreachable,--prohibit,--blackhole] [--mtu=MTU]` ++`network route static remove NETWORK` ++`network route static list` [--protocol=ipv6|ipv4]` + + == DESCRIPTION + This command helps to manage routes. +@@ -20,14 +20,14 @@ The following commands are understood: + A new route may be added by the 'add' command. It is required to pass a + valid network prefix NETWORK, which can be either IPv6 or IPv4. + + +- For unicast routes, the '--gateway=GATEWAY' option must be passed, where ++ For unicast routes, the `--gateway=GATEWAY` option must be passed, where + GATEWAY is a valid IP address of the same protocol type as the network + prefix is. + + +- Use '--unreachable', '--prohibit', '--blackhole' can be used to create of ++ Use `--unreachable`, `--prohibit`, `--blackhole` can be used to create of + that type. See ROUTE TYPES below for more information about these options. + + +- The optional '--mtu=MTU' parameter defines the MTU along the path to the ++ The optional `--mtu=MTU` parameter defines the MTU along the path to the + destination and must be an integer number. This will show you very + detailed information about the given device. + +@@ -39,7 +39,7 @@ The following commands are understood: + 'list':: + Shows a list of all configured routes. + + +- Output can be filtered by passing --protocol=[ipv6|ipv4]. ++ Output can be filtered by passing `--protocol=[ipv6|ipv4]`. + + == ROUTE TYPES + +@@ -47,7 +47,7 @@ The following commands are understood: + 'unicast':: + A unicast route is the most common route in routing tables. It is a route to + a destination network address, which describes the path to the destination. +- Use the '--gateway=GATEWAY' option to create such a route. ++ Use the `--gateway=GATEWAY` option to create such a route. + + 'unreachable':: + When a route is determined and the routing decision process returns a +-- +2.39.2 + diff --git a/network/patches/0099-hooks-Add-overwritable-function-to-determine-the-por.patch b/network/patches/0099-hooks-Add-overwritable-function-to-determine-the-por.patch new file mode 100644 index 000000000..09b95df3c --- /dev/null +++ b/network/patches/0099-hooks-Add-overwritable-function-to-determine-the-por.patch @@ -0,0 +1,53 @@ +From d673165c5456e29013def29ed1fa9f202110665a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 11:50:13 +0200 +Subject: [PATCH 099/304] hooks: Add overwritable function to determine the + port name + +Signed-off-by: Michael Tremer +--- + src/header-port | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/header-port b/src/header-port +index d75fdd8..7d0b272 100644 +--- a/src/header-port ++++ b/src/header-port +@@ -68,6 +68,12 @@ hook_hotplug_rename_by_address() { + return ${EXIT_ERROR} + } + ++# Returns the suggested name of the port ++hook_find_port_name() { ++ assert isset HOOK_PORT_PATTERN ++ port_find_free "${HOOK_PORT_PATTERN}" ++} ++ + hook_default_new() { + local ${HOOK_SETTINGS[*]} + +@@ -78,14 +84,16 @@ hook_default_new() { + return ${EXIT_ERROR} + fi + +- assert isset HOOK_PORT_PATTERN +- +- local port=$(port_find_free ${HOOK_PORT_PATTERN}) ++ # Determine a name for this port ++ local port="$(hook_find_port_name)" + assert isset port + +- port_settings_write "${port}" ${HOOK_SETTINGS[*]} ++ # Save settings ++ if ! port_settings_write "${port}" ${HOOK_SETTINGS[*]}; then ++ return ${EXIT_ERROR} ++ fi + +- exit ${EXIT_OK} ++ return ${EXIT_OK} + } + + hook_new() { +-- +2.39.2 + diff --git a/network/patches/0100-vlan-Convert-hook-to-use-parse_cmdline-function.patch b/network/patches/0100-vlan-Convert-hook-to-use-parse_cmdline-function.patch new file mode 100644 index 000000000..3a6445824 --- /dev/null +++ b/network/patches/0100-vlan-Convert-hook-to-use-parse_cmdline-function.patch @@ -0,0 +1,76 @@ +From 96045e9c044a709407b40df4145011e335929a3e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 11:55:35 +0200 +Subject: [PATCH 100/304] vlan: Convert hook to use parse_cmdline function + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 42 ++++++++---------------------------------- + 1 file changed, 8 insertions(+), 34 deletions(-) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index f511986..69f5144 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -51,7 +51,14 @@ hook_check_settings() { + done + } + +-hook_new() { ++hook_find_port_name() { ++ assert isset PARENT_DEVICE ++ assert isset TAG ++ ++ print "${PARENT_DEVICE}${VLAN_PORT_INTERFIX}${TAG}" ++} ++ ++hook_parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in + --parent-device=*) +@@ -63,42 +70,9 @@ hook_new() { + --tag=*) + TAG=$(cli_get_val "${1}") + ;; +- *) +- warning "Unknown argument '${1}'" +- ;; +- esac +- shift +- done +- +- local port="${PARENT_DEVICE}${VLAN_PORT_INTERFIX}${TAG}" +- +- port_settings_write "${port}" +- +- exit ${EXIT_OK} +-} +- +-hook_edit() { +- local port=${1} +- assert isset port +- shift +- +- port_settings_read "${port}" +- +- while [ $# -gt 0 ]; do +- case "${1}" in +- --address=*) +- ADDRESS=$(cli_get_val "${1}") +- ;; +- *) +- warning "Unknown argument '${1}'" +- ;; + esac + shift + done +- +- port_settings_write "${port}" +- +- exit ${EXIT_OK} + } + + hook_create() { +-- +2.39.2 + diff --git a/network/patches/0101-vlan-Validate-and-always-set-MAC-address.patch b/network/patches/0101-vlan-Validate-and-always-set-MAC-address.patch new file mode 100644 index 000000000..75a5310ee --- /dev/null +++ b/network/patches/0101-vlan-Validate-and-always-set-MAC-address.patch @@ -0,0 +1,42 @@ +From abb655547c79f72b97451c02ba285b13c68e5a2a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:00:02 +0200 +Subject: [PATCH 101/304] vlan: Validate and always set MAC address + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 69f5144..0147e54 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -66,6 +66,12 @@ hook_parse_cmdline() { + ;; + --address=*) + ADDRESS=$(cli_get_val "${1}") ++ ++ # Validate address ++ if ! mac_is_valid "${ADDRESS}"; then ++ error "Invalid MAC address given: ${ADDRESS}" ++ return ${EXIT_CONF_ERROR} ++ fi + ;; + --tag=*) + TAG=$(cli_get_val "${1}") +@@ -73,6 +79,11 @@ hook_parse_cmdline() { + esac + shift + done ++ ++ # Generate a random MAC address if none given ++ if ! isset ADDRESS; then ++ ADDRESS="$(mac_generate)" ++ fi + } + + hook_create() { +-- +2.39.2 + diff --git a/network/patches/0102-vlan-Fail-when-unknown-command-line-parameters-are-b.patch b/network/patches/0102-vlan-Fail-when-unknown-command-line-parameters-are-b.patch new file mode 100644 index 000000000..28c850b34 --- /dev/null +++ b/network/patches/0102-vlan-Fail-when-unknown-command-line-parameters-are-b.patch @@ -0,0 +1,29 @@ +From 0cf39f2d5178f624161b8c4329140bd00b06019c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:02:15 +0200 +Subject: [PATCH 102/304] vlan: Fail when unknown command line parameters are + being passed + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 0147e54..39dbfff 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -76,6 +76,10 @@ hook_parse_cmdline() { + --tag=*) + TAG=$(cli_get_val "${1}") + ;; ++ -*) ++ error "Unknown argument '${1}'" ++ return ${EXIT_CONF_ERROR} ++ ;; + esac + shift + done +-- +2.39.2 + diff --git a/network/patches/0103-vlan-Rename-PARENT_DEVICE-to-PARENT_PORT.patch b/network/patches/0103-vlan-Rename-PARENT_DEVICE-to-PARENT_PORT.patch new file mode 100644 index 000000000..897e75be7 --- /dev/null +++ b/network/patches/0103-vlan-Rename-PARENT_DEVICE-to-PARENT_PORT.patch @@ -0,0 +1,102 @@ +From a2f35a67d83bd3a4a4438c2b7b8cbc2ee0002e38 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:08:05 +0200 +Subject: [PATCH 103/304] vlan: Rename PARENT_DEVICE to PARENT_PORT + +It technically is a port + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 26 ++++++++++++++++---------- + test/nitsi/test/port-vlan/recipe | 2 +- + 2 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 39dbfff..f19eda4 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -23,14 +23,14 @@ + + HOOK_SETTINGS=( + "ADDRESS" +- "PARENT_DEVICE" ++ "PARENT_PORT" + "TAG" + ) + +-PORT_PARENTS_VAR="PARENT" ++PORT_PARENTS_VAR="PARENT_PORT" + + hook_check_settings() { +- assert isset PARENT_DEVICE ++ assert isset PARENT_PORT + assert isinteger TAG + + if isset ADDRESS; then +@@ -52,18 +52,15 @@ hook_check_settings() { + } + + hook_find_port_name() { +- assert isset PARENT_DEVICE ++ assert isset PARENT_PORT + assert isset TAG + +- print "${PARENT_DEVICE}${VLAN_PORT_INTERFIX}${TAG}" ++ print "${PARENT_PORT}${VLAN_PORT_INTERFIX}${TAG}" + } + + hook_parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in +- --parent-device=*) +- PARENT_DEVICE=$(cli_get_val "${1}") +- ;; + --address=*) + ADDRESS=$(cli_get_val "${1}") + +@@ -73,10 +70,19 @@ hook_parse_cmdline() { + return ${EXIT_CONF_ERROR} + fi + ;; ++ --port=*) ++ PARENT_PORT=$(cli_get_val "${1}") ++ ++ # Check if PARENT_PORT exists ++ if ! port_exists "${PARENT_PORT}"; then ++ error "Port '${PARENT_PORT}' does not exist" ++ return ${EXIT_CONF_ERROR} ++ fi ++ ;; + --tag=*) + TAG=$(cli_get_val "${1}") + ;; +- -*) ++ *) + error "Unknown argument '${1}'" + return ${EXIT_CONF_ERROR} + ;; +@@ -100,7 +106,7 @@ hook_create() { + port_settings_read "${port}" + + # Create the VLAN device +- vlan_create "${port}" "${PARENT_DEVICE}" "${TAG}" "${ADDRESS}" ++ vlan_create "${port}" "${PARENT_PORT}" "${TAG}" "${ADDRESS}" + + exit ${EXIT_OK} + } +diff --git a/test/nitsi/test/port-vlan/recipe b/test/nitsi/test/port-vlan/recipe +index d41377b..7a99251 100644 +--- a/test/nitsi/test/port-vlan/recipe ++++ b/test/nitsi/test/port-vlan/recipe +@@ -17,7 +17,7 @@ bob: network zone upl0 config new static 192.168.100.102/24 + all: network status + + # Create a vlan device with parent port attached to net1 +-all: network port new vlan --parent-device=${p_net1} --tag=42 ++all: network port new vlan --port="${p_net1}" --tag=42 + all: network zone upl0 port attach "${p_net1}v42" + + # Test if the vlan works by pinging bob +-- +2.39.2 + diff --git a/network/patches/0104-vlan-Check-if-parent-device-exists-before-bringing-i.patch b/network/patches/0104-vlan-Check-if-parent-device-exists-before-bringing-i.patch new file mode 100644 index 000000000..6f4ebeded --- /dev/null +++ b/network/patches/0104-vlan-Check-if-parent-device-exists-before-bringing-i.patch @@ -0,0 +1,35 @@ +From 4776723194ad4d1ba75d1b373c1892e44ddcbf97 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:15:01 +0200 +Subject: [PATCH 104/304] vlan: Check if parent device exists before bringing + it up + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index f19eda4..98178e3 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -103,7 +103,15 @@ hook_create() { + device_exists "${port}" && exit ${EXIT_OK} + + # Read configruation +- port_settings_read "${port}" ++ if ! port_settings_read "${port}"; then ++ return ${EXIT_ERROR} ++ fi ++ ++ # Check if the parent port exists ++ if ! port_exists "${PARENT_PORT}"; then ++ error "Port '${PARENT_PORT}' does not exist" ++ return ${EXIT_ERROR} ++ fi + + # Create the VLAN device + vlan_create "${port}" "${PARENT_PORT}" "${TAG}" "${ADDRESS}" +-- +2.39.2 + diff --git a/network/patches/0105-vlan-Simplify-vlan_remove.patch b/network/patches/0105-vlan-Simplify-vlan_remove.patch new file mode 100644 index 000000000..b6d1d2bf1 --- /dev/null +++ b/network/patches/0105-vlan-Simplify-vlan_remove.patch @@ -0,0 +1,32 @@ +From 23ddd3765e344e06f379a5ccc5c2cfcbfca9c7b7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:15:41 +0200 +Subject: [PATCH 105/304] vlan: Simplify vlan_remove() + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index 97028b0..d83e3ad 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -88,13 +88,7 @@ vlan_create() { + } + + vlan_remove() { +- local device=${1} +- assert isset device +- +- # Set down device (if not already done). +- device_set_down ${device} +- +- device_delete ${device} ++ device_delete "$@" + } + + vlan_get_parent() { +-- +2.39.2 + diff --git a/network/patches/0106-vlan-Refactor-vlan_create.patch b/network/patches/0106-vlan-Refactor-vlan_create.patch new file mode 100644 index 000000000..250739fda --- /dev/null +++ b/network/patches/0106-vlan-Refactor-vlan_create.patch @@ -0,0 +1,146 @@ +From d3a0f73d7b2b6d4f634083f5620752e57a7a691b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:28:17 +0200 +Subject: [PATCH 106/304] vlan: Refactor vlan_create() + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 81 +++++++++++++++++++++++------------- + src/hooks/ports/vlan | 10 ++++- + 2 files changed, 60 insertions(+), 31 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index d83e3ad..99a8baa 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -38,53 +38,76 @@ EOF + } + + vlan_create() { +- local device=${1} +- assert isset device ++ local device="${1}" ++ shift + +- local parent=${2} +- assert isset parent ++ assert isset device + +- local tag=${3} +- assert isinteger tag ++ local address ++ local parent ++ local tag ++ ++ # Parse command line arguments ++ while [ $# -gt 0 ]; do ++ case "${1}" in ++ --address=*) ++ address=$(cli_get_val "${1}") ++ ;; ++ --parent=*) ++ parent=$(cli_get_val "${1}") ++ ;; ++ --tag=*) ++ tag=$(cli_get_val "${1}") ++ ;; ++ *) ++ error "Unrecognized argument: ${1}" ++ return ${EXIT_ERROR} ++ ;; ++ esac ++ shift ++ done ++ ++ # Generate a random MAC address if none was passed ++ if ! isset address; then ++ address="$(mac_generate)" ++ fi + +- local address=${4} +- if isset address; then +- assert ismac address ++ # Check if address is valid ++ if ! ismac address; then ++ log ERROR "Invalid mac address: ${address}" ++ return ${EXIT_ERROR} + fi + +- # Check if a device with the name does already exist. +- if device_exists ${device}; then +- log ERROR "device '${device}' does already exist" ++ # Check if a device with the name does already exist ++ if device_exists "${device}"; then ++ log ERROR "Device '${device}' already exists" + return ${EXIT_ERROR} + fi + +- # Check if the parent device exists. +- if ! device_exists ${parent}; then +- log ERROR "parent device '${parent}' does not exist" ++ # Check if the parent device exists ++ if ! device_exists "${parent}"; then ++ log ERROR "Parent device '${parent}' does not exist" + return ${EXIT_ERROR} + fi + + # Load ebtables stuff. + vlan_init + +- local command="ip link add link ${parent} name ${device}" ++ # Make the command ++ local command=( ++ ip link add link "${parent}" name "${device}" ++ address "${address}" type vlan id "${tag}" ++ ) + +- if isset address; then +- command="${command} address ${address}" ++ # Run the command ++ if ! cmd_quiet "${command[*]}"; then ++ log ERROR "Could not create VLAN device ${device}: $?" ++ return ${EXIT_ERROR} + fi + +- command="${command} type vlan id ${tag}" +- +- cmd_quiet ${command} +- local ret=$? +- +- if [ ${ret} -eq ${EXIT_OK} ]; then +- log DEBUG "vlan device '${device}' has been created" +- else +- log ERROR "could not create vlan device '${device}': ${ret}" +- fi ++ log DEBUG "Created VLAN device ${device} (parent = ${parent}, id = ${tag})" + +- return ${ret} ++ return ${EXIT_OK} + } + + vlan_remove() { +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 98178e3..4715b1f 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -114,9 +114,15 @@ hook_create() { + fi + + # Create the VLAN device +- vlan_create "${port}" "${PARENT_PORT}" "${TAG}" "${ADDRESS}" ++ if ! vlan_create "${port}" \ ++ --address="${ADDRESS}" \ ++ --parent="${PARENT_PORT}" \ ++ --tag="${TAG}"; then ++ error "Could not create port: ${port}" ++ return ${EXIT_ERROR} ++ fi + +- exit ${EXIT_OK} ++ return ${EXIT_OK} + } + + hook_remove() { +-- +2.39.2 + diff --git a/network/patches/0107-vlan-Create-partent-port-if-necessary.patch b/network/patches/0107-vlan-Create-partent-port-if-necessary.patch new file mode 100644 index 000000000..2201b68f2 --- /dev/null +++ b/network/patches/0107-vlan-Create-partent-port-if-necessary.patch @@ -0,0 +1,30 @@ +From 68cacd23226f401f1676e8bfc975467647cefef0 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:29:57 +0200 +Subject: [PATCH 107/304] vlan: Create partent port (if necessary) + +Signed-off-by: Michael Tremer +--- + src/hooks/ports/vlan | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 4715b1f..384ad50 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -113,6 +113,12 @@ hook_create() { + return ${EXIT_ERROR} + fi + ++ # Create the partent port first ++ if ! port_create "${PARENT_PORT}"; then ++ error "Could not bring up parent port: ${PARENT_PORT}" ++ return ${EXIT_ERROR} ++ fi ++ + # Create the VLAN device + if ! vlan_create "${port}" \ + --address="${ADDRESS}" \ +-- +2.39.2 + diff --git a/network/patches/0108-vlan-Drop-ebtables-stuff.patch b/network/patches/0108-vlan-Drop-ebtables-stuff.patch new file mode 100644 index 000000000..4945f7dd2 --- /dev/null +++ b/network/patches/0108-vlan-Drop-ebtables-stuff.patch @@ -0,0 +1,49 @@ +From 5338fb1423a84f9faeb597a2b67606fff1f6d6ab Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:30:48 +0200 +Subject: [PATCH 108/304] vlan: Drop ebtables stuff + +We no longer have ebtables + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index 99a8baa..c542bb5 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -24,19 +24,6 @@ PROC_NET_VLAN_CONFIG="${PROC_NET_VLAN}/config" + + VLAN_PORT_INTERFIX="v" + +-vlan_init() { +- ebtables-restore < +Date: Mon, 3 Jun 2019 12:34:49 +0200 +Subject: [PATCH 109/304] vlan: Rename tag to id + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 12 ++++++------ + src/hooks/ports/vlan | 26 +++++++++++++------------- + test/nitsi/test/port-vlan/recipe | 2 +- + 3 files changed, 20 insertions(+), 20 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index c542bb5..9a70c95 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -31,8 +31,8 @@ vlan_create() { + assert isset device + + local address ++ local id + local parent +- local tag + + # Parse command line arguments + while [ $# -gt 0 ]; do +@@ -40,12 +40,12 @@ vlan_create() { + --address=*) + address=$(cli_get_val "${1}") + ;; ++ --id=*) ++ id=$(cli_get_val "${1}") ++ ;; + --parent=*) + parent=$(cli_get_val "${1}") + ;; +- --tag=*) +- tag=$(cli_get_val "${1}") +- ;; + *) + error "Unrecognized argument: ${1}" + return ${EXIT_ERROR} +@@ -80,7 +80,7 @@ vlan_create() { + # Make the command + local command=( + ip link add link "${parent}" name "${device}" +- address "${address}" type vlan id "${tag}" ++ address "${address}" type vlan id "${id}" + ) + + # Run the command +@@ -89,7 +89,7 @@ vlan_create() { + return ${EXIT_ERROR} + fi + +- log DEBUG "Created VLAN device ${device} (parent = ${parent}, id = ${tag})" ++ log DEBUG "Created VLAN device ${device} (parent = ${parent}, id = ${id})" + + return ${EXIT_OK} + } +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 384ad50..97b6985 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -23,39 +23,39 @@ + + HOOK_SETTINGS=( + "ADDRESS" ++ "ID" + "PARENT_PORT" +- "TAG" + ) + + PORT_PARENTS_VAR="PARENT_PORT" + + hook_check_settings() { + assert isset PARENT_PORT +- assert isinteger TAG ++ assert isinteger ID + + if isset ADDRESS; then + assert ismac ADDRESS + fi + +- if [ ${TAG} -gt 4096 ]; then +- error "TAG is greater than 4096." ++ if [ ${ID} -gt 4096 ]; then ++ error "ID is greater than 4096." + exit ${EXIT_ERROR} + fi + + local reserved + for reserved in 0 4095; do +- if [ "${TAG}" = "${reserved}" ]; then +- error "TAG=${reserved} is reserved." ++ if [ "${ID}" = "${reserved}" ]; then ++ error "ID=${reserved} is reserved." + exit ${EXIT_ERROR} + fi + done + } + + hook_find_port_name() { ++ assert isset ID + assert isset PARENT_PORT +- assert isset TAG + +- print "${PARENT_PORT}${VLAN_PORT_INTERFIX}${TAG}" ++ print "${PARENT_PORT}${VLAN_PORT_INTERFIX}${ID}" + } + + hook_parse_cmdline() { +@@ -70,6 +70,9 @@ hook_parse_cmdline() { + return ${EXIT_CONF_ERROR} + fi + ;; ++ --id=*) ++ ID=$(cli_get_val "${1}") ++ ;; + --port=*) + PARENT_PORT=$(cli_get_val "${1}") + +@@ -79,9 +82,6 @@ hook_parse_cmdline() { + return ${EXIT_CONF_ERROR} + fi + ;; +- --tag=*) +- TAG=$(cli_get_val "${1}") +- ;; + *) + error "Unknown argument '${1}'" + return ${EXIT_CONF_ERROR} +@@ -122,8 +122,8 @@ hook_create() { + # Create the VLAN device + if ! vlan_create "${port}" \ + --address="${ADDRESS}" \ +- --parent="${PARENT_PORT}" \ +- --tag="${TAG}"; then ++ --id="${id}" \ ++ --parent="${PARENT_PORT}"; then + error "Could not create port: ${port}" + return ${EXIT_ERROR} + fi +diff --git a/test/nitsi/test/port-vlan/recipe b/test/nitsi/test/port-vlan/recipe +index 7a99251..2341e19 100644 +--- a/test/nitsi/test/port-vlan/recipe ++++ b/test/nitsi/test/port-vlan/recipe +@@ -17,7 +17,7 @@ bob: network zone upl0 config new static 192.168.100.102/24 + all: network status + + # Create a vlan device with parent port attached to net1 +-all: network port new vlan --port="${p_net1}" --tag=42 ++all: network port new vlan --port="${p_net1}" --id=42 + all: network zone upl0 port attach "${p_net1}v42" + + # Test if the vlan works by pinging bob +-- +2.39.2 + diff --git a/network/patches/0110-vlan-Validate-ID.patch b/network/patches/0110-vlan-Validate-ID.patch new file mode 100644 index 000000000..f4abee55f --- /dev/null +++ b/network/patches/0110-vlan-Validate-ID.patch @@ -0,0 +1,110 @@ +From fc1e91cca425c8e929df76dad4488066070879dd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 12:41:36 +0200 +Subject: [PATCH 110/304] vlan: Validate ID + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 25 ++++++++++++++++++++++++- + src/hooks/ports/vlan | 26 +++++++++----------------- + 2 files changed, 33 insertions(+), 18 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index 9a70c95..ee2fb34 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -24,6 +24,23 @@ PROC_NET_VLAN_CONFIG="${PROC_NET_VLAN}/config" + + VLAN_PORT_INTERFIX="v" + ++vlan_valid_id() { ++ local id="${1}" ++ ++ # Must be an integer ++ if ! isinteger id; then ++ return ${EXIT_FALSE} ++ fi ++ ++ # Must be between 1 and 4095 ++ if [ ${id} -ge 1 ] && [ ${id} -le 4096 ]; then ++ return ${EXIT_TRUE} ++ fi ++ ++ # Otherwise this is invalid ++ return ${EXIT_FALSE} ++} ++ + vlan_create() { + local device="${1}" + shift +@@ -31,7 +48,7 @@ vlan_create() { + assert isset device + + local address +- local id ++ local id=1 + local parent + + # Parse command line arguments +@@ -65,6 +82,12 @@ vlan_create() { + return ${EXIT_ERROR} + fi + ++ # Check VLAN ID ++ if ! vlan_valid_id "${id}"; then ++ log ERROR "Invalid VLAN ID: ${id}" ++ return ${EXIT_ERROR} ++ fi ++ + # Check if a device with the name does already exist + if device_exists "${device}"; then + log ERROR "Device '${device}' already exists" +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 97b6985..7f99dbc 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -30,25 +30,11 @@ HOOK_SETTINGS=( + PORT_PARENTS_VAR="PARENT_PORT" + + hook_check_settings() { ++ assert ismac ADDRESS + assert isset PARENT_PORT +- assert isinteger ID +- +- if isset ADDRESS; then +- assert ismac ADDRESS +- fi +- +- if [ ${ID} -gt 4096 ]; then +- error "ID is greater than 4096." +- exit ${EXIT_ERROR} +- fi + +- local reserved +- for reserved in 0 4095; do +- if [ "${ID}" = "${reserved}" ]; then +- error "ID=${reserved} is reserved." +- exit ${EXIT_ERROR} +- fi +- done ++ assert isinteger ID ++ assert vlan_valid_id "${ID}" + } + + hook_find_port_name() { +@@ -72,6 +58,12 @@ hook_parse_cmdline() { + ;; + --id=*) + ID=$(cli_get_val "${1}") ++ ++ # Validate VLAN ID ++ if ! vlan_valid_id "${ID}"; then ++ error "Invalid VLAN ID: ${ID}" ++ return ${EXIT_CONF_ERROR} ++ fi + ;; + --port=*) + PARENT_PORT=$(cli_get_val "${1}") +-- +2.39.2 + diff --git a/network/patches/0111-util-Add-abort-which-will-stop-the-program-immediate.patch b/network/patches/0111-util-Add-abort-which-will-stop-the-program-immediate.patch new file mode 100644 index 000000000..f14d8610a --- /dev/null +++ b/network/patches/0111-util-Add-abort-which-will-stop-the-program-immediate.patch @@ -0,0 +1,48 @@ +From 9532462fe04658d728ecbf263b586111f73fe2b2 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 13:16:47 +0200 +Subject: [PATCH 111/304] util: Add abort() which will stop the program + immediately + +Signed-off-by: Michael Tremer +--- + src/functions/functions.util | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/functions/functions.util b/src/functions/functions.util +index 7379a98..39ad861 100644 +--- a/src/functions/functions.util ++++ b/src/functions/functions.util +@@ -469,14 +469,27 @@ assert() { + local assertion="$@" + + if ! ${assertion}; then +- error_log "Assertion '${assertion}' failed." + backtrace +- exit ${EXIT_ERROR_ASSERT} ++ ++ # End the program here ++ abort "Assertion failed: ${assertion}" + fi + + return ${EXIT_OK} + } + ++# Ends the program immediately without cleaning up ++abort() { ++ local msg="$@" ++ ++ # Print message ++ if isset msg; then ++ log ERROR "${msg}" ++ fi ++ ++ exit ${EXIT_ERROR_ASSERT} ++} ++ + # This function checks, if the given argument is an assert error + # exit code. If this is the case, the script will halt immediately. + assert_check_retval() { +-- +2.39.2 + diff --git a/network/patches/0112-vlan-Add-support-for-802.1ad-QinQ.patch b/network/patches/0112-vlan-Add-support-for-802.1ad-QinQ.patch new file mode 100644 index 000000000..62f77efca --- /dev/null +++ b/network/patches/0112-vlan-Add-support-for-802.1ad-QinQ.patch @@ -0,0 +1,139 @@ +From 2eb7011cb5447f9568c8136940f59a047e1b8dae Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 3 Jun 2019 13:17:06 +0200 +Subject: [PATCH 112/304] vlan: Add support for 802.1ad (QinQ) + +Signed-off-by: Michael Tremer +--- + src/functions/functions.vlan | 24 +++++++++++++++++++++++- + src/hooks/ports/vlan | 22 ++++++++++++++++++++-- + 2 files changed, 43 insertions(+), 3 deletions(-) + +diff --git a/src/functions/functions.vlan b/src/functions/functions.vlan +index ee2fb34..fbaa34f 100644 +--- a/src/functions/functions.vlan ++++ b/src/functions/functions.vlan +@@ -22,6 +22,11 @@ + PROC_NET_VLAN="/proc/net/vlan" + PROC_NET_VLAN_CONFIG="${PROC_NET_VLAN}/config" + ++VLAN_SUPPORTED_PROTOCOLS=( ++ "802.1Q" # default ++ "802.1ad" ++) ++ + VLAN_PORT_INTERFIX="v" + + vlan_valid_id() { +@@ -41,6 +46,13 @@ vlan_valid_id() { + return ${EXIT_FALSE} + } + ++vlan_supported_protocol() { ++ local proto="${1}" ++ assert isset proto ++ ++ list_match "${proto}" "${VLAN_SUPPORTED_PROTOCOLS[@]}" ++} ++ + vlan_create() { + local device="${1}" + shift +@@ -50,6 +62,7 @@ vlan_create() { + local address + local id=1 + local parent ++ local protocol="${VLAN_SUPPORTED_PROTOCOLS[0]}" + + # Parse command line arguments + while [ $# -gt 0 ]; do +@@ -63,6 +76,9 @@ vlan_create() { + --parent=*) + parent=$(cli_get_val "${1}") + ;; ++ --protocol=*) ++ protocol=$(cli_get_val "${1}") ++ ;; + *) + error "Unrecognized argument: ${1}" + return ${EXIT_ERROR} +@@ -82,6 +98,12 @@ vlan_create() { + return ${EXIT_ERROR} + fi + ++ # Check protocol ++ if ! vlan_supported_protocol "${protocol}"; then ++ log ERROR "Invalid protocol: ${protocol}" ++ return ${EXIT_ERROR} ++ fi ++ + # Check VLAN ID + if ! vlan_valid_id "${id}"; then + log ERROR "Invalid VLAN ID: ${id}" +@@ -103,7 +125,7 @@ vlan_create() { + # Make the command + local command=( + ip link add link "${parent}" name "${device}" +- address "${address}" type vlan id "${id}" ++ address "${address}" type vlan proto "${protocol}" id "${id}" + ) + + # Run the command +diff --git a/src/hooks/ports/vlan b/src/hooks/ports/vlan +index 7f99dbc..af563ee 100644 +--- a/src/hooks/ports/vlan ++++ b/src/hooks/ports/vlan +@@ -25,14 +25,21 @@ HOOK_SETTINGS=( + "ADDRESS" + "ID" + "PARENT_PORT" ++ "PROTOCOL" + ) + ++# Set the default to 802.1Q ++DEFAULT_PROTOCOL="${VLAN_SUPPORTED_PROTOCOLS[0]}" ++ + PORT_PARENTS_VAR="PARENT_PORT" + + hook_check_settings() { + assert ismac ADDRESS + assert isset PARENT_PORT + ++ assert isset PROTOCOL ++ assert vlan_supported_protocol "${PROTOCOL}" ++ + assert isinteger ID + assert vlan_valid_id "${ID}" + } +@@ -74,6 +81,16 @@ hook_parse_cmdline() { + return ${EXIT_CONF_ERROR} + fi + ;; ++ --protocol=*) ++ PROTOCOL="$(cli_get_val "${1}")" ++ ++ # Check if PROTOCOL is supported ++ if ! vlan_supported_protocol "${PROTOCOL}"; then ++ error "Protocol '${PROTOCOL}' is not supported" ++ error "Choose one of ${VLAN_SUPPORTED_PROTOCOLS[*]}" ++ return ${EXIT_CONF_ERROR} ++ fi ++ ;; + *) + error "Unknown argument '${1}'" + return ${EXIT_CONF_ERROR} +@@ -114,8 +131,9 @@ hook_create() { + # Create the VLAN device + if ! vlan_create "${port}" \ + --address="${ADDRESS}" \ +- --id="${id}" \ +- --parent="${PARENT_PORT}"; then ++ --id="${ID}" \ ++ --parent="${PARENT_PORT}" \ ++ --protocol="${PROTOCOL}"; then + error "Could not create port: ${port}" + return ${EXIT_ERROR} + fi +-- +2.39.2 + diff --git a/network/patches/0113-Do-not-try-to-start-Bird-during-boot-process.patch b/network/patches/0113-Do-not-try-to-start-Bird-during-boot-process.patch new file mode 100644 index 000000000..7e25e5d9f --- /dev/null +++ b/network/patches/0113-Do-not-try-to-start-Bird-during-boot-process.patch @@ -0,0 +1,57 @@ +From ecc7067479d165f4178f04248d86898cf50e3d95 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 20 Jun 2019 23:09:01 +0200 +Subject: [PATCH 113/304] Do not try to start Bird during boot process + +We should not do this in the network script and let just +systemd take care of this. Otherwise we would end up in +an infinite loop during the boot process. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.bird | 14 -------------- + src/network | 3 --- + 2 files changed, 17 deletions(-) + +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index 1bbac8c..55d43b5 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -33,20 +33,6 @@ bird_reload() { + service_reload "bird.service" + } + +-bird_enable() { +- # Generate configuration file +- if ! bird_generate_config; then +- log ERROR "Could not write Bird configuration" +- return ${EXIT_ERROR} +- fi +- +- # Enable the service to be automatically started next time +- service_enable "bird.service" +- +- # Start it now +- bird_start +-} +- + # Update configuration any apply it in one go + bird_update() { + if ! bird_generate_config; then +diff --git a/src/network b/src/network +index be06d8a..30f87a0 100644 +--- a/src/network ++++ b/src/network +@@ -1381,9 +1381,6 @@ case "${action}" in + # Update resolv.conf(5) when initializing the network + dns_generate_resolvconf + +- # Make sure bird is running +- bird_enable +- + # Also execute all triggers + triggers_execute_all "init" + ;; +-- +2.39.2 + diff --git a/network/patches/0114-configure-Break-when-asciidoc-cannot-be-found.patch b/network/patches/0114-configure-Break-when-asciidoc-cannot-be-found.patch new file mode 100644 index 000000000..1fc0c289d --- /dev/null +++ b/network/patches/0114-configure-Break-when-asciidoc-cannot-be-found.patch @@ -0,0 +1,27 @@ +From 9665b7963d263fd83ac132a84a3809fc6a03287a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 21 Jun 2019 06:30:44 +0100 +Subject: [PATCH 114/304] configure: Break when asciidoc cannot be found + +Signed-off-by: Michael Tremer +--- + configure.ac | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 117850f..340cfd6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -144,6 +144,9 @@ PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) + # ------------------------------------------------------------------------------ + + AC_CHECK_PROGS(ASCIIDOC, [asciidoc]) ++if test -z "${ASCIIDOC}"; then ++ AC_MSG_ERROR([Required program 'asciidoc' not found]) ++fi + + # ------------------------------------------------------------------------------ + +-- +2.39.2 + diff --git a/network/patches/0115-Fix-creating-new-configs.patch b/network/patches/0115-Fix-creating-new-configs.patch new file mode 100644 index 000000000..6f1c964e4 --- /dev/null +++ b/network/patches/0115-Fix-creating-new-configs.patch @@ -0,0 +1,29 @@ +From f1081966991d55ccd182b45f58fc0fde31437f77 Mon Sep 17 00:00:00 2001 +From: Stefan Schantl +Date: Sat, 22 Jun 2019 09:52:37 +0000 +Subject: [PATCH 115/304] Fix creating new configs + +The id argument was missing for the zone_config_settings_write. + +Signed-off-by: Stefan Schantl +Signed-off-by: Michael Tremer +--- + src/header-config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/header-config b/src/header-config +index c6a775c..ed647cd 100644 +--- a/src/header-config ++++ b/src/header-config +@@ -45,7 +45,7 @@ hook_new() { + fi + + # Write configuration to disk +- if ! zone_config_settings_write "${zone}" "${HOOK}"; then ++ if ! zone_config_settings_write "${zone}" "${HOOK}" "${id}"; then + return ${EXIT_ERROR} + fi + +-- +2.39.2 + diff --git a/network/patches/0116-inetcalc-Fix-compiler-warnings.patch b/network/patches/0116-inetcalc-Fix-compiler-warnings.patch new file mode 100644 index 000000000..9b6dca279 --- /dev/null +++ b/network/patches/0116-inetcalc-Fix-compiler-warnings.patch @@ -0,0 +1,30 @@ +From d07532fad069c51d188ba7b93539488499d5dbf9 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 13:31:03 +0000 +Subject: [PATCH 116/304] inetcalc: Fix compiler warnings + +Signed-off-by: Michael Tremer +--- + src/inetcalc.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/inetcalc.c b/src/inetcalc.c +index 1841c84..7c072e9 100644 +--- a/src/inetcalc.c ++++ b/src/inetcalc.c +@@ -134,9 +134,9 @@ static int default_prefix(const int family) { + static int ip_address_parse_simple(ip_address_t* ip, const int family, const char* address) { + assert(family == AF_INET || family == AF_INET6); + +- size_t address_length = strlen(address); +- char buffer[address_length + 1]; +- strncpy(buffer, address, sizeof(buffer)); ++ // Copy input to stack ++ char buffer[512]; ++ strncpy(buffer, address, sizeof(buffer) - 1); + + // Search for a prefix or subnet mask + char* prefix = strchr(buffer, '/'); +-- +2.39.2 + diff --git a/network/patches/0117-firewall-Drop-separate-scripts-for-IPv6-and-IPv4.patch b/network/patches/0117-firewall-Drop-separate-scripts-for-IPv6-and-IPv4.patch new file mode 100644 index 000000000..bb9f90e7a --- /dev/null +++ b/network/patches/0117-firewall-Drop-separate-scripts-for-IPv6-and-IPv4.patch @@ -0,0 +1,70 @@ +From 0c5d22de5c22c9264dcb839df72440a1d11faa0c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 21 Jun 2019 06:34:23 +0100 +Subject: [PATCH 117/304] firewall: Drop separate scripts for IPv6 and IPv4 + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 +-- + src/{firewall6 => firewall} | 0 + src/firewall4 | 29 ----------------------------- + 3 files changed, 1 insertion(+), 31 deletions(-) + rename src/{firewall6 => firewall} (100%) + delete mode 100644 src/firewall4 + +diff --git a/Makefile.am b/Makefile.am +index 4c26a9d..a36a4ab 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -115,8 +115,7 @@ dist_doc_DATA = \ + dist_sbin_SCRIPTS = \ + src/dhclient-script \ + src/firewall-config \ +- src/firewall4 \ +- src/firewall6 \ ++ src/firewall \ + src/network + + network_DATA = \ +diff --git a/src/firewall6 b/src/firewall +similarity index 100% +rename from src/firewall6 +rename to src/firewall +diff --git a/src/firewall4 b/src/firewall4 +deleted file mode 100644 +index 55eed2c..0000000 +--- a/src/firewall4 ++++ /dev/null +@@ -1,29 +0,0 @@ +-#!/bin/bash +-############################################################################### +-# # +-# IPFire.org - A linux based firewall # +-# Copyright (C) 2012 IPFire Network Development Team # +-# # +-# This program is free software: you can redistribute it and/or modify # +-# it under the terms of the GNU General Public License as published by # +-# the Free Software Foundation, either version 3 of the License, or # +-# (at your option) any later version. # +-# # +-# This program 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 General Public License for more details. # +-# # +-# You should have received a copy of the GNU General Public License # +-# along with this program. If not, see . # +-# # +-############################################################################### +- +-. /usr/lib/network/functions +- +-# Read firewall settings +-firewall_settings_read +- +-firewall_cli "ipv4" "$@" +- +-exit ${EXIT_ERROR} +-- +2.39.2 + diff --git a/network/patches/0118-systemd-Remove-double-firewall-scripts.patch b/network/patches/0118-systemd-Remove-double-firewall-scripts.patch new file mode 100644 index 000000000..d9090af5f --- /dev/null +++ b/network/patches/0118-systemd-Remove-double-firewall-scripts.patch @@ -0,0 +1,76 @@ +From 67131768c979c66ad3717e46cb81a068b14eafee Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 13:43:04 +0000 +Subject: [PATCH 118/304] systemd: Remove double firewall scripts + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 +-- + .../{firewall4.service.in => firewall.service} | 6 +++--- + src/systemd/firewall6.service.in | 14 -------------- + 3 files changed, 4 insertions(+), 19 deletions(-) + rename src/systemd/{firewall4.service.in => firewall.service} (62%) + delete mode 100644 src/systemd/firewall6.service.in + +diff --git a/Makefile.am b/Makefile.am +index a36a4ab..81cf50d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -363,8 +363,7 @@ UNINSTALL_EXEC_HOOKS += ppp-uninstall-hook + + if HAVE_SYSTEMD + systemdsystemunit_DATA = \ +- src/systemd/firewall4.service \ +- src/systemd/firewall6.service \ ++ src/systemd/firewall.service \ + src/systemd/firewall-init.service \ + src/systemd/network-init.service \ + src/systemd/network@.service +diff --git a/src/systemd/firewall4.service.in b/src/systemd/firewall.service +similarity index 62% +rename from src/systemd/firewall4.service.in +rename to src/systemd/firewall.service +index 568f5e7..34797e5 100644 +--- a/src/systemd/firewall4.service.in ++++ b/src/systemd/firewall.service +@@ -1,5 +1,5 @@ + [Unit] +-Description=Firewall for IPv4 ++Description=Firewall for IPFire + After=firewall-init.service + Before=network.target + Requires=firewall-init.service +@@ -7,8 +7,8 @@ Requires=firewall-init.service + [Service] + Type=oneshot + RemainAfterExit=yes +-ExecStart=@sbindir@/firewall4 start +-ExecStop=@sbindir@/firewall4 stop ++ExecStart=@sbindir@/firewall start ++ExecStop=@sbindir@/firewall stop + + [Install] + WantedBy=multi-user.target +diff --git a/src/systemd/firewall6.service.in b/src/systemd/firewall6.service.in +deleted file mode 100644 +index 873bfe6..0000000 +--- a/src/systemd/firewall6.service.in ++++ /dev/null +@@ -1,14 +0,0 @@ +-[Unit] +-Description=Firewall for IPv6 +-After=firewall-init.service +-Before=network.target +-Requires=firewall-init.service +- +-[Service] +-Type=oneshot +-RemainAfterExit=yes +-ExecStart=@sbindir@/firewall6 start +-ExecStop=@sbindir@/firewall6 stop +- +-[Install] +-WantedBy=multi-user.target +-- +2.39.2 + diff --git a/network/patches/0119-firewall-Add-init-action-to-main-script.patch b/network/patches/0119-firewall-Add-init-action-to-main-script.patch new file mode 100644 index 000000000..82a8ae26e --- /dev/null +++ b/network/patches/0119-firewall-Add-init-action-to-main-script.patch @@ -0,0 +1,54 @@ +From 3e446cf0bff8c1dc409479bf02b0fc8912847c13 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 13:50:00 +0000 +Subject: [PATCH 119/304] firewall: Add init action to main script + +Signed-off-by: Michael Tremer +--- + src/firewall | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +diff --git a/src/firewall b/src/firewall +index db7284c..c47ac61 100644 +--- a/src/firewall ++++ b/src/firewall +@@ -19,11 +19,35 @@ + # # + ############################################################################### + ++# Parse the command line ++while [ $# -gt 0 ]; do ++ case "${1}" in ++ -d|--debug) ++ DEBUG=1 ++ ;; ++ *) ++ action=${1} ++ ;; ++ esac ++ shift ++ [ -n "${action}" ] && break ++done ++ + . /usr/lib/network/functions + + # Read firewall settings + firewall_settings_read + +-firewall_cli "ipv6" "$@" ++case "${action}" in ++ # Initialise kernel with firewall settings ++ init) ++ firewall_kernel_init ++ exit $? ++ ;; ++ ++ *) ++ firewall_cli "ipv6" "${action}" "$@" ++ ;; ++esac + + exit ${EXIT_ERROR} +-- +2.39.2 + diff --git a/network/patches/0120-firewall-Drop-initialisation-helper-script.patch b/network/patches/0120-firewall-Drop-initialisation-helper-script.patch new file mode 100644 index 000000000..f77ad79db --- /dev/null +++ b/network/patches/0120-firewall-Drop-initialisation-helper-script.patch @@ -0,0 +1,79 @@ +From 19b14da45fb83638878b14e77303194733679bc1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 13:52:09 +0000 +Subject: [PATCH 120/304] firewall: Drop initialisation helper script + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 - + src/helpers/firewall-kernel-init | 30 ---------------------------- + src/systemd/firewall-init.service.in | 4 ++-- + 3 files changed, 2 insertions(+), 33 deletions(-) + delete mode 100644 src/helpers/firewall-kernel-init + +diff --git a/Makefile.am b/Makefile.am +index 81cf50d..0974ba8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -206,7 +206,6 @@ dist_network_SCRIPTS = \ + + dist_helpers_SCRIPTS = \ + src/helpers/dhcpd-config-helper \ +- src/helpers/firewall-kernel-init \ + src/helpers/hostapd-config-helper \ + src/helpers/ipsec-updown \ + src/helpers/pppd-angel \ +diff --git a/src/helpers/firewall-kernel-init b/src/helpers/firewall-kernel-init +deleted file mode 100644 +index aea82c4..0000000 +--- a/src/helpers/firewall-kernel-init ++++ /dev/null +@@ -1,30 +0,0 @@ +-#!/bin/bash +-############################################################################### +-# # +-# IPFire.org - A linux based firewall # +-# Copyright (C) 2012 IPFire Network Development Team # +-# # +-# This program is free software: you can redistribute it and/or modify # +-# it under the terms of the GNU General Public License as published by # +-# the Free Software Foundation, either version 3 of the License, or # +-# (at your option) any later version. # +-# # +-# This program 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 General Public License for more details. # +-# # +-# You should have received a copy of the GNU General Public License # +-# along with this program. If not, see . # +-# # +-############################################################################### +- +-. /usr/lib/network/functions +- +-# Read firewall settings +-firewall_setttings_read +- +-# Initialize kernel parameters for the firewall. +-firewall_kernel_init +- +-exit ${EXIT_OK} +diff --git a/src/systemd/firewall-init.service.in b/src/systemd/firewall-init.service.in +index 24497e9..91dd058 100644 +--- a/src/systemd/firewall-init.service.in ++++ b/src/systemd/firewall-init.service.in +@@ -1,8 +1,8 @@ + [Unit] +-Description=Initialize kernel parameters for the firewalls ++Description=Initialize kernel parameters for the firewall + Before=network.target + + [Service] + Type=oneshot + RemainAfterExit=yes +-ExecStart=@helpersdir@/firewall-kernel-init ++ExecStart=@sbindir@/firewall init +-- +2.39.2 + diff --git a/network/patches/0121-Revert-firewall-Disable-PMTU-by-default.patch b/network/patches/0121-Revert-firewall-Disable-PMTU-by-default.patch new file mode 100644 index 000000000..01c70c7be --- /dev/null +++ b/network/patches/0121-Revert-firewall-Disable-PMTU-by-default.patch @@ -0,0 +1,28 @@ +From 70c56486267789a3767e22833548694a9b69e1b8 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 13:55:00 +0000 +Subject: [PATCH 121/304] Revert "firewall: Disable PMTU by default" + +This reverts commit b3a66a5c00bc4e39ce0db34e2ac96c4911b4e31a. + +Signed-off-by: Michael Tremer +--- + src/functions/functions.constants-firewall | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/functions/functions.constants-firewall b/src/functions/functions.constants-firewall +index 4f7f503..d42189a 100644 +--- a/src/functions/functions.constants-firewall ++++ b/src/functions/functions.constants-firewall +@@ -78,7 +78,7 @@ FIREWALL_USE_ECN="true" + FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_USE_ECN" + + # Path MTU discovery +-FIREWALL_PMTU_DISCOVERY="false" ++FIREWALL_PMTU_DISCOVERY="true" + FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_PMTU_DISCOVERY" + + # Default TTL +-- +2.39.2 + diff --git a/network/patches/0122-firewall-Fix-reading-writing-settings.patch b/network/patches/0122-firewall-Fix-reading-writing-settings.patch new file mode 100644 index 000000000..d0cd4b263 --- /dev/null +++ b/network/patches/0122-firewall-Fix-reading-writing-settings.patch @@ -0,0 +1,147 @@ +From c69adafd8ad8abf4f14b6fe110bbd8efb5eca596 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 14:11:15 +0000 +Subject: [PATCH 122/304] firewall: Fix reading/writing settings + +Signed-off-by: Michael Tremer +--- + src/functions/functions.constants-firewall | 40 ++++++++++++---------- + src/functions/functions.settings | 6 ++-- + 2 files changed, 25 insertions(+), 21 deletions(-) + +diff --git a/src/functions/functions.constants-firewall b/src/functions/functions.constants-firewall +index d42189a..2ca9390 100644 +--- a/src/functions/functions.constants-firewall ++++ b/src/functions/functions.constants-firewall +@@ -19,6 +19,10 @@ + # # + ############################################################################### + ++# Firewall file configuration ++FIREWALL_SETTINGS_DIR="/etc/firewall" ++FIREWALL_SETTINGS_FILE="${FIREWALL_SETTINGS_DIR}/settings" ++ + # This variable is used to point to a directory + # in which the iptables ruleset will be generated. + IPTABLES_TMPDIR= +@@ -32,78 +36,78 @@ FIREWALL_MACROS_DIRS="${FIREWALL_CONFIG_DIR}/macros" + FIREWALL_MACROS_DIRS="${FIREWALL_MACROS_DIRS} /usr/share/firewall/macros" + + # List of parameters which are saved in the configuration file. +-FIREWALL_CONFIG_PARAMS="" ++FIREWALL_SETTINGS=( "DEBUG" ) + + # Valid arguments in the rules file. + FIREWALL_RULES_CONFIG_PARAMS="src dst proto action sport dport in out" + + # Define the default logging method (nflog or syslog). + FIREWALL_LOG_METHOD="nflog" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_METHOD" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_METHOD" ) + + # Set the default threshold for the nflog method. + FIREWALL_NFLOG_THRESHOLD=30 +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_NFLOG_THRESHOLD" ++FIREWALL_SETTINGS+=( "FIREWALL_NFLOG_THRESHOLD" ) + + # Enable clamping MSS for braindead ISPs which filter ICMP packets. + FIREWALL_CLAMP_PATH_MTU="false" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_CLAMP_PATH_MTU" ++FIREWALL_SETTINGS+=( "FIREWALL_CLAMP_PATH_MTU" ) + + # Conntrack: Max. amount of simultaneous connections. + CONNTRACK_MAX_CONNECTIONS="16384" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} CONNTRACK_MAX_CONNECTIONS" ++FIREWALL_SETTINGS+=( "CONNTRACK_MAX_CONNECTIONS" ) + + # Conntrack: UDP timeout + CONNTRACK_UDP_TIMEOUT="60" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} CONNTRACK_UDP_TIMEOUT" ++FIREWALL_SETTINGS+=( "CONNTRACK_UDP_TIMEOUT" ) + + # Use SYN cookies or not + FIREWALL_SYN_COOKIES="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_SYN_COOKIES" ++FIREWALL_SETTINGS+=( "FIREWALL_SYN_COOKIES" ) + + # rp_filter + FIREWALL_RP_FILTER="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_RP_FILTER" ++FIREWALL_SETTINGS+=( "FIREWALL_RP_FILTER" ) + + # Log martians + FIREWALL_LOG_MARTIANS="false" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_MARTIANS" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_MARTIANS" ) + + # Accept ICMP redirects + FIREWALL_ACCEPT_ICMP_REDIRECTS="false" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_ACCEPT_ICMP_REDIRECTS" ++FIREWALL_SETTINGS+=( "FIREWALL_ACCEPT_ICMP_REDIRECTS" ) + + # ECN (Explicit Congestion Notification) + FIREWALL_USE_ECN="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_USE_ECN" ++FIREWALL_SETTINGS+=( "FIREWALL_USE_ECN" ) + + # Path MTU discovery + FIREWALL_PMTU_DISCOVERY="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_PMTU_DISCOVERY" ++FIREWALL_SETTINGS+=( "FIREWALL_PMTU_DISCOVERY" ) + + # Default TTL + FIREWALL_DEFAULT_TTL="64" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_DEFAULT_TTL" ++FIREWALL_SETTINGS+=( "FIREWALL_DEFAULT_TTL" ) + + # Log stealth scans + FIREWALL_LOG_STEALTH_SCANS="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_STEALTH_SCANS" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_STEALTH_SCANS" ) + + # Log packets with bad TCP flags + FIREWALL_LOG_BAD_TCP_FLAGS="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_BAD_TCP_FLAGS" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_BAD_TCP_FLAGS" ) + + # Log INVALID TCP packets + FIREWALL_LOG_INVALID_TCP="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_TCP" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_INVALID_TCP" ) + + # Log INVALID UDP packets + FIREWALL_LOG_INVALID_UDP="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_UDP" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_INVALID_UDP" ) + + # Log INVALID ICMP packets + FIREWALL_LOG_INVALID_ICMP="true" +-FIREWALL_CONFIG_PARAMS="${FIREWALL_CONFIG_PARAMS} FIREWALL_LOG_INVALID_ICMP" ++FIREWALL_SETTINGS+=( "FIREWALL_LOG_INVALID_ICMP" ) + + FIREWALL_SUPPORTED_PROTOCOLS="tcp udp icmp igmp esp ah gre" + FIREWALL_PROTOCOLS_SUPPORTING_PORTS="tcp udp" +diff --git a/src/functions/functions.settings b/src/functions/functions.settings +index 69f4c23..5728e72 100644 +--- a/src/functions/functions.settings ++++ b/src/functions/functions.settings +@@ -297,13 +297,13 @@ network_settings_list() { + } + + firewall_settings_read() { +- settings_read "${FIREWALL_SETTINGS_FILE}" "${FIREWALL_SETTINGS_PARAMS}" ++ settings_read "${FIREWALL_SETTINGS_FILE}" "${FIREWALL_SETTINGS[*]}" + } + + firewall_settings_write() { +- settings_write "${FIREWALL_SETTINGS_FILE}" "${FIREWALL_SETTINGS_PARAMS}" ++ settings_write "${FIREWALL_SETTINGS_FILE}" "${FIREWALL_SETTINGS[*]}" + } + + firewall_settings_print() { +- settings_print "${FIREWALL_SETTINGS_PARAMS}" ++ settings_print "${FIREWALL_SETTINGS[*]}" + } +-- +2.39.2 + diff --git a/network/patches/0123-firewall-Drop-firewall-config-command-in-favour-of-f.patch b/network/patches/0123-firewall-Drop-firewall-config-command-in-favour-of-f.patch new file mode 100644 index 000000000..8f26fe8ec --- /dev/null +++ b/network/patches/0123-firewall-Drop-firewall-config-command-in-favour-of-f.patch @@ -0,0 +1,80 @@ +From 12c8f41a0791a517d5cc7cd30bd566896891f092 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 22 Jun 2019 14:16:07 +0000 +Subject: [PATCH 123/304] firewall: Drop firewall-config command in favour of + "firewall settings" + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 - + src/firewall | 5 +++++ + src/firewall-config | 29 ----------------------------- + 3 files changed, 5 insertions(+), 30 deletions(-) + delete mode 100644 src/firewall-config + +diff --git a/Makefile.am b/Makefile.am +index 0974ba8..4fe5068 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -114,7 +114,6 @@ dist_doc_DATA = \ + + dist_sbin_SCRIPTS = \ + src/dhclient-script \ +- src/firewall-config \ + src/firewall \ + src/network + +diff --git a/src/firewall b/src/firewall +index c47ac61..569f413 100644 +--- a/src/firewall ++++ b/src/firewall +@@ -45,6 +45,11 @@ case "${action}" in + exit $? + ;; + ++ settings) ++ firewall_cli_settings "$@" ++ exit $? ++ ;; ++ + *) + firewall_cli "ipv6" "${action}" "$@" + ;; +diff --git a/src/firewall-config b/src/firewall-config +deleted file mode 100644 +index 53ec175..0000000 +--- a/src/firewall-config ++++ /dev/null +@@ -1,29 +0,0 @@ +-#!/bin/bash +-############################################################################### +-# # +-# IPFire.org - A linux based firewall # +-# Copyright (C) 2012 IPFire Network Development Team # +-# # +-# This program is free software: you can redistribute it and/or modify # +-# it under the terms of the GNU General Public License as published by # +-# the Free Software Foundation, either version 3 of the License, or # +-# (at your option) any later version. # +-# # +-# This program 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 General Public License for more details. # +-# # +-# You should have received a copy of the GNU General Public License # +-# along with this program. If not, see . # +-# # +-############################################################################### +- +-. /usr/lib/network/functions +- +-# Read firewall settings +-firewall_settings_read +- +-firewall_cli_settings "$@" +- +-exit ${EXIT_ERROR} +-- +2.39.2 + diff --git a/network/patches/0124-wireless-Do-not-attempt-DFS-when-reg-domain-is-set-t.patch b/network/patches/0124-wireless-Do-not-attempt-DFS-when-reg-domain-is-set-t.patch new file mode 100644 index 000000000..d7e631785 --- /dev/null +++ b/network/patches/0124-wireless-Do-not-attempt-DFS-when-reg-domain-is-set-t.patch @@ -0,0 +1,30 @@ +From 038a7f3628f6b7648f89bb3ef6813e757fed6fec Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 23 Jun 2019 10:30:17 +0000 +Subject: [PATCH 124/304] wireless: Do not attempt DFS when reg domain is set + to world + +Signed-off-by: Michael Tremer +--- + src/functions/functions.wireless | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/functions/functions.wireless b/src/functions/functions.wireless +index 733a356..860b2dd 100644 +--- a/src/functions/functions.wireless ++++ b/src/functions/functions.wireless +@@ -555,6 +555,11 @@ wireless_supports_dfs() { + local device="${1}" + assert isset device + ++ # DFS is not supported if wireless reg domain is set to world ++ if [ -n "${WIRELESS_REGULATORY_DOMAIN}" ] || [ "${WIRELESS_REGULATORY_DOMAIN}" = "00" ]; then ++ return ${EXIT_FALSE} ++ fi ++ + local phy="$(device_get_phy "${device}")" + if ! isset phy; then + log ERROR "Could not determine PHY for ${device}" +-- +2.39.2 + diff --git a/network/patches/0125-bird-Start-service-when-needed-and-not-already-runni.patch b/network/patches/0125-bird-Start-service-when-needed-and-not-already-runni.patch new file mode 100644 index 000000000..ad660cf7c --- /dev/null +++ b/network/patches/0125-bird-Start-service-when-needed-and-not-already-runni.patch @@ -0,0 +1,42 @@ +From 0d99f882ea0f8c4b1c55f7107067a0cb35fedfb3 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 23 Jun 2019 10:33:48 +0000 +Subject: [PATCH 125/304] bird: Start service when needed and not already + running + +Signed-off-by: Michael Tremer +--- + src/functions/functions.bird | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/functions/functions.bird b/src/functions/functions.bird +index 55d43b5..cbcb6e2 100644 +--- a/src/functions/functions.bird ++++ b/src/functions/functions.bird +@@ -21,6 +21,10 @@ + + BIRD_CONF="/etc/bird.conf" + ++bird_is_active() { ++ service_is_active "bird.service" ++} ++ + bird_start() { + service_start "bird.service" + } +@@ -41,7 +45,11 @@ bird_update() { + fi + + # Reload bird +- bird_reload ++ if bird_is_active; then ++ bird_reload ++ else ++ bird_start ++ fi + } + + bird_generate_config() { +-- +2.39.2 + diff --git a/network/patches/0126-ip-tunnel-Support-setting-MTU-on-tunnels.patch b/network/patches/0126-ip-tunnel-Support-setting-MTU-on-tunnels.patch new file mode 100644 index 000000000..78fc906ba --- /dev/null +++ b/network/patches/0126-ip-tunnel-Support-setting-MTU-on-tunnels.patch @@ -0,0 +1,60 @@ +From 9515b03940a0fac2db3fff105638f49a53f85e7d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 23 Jun 2019 11:57:17 +0000 +Subject: [PATCH 126/304] ip-tunnel: Support setting MTU on tunnels + +Signed-off-by: Michael Tremer +--- + src/hooks/zones/ip-tunnel | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/hooks/zones/ip-tunnel b/src/hooks/zones/ip-tunnel +index c4a4fb4..3c885cb 100644 +--- a/src/hooks/zones/ip-tunnel ++++ b/src/hooks/zones/ip-tunnel +@@ -26,6 +26,7 @@ SUPPORTED_IP_TUNNEL_MODES="gre sit vti" + HOOK_SETTINGS=( + "MARK" + "MODE" ++ "MTU" + "PEER" + "LOCAL_ADDRESS" + ) +@@ -33,6 +34,9 @@ HOOK_SETTINGS=( + # Default mode of the tunnel + DEFAULT_MODE="gre" + ++# Default MTU ++DEFAULT_MTU="1480" ++ + hook_check_settings() { + assert isset MODE && assert isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES} + +@@ -67,6 +71,16 @@ hook_parse_cmdline() { + fi + ;; + ++ --mtu=*) ++ MTU="$(cli_get_val "${1}")" ++ ++ # Validate MTU ++ if ! mtu_is_valid "ipv6" "${MTU}"; then ++ error "Invalid MTU: ${MTU}" ++ return ${EXIT_ERROR} ++ fi ++ ;; ++ + --peer=*) + PEER="$(cli_get_val "${1}")" + ;; +@@ -116,6 +130,7 @@ hook_up() { + if ! device_exists "${zone}"; then + ip_tunnel_add "${zone}" \ + --mode="${MODE}" \ ++ --mtu="${MTU}" \ + --remote-address="${PEER}" \ + --local-address="${LOCAL_ADDRESS}" \ + --ikey="${MARK}" \ +-- +2.39.2 + diff --git a/network/patches/0127-firewall-Fix-generating-systemd-file.patch b/network/patches/0127-firewall-Fix-generating-systemd-file.patch new file mode 100644 index 000000000..9248fb44f --- /dev/null +++ b/network/patches/0127-firewall-Fix-generating-systemd-file.patch @@ -0,0 +1,33 @@ +From b41f1f866ef816e6ea7dd9e23e11e36a588ed611 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 23 Jun 2019 15:37:41 +0000 +Subject: [PATCH 127/304] firewall: Fix generating systemd file + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 +-- + src/systemd/{firewall.service => firewall.service.in} | 0 + 2 files changed, 1 insertion(+), 2 deletions(-) + rename src/systemd/{firewall.service => firewall.service.in} (100%) + +diff --git a/Makefile.am b/Makefile.am +index 4fe5068..78da25f 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -374,8 +374,7 @@ INSTALL_DIRS += \ + endif + + EXTRA_DIST += \ +- src/systemd/firewall4.service.in \ +- src/systemd/firewall6.service.in \ ++ src/systemd/firewall.service.in \ + src/systemd/firewall-init.service.in \ + src/systemd/network-init.service.in \ + src/systemd/network@.service.in +diff --git a/src/systemd/firewall.service b/src/systemd/firewall.service.in +similarity index 100% +rename from src/systemd/firewall.service +rename to src/systemd/firewall.service.in +-- +2.39.2 + diff --git a/network/patches/0128-Make-generating-man-pages-optional.patch b/network/patches/0128-Make-generating-man-pages-optional.patch new file mode 100644 index 000000000..1dd835994 --- /dev/null +++ b/network/patches/0128-Make-generating-man-pages-optional.patch @@ -0,0 +1,69 @@ +From dbe28a055de31302f0b8101e4e294394c6c2b63c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 21 Jun 2019 14:37:03 +0100 +Subject: [PATCH 128/304] Make generating man-pages optional + +Fixes: #11862 +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 +++- + configure.ac | 12 +++++++++++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 78da25f..b6ba5ac 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -480,11 +480,13 @@ MANPAGES_XML = $(patsubst %.txt,%.xml,$(MANPAGES_TXT)) + .PHONY: man + man: $(MANPAGES) $(MANPAGES_HTML) + ++if ENABLE_MANPAGES + man_MANS = \ + $(MANPAGES) ++endif + + CLEANFILES += \ +- $(man_MANS) \ ++ $(MANPAGES) \ + $(MANPAGES_HTML) \ + $(MANPAGES_XML) + +diff --git a/configure.ac b/configure.ac +index 340cfd6..37c17e3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -123,6 +123,14 @@ AS_IF([test "x$enable_debug" = "xyes"], [ + AC_DEFINE(ENABLE_DEBUG, [1], [Debug messages.]) + ]) + ++# ------------------------------------------------------------------------------ ++ ++have_manpages=no ++AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-man-pages], ++ [do not install man pages])) ++AS_IF([test "x$enable_manpages" != xno], [have_manpages=yes]) ++AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"]) ++ + # ------------------------------------------------------------------------------ + AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), +@@ -144,7 +152,7 @@ PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) + # ------------------------------------------------------------------------------ + + AC_CHECK_PROGS(ASCIIDOC, [asciidoc]) +-if test -z "${ASCIIDOC}"; then ++if test "${have_manpages}" = "yes" && test -z "${ASCIIDOC}"; then + AC_MSG_ERROR([Required program 'asciidoc' not found]) + fi + +@@ -167,4 +175,6 @@ AC_MSG_RESULT([ + + systemdsystemunitdir: $systemdsystemunitdir + udevdir: $udevdir ++ ++ Generate man-pages: ${have_manpages} + ]) +-- +2.39.2 + diff --git a/network/patches/0129-Add-documentation-for-the-IPsec-VPN.patch b/network/patches/0129-Add-documentation-for-the-IPsec-VPN.patch new file mode 100644 index 000000000..4cf29d53f --- /dev/null +++ b/network/patches/0129-Add-documentation-for-the-IPsec-VPN.patch @@ -0,0 +1,135 @@ +From 18bace574c15e966b8e3571cc00be287236162b5 Mon Sep 17 00:00:00 2001 +From: Jonatan Schlag +Date: Mon, 24 Jun 2019 13:30:14 +0200 +Subject: [PATCH 129/304] Add documentation for the IPsec VPN + +Signed-off-by: Jonatan Schlag +Signed-off-by: Michael Tremer +--- + man/network-vpn-ipsec.txt | 97 +++++++++++++++++++++++++++++++++++++++ + man/network-vpn.txt | 5 ++ + 2 files changed, 102 insertions(+) + create mode 100644 man/network-vpn-ipsec.txt + +diff --git a/man/network-vpn-ipsec.txt b/man/network-vpn-ipsec.txt +new file mode 100644 +index 0000000..25347a8 +--- /dev/null ++++ b/man/network-vpn-ipsec.txt +@@ -0,0 +1,97 @@ ++= network-vpn-security-policies(8) ++ ++== NAME ++network-ipsec - Configure IPsec VPN connections ++ ++== SYNOPSIS ++[verse] ++'network vpn ipsec [new|destroy]' NAME... ++'network vpn ipsec' NAME COMMAND ... ++ ++== DESCRIPTION ++With help of the 'vpn ipsec', it is possible to create, destroy ++and edit IPsec VPN connections. ++ ++ ++== COMMANDS ++The following commands are understood: ++ ++'new NAME':: ++ A new IPsec VPN connection may be created with the 'new' command. ++ + ++ NAME does not allow any spaces. ++ ++'destroy NAME':: ++ A IPsec VPN connection can be destroyed with this command. ++ ++For all other commands, the name of the IPsec VPN connection needs to be passed first: ++ ++'NAME show':: ++ Shows the configuration of the IPsec VPN connection ++ ++'NAME authentication mode':: ++ Set the authentication mode out of the following available modes: ++ * psk ++ ++'NAME authentication psk PSK':: ++ Set the pre-shared-key to PSK, only useful when the authentication mode is psk: ++ ++include::include-color.txt[] ++ ++include::include-description.txt[] ++ ++'NAME down':: ++ Shutdown a etablished IPsec VPN connection ++ ++'NAME inactivity-timeout TIME':: ++ Set the inactivity timeout with TIME in seconds or in the format hh:mm:ss ++ ++'NAME local id ID':: ++ Specify the identity of the local system. ++ + ++ The ID must be in one of the following formats: ++ * IP address ++ * FQDN ++ * a string which starts with @ ++ ++'NAME local prefix [PREFIX-LIST|+PREFIX ...|-PREFIX ...]':: ++ Specify the subnets of the local system which should be made available to the remote peer. ++ ++'NAME mode [transport|tunnel]':: ++ Set the mode of the IPsec VPN connection. ++ ++'NAME peer PEER':: ++ Set the peer to which the IPsec VPN connection should be etablished. ++ ++'NAME remote id ID':: ++ Specify the identity of the remote machine. ++ + ++ The ID must be in one of the following formats: ++ * IP address ++ * FQDN ++ * A string which starts with @ ++ ++'NAME remote prefix [PREFIX-LIST|+PREFIX ...|-PREFIX ...]':: ++ Specify the subnets which the remote side makes available to us. ++ ++'NAME security-policy':: ++ Set the security policy which the connection uses. ++ + ++ See link:network-vpn-security-policies[8] for details. ++ ++'NAME up':: ++ Establishes the IPsec VPN connection to the remote peer. ++ ++'NAME zone':: ++ When you specify a zone of type ip-tunnel here the IPsec connection is established over a vti tunnel. ++ The remote and local prefixes are ignored. Imagine a fiber connection between this two machines, and how you would use it. ++ The IPsec VPN connection works in the same way. You must configure routes and IP addresses of the ip-tunnel hook manually. ++ ++ ++== AUTHORS ++Michael Tremer, ++Jonatan Schlag ++ ++== SEE ALSO ++link:network[8], ++link:network-vpn[8] +diff --git a/man/network-vpn.txt b/man/network-vpn.txt +index 5a905db..be33606 100644 +--- a/man/network-vpn.txt ++++ b/man/network-vpn.txt +@@ -19,6 +19,11 @@ The following commands are understood: + + + See link:network-vpn-security-policies[8] for details. + ++'ipsec' ...:: ++ Use this command to manage ipsec vpn connections. ++ + ++ See link:network-vpn-ipsec[8] for details. ++ + == AUTHORS + Michael Tremer + +-- +2.39.2 + diff --git a/network/patches/0130-Makefile-Add-network-vpn-ipsec-8.patch b/network/patches/0130-Makefile-Add-network-vpn-ipsec-8.patch new file mode 100644 index 000000000..2832396ec --- /dev/null +++ b/network/patches/0130-Makefile-Add-network-vpn-ipsec-8.patch @@ -0,0 +1,25 @@ +From 2612a6f4bb0bcc3e155425a653705146eb65d7cd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Jun 2019 13:28:01 +0100 +Subject: [PATCH 130/304] Makefile: Add network-vpn-ipsec(8) + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile.am b/Makefile.am +index b6ba5ac..a5ea123 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -460,6 +460,7 @@ MANPAGES = \ + man/network-route-static.8 \ + man/network-settings.8 \ + man/network-vpn.8 \ ++ man/network-vpn-ipsec.8 \ + man/network-vpn-security-policies.8 \ + man/network-zone.8 \ + man/network-zone-bridge.8 \ +-- +2.39.2 + diff --git a/network/patches/0131-security-policies-performance-Remove-CBC-ciphers.patch b/network/patches/0131-security-policies-performance-Remove-CBC-ciphers.patch new file mode 100644 index 000000000..92b549ec4 --- /dev/null +++ b/network/patches/0131-security-policies-performance-Remove-CBC-ciphers.patch @@ -0,0 +1,23 @@ +From 2cb783babd59716366984c8908e70285f23347f3 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 24 Jun 2019 13:28:12 +0100 +Subject: [PATCH 131/304] security-policies: performance: Remove CBC ciphers + +Signed-off-by: Michael Tremer +--- + config/vpn/security-policies/performance | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/config/vpn/security-policies/performance b/config/vpn/security-policies/performance +index 9b8e943..b226d8d 100644 +--- a/config/vpn/security-policies/performance ++++ b/config/vpn/security-policies/performance +@@ -1,4 +1,4 @@ +-CIPHERS="CHACHA20-POLY1305 AES128-GCM128 AES128-CBC" ++CIPHERS="CHACHA20-POLY1305 AES128-GCM128" + COMPRESSION="off" + GROUP_TYPES="ECP521 ECP384 ECP256 ECP224 ECP192 CURVE25519" + INTEGRITIES="SHA256" +-- +2.39.2 + diff --git a/network/patches/0132-IPsec-Add-support-for-Curve448.patch b/network/patches/0132-IPsec-Add-support-for-Curve448.patch new file mode 100644 index 000000000..0238aad9a --- /dev/null +++ b/network/patches/0132-IPsec-Add-support-for-Curve448.patch @@ -0,0 +1,65 @@ +From 27208caa363cad7c2250bdff5b99a9bc16a5ca91 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 2 Oct 2019 10:36:13 +0000 +Subject: [PATCH 132/304] IPsec: Add support for Curve448 + +Signed-off-by: Michael Tremer +--- + config/vpn/security-policies/performance | 2 +- + config/vpn/security-policies/system | 2 +- + src/functions/functions.vpn-security-policies | 6 +++++- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/config/vpn/security-policies/performance b/config/vpn/security-policies/performance +index b226d8d..209f43d 100644 +--- a/config/vpn/security-policies/performance ++++ b/config/vpn/security-policies/performance +@@ -1,6 +1,6 @@ + CIPHERS="CHACHA20-POLY1305 AES128-GCM128" + COMPRESSION="off" +-GROUP_TYPES="ECP521 ECP384 ECP256 ECP224 ECP192 CURVE25519" ++GROUP_TYPES="CURVE25519 CURVE448 ECP521 ECP384 ECP256 ECP224 ECP192" + INTEGRITIES="SHA256" + PSEUDO_RANDOM_FUNCTIONS="SHA256" + KEY_EXCHANGE="ikev2" +diff --git a/config/vpn/security-policies/system b/config/vpn/security-policies/system +index db30e69..6ceb0c4 100644 +--- a/config/vpn/security-policies/system ++++ b/config/vpn/security-policies/system +@@ -1,7 +1,7 @@ + KEY_EXCHANGE="ikev2" + CIPHERS="CHACHA20-POLY1305 AES256-GCM128 AES256-CBC AES192-GCM128 AES192-CBC AES128-GCM128 AES128-CBC" + INTEGRITIES="SHA512 SHA384 SHA256" +-GROUP_TYPES="CURVE25519 ECP521 ECP384 ECP256 ECP224 ECP192 MODP8192 MODP6144 MODP4096 MODP2048" ++GROUP_TYPES="CURVE25519 CURVE448 ECP521 ECP384 ECP256 ECP224 ECP192 MODP8192 MODP6144 MODP4096 MODP2048" + PSEUDO_RANDOM_FUNCTIONS="SHA512 SHA384 SHA256" + LIFETIME="28800" + PFS="on" +diff --git a/src/functions/functions.vpn-security-policies b/src/functions/functions.vpn-security-policies +index d1d720b..138e821 100644 +--- a/src/functions/functions.vpn-security-policies ++++ b/src/functions/functions.vpn-security-policies +@@ -263,6 +263,9 @@ declare -A VPN_SUPPORTED_GROUP_TYPES=( + + # Curve25519 + [CURVE25519]="256 bit Elliptic Curve 25519" ++ ++ # Curve448 ++ [CURVE448]="224 bit Elliptic Curve 448" + ) + + declare -A GROUP_TYPE_TO_STRONGSWAN=( +@@ -289,8 +292,9 @@ declare -A GROUP_TYPE_TO_STRONGSWAN=( + [ECP384BP]="ecp384bp" + [ECP512BP]="ecp512bp" + +- # Curve25519 ++ # More Curves + [CURVE25519]="curve25519" ++ [CURVE448]="curve448" + ) + + cli_vpn_security_policies() { +-- +2.39.2 + diff --git a/network/patches/0133-Disable-copybreak.patch b/network/patches/0133-Disable-copybreak.patch new file mode 100644 index 000000000..c1294c8fb --- /dev/null +++ b/network/patches/0133-Disable-copybreak.patch @@ -0,0 +1,112 @@ +From ea4abb82bc6e613ddebd6235f792dd5bbbc469c9 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 7 May 2020 20:30:03 +0100 +Subject: [PATCH 133/304] Disable copybreak + +Some network interface drivers employ a scheme known as "copybreak" +in which they make a copy of a received skb if the size of the +buffer is below a particular threshold, then return the original +receive skb back to the pool. Since these drivers initially +allocate a buffer size that is larger than the largest possible +packet, this scheme returns that large buffer to the pool quickly, +and uses a smaller one. + +The primary benefit of copybreak is better memory utilization. On +systems where the data is ultimately going to be copied out to user +space, the copybreak scheme is "low cost" because it has the side +benefit of priming the cache for that later copy. But on a router +that only touches the header fields of a received packet, the cost +can be relatively higher. And on modern systems the memory savings +is rarely an important consideration. + +Some of the drivers that employ copybreak make the feature +configurable via a module parameter. This file disables copybreak +in some of those drivers. Generally this results in an improvement +in forwarding performance for traffic using these drivers. + +Fixes: #11930 +Signed-off-by: Michael Tremer +Signed-off-by: Arne Fitzenreiter +--- + Makefile.am | 6 +++++ + src/modprobe.d/no-copybreak.conf | 44 ++++++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + create mode 100644 src/modprobe.d/no-copybreak.conf + +diff --git a/Makefile.am b/Makefile.am +index a5ea123..4aa7314 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -31,6 +31,7 @@ AUTOMAKE_OPTIONS = color-tests + configdir = $(sysconfdir)/network + bashcompletiondir= $(datadir)/bash-completion/completions + libexecdir = $(prefix)/lib ++modprobedir = $(prefix)/lib/modprobe.d + pkgconfigdir = $(libdir)/pkgconfig + pppdir = $(sysconfdir)/ppp + systemconfigdir = $(datadir)/network +@@ -396,6 +397,11 @@ dist_sysctl_DATA = \ + + # ------------------------------------------------------------------------------ + ++dist_modprobe_DATA = \ ++ src/modprobe.d/no-copybreak.conf ++ ++# ------------------------------------------------------------------------------ ++ + dist_bashcompletion_SCRIPTS = \ + src/bash-completion/network + +diff --git a/src/modprobe.d/no-copybreak.conf b/src/modprobe.d/no-copybreak.conf +new file mode 100644 +index 0000000..97ea886 +--- /dev/null ++++ b/src/modprobe.d/no-copybreak.conf +@@ -0,0 +1,44 @@ ++# ++# Some network interface drivers employ a scheme known as "copybreak" ++# in which they make a copy of a received skb if the size of the ++# buffer is below a particular threshold, then return the original ++# receive skb back to the pool. Since these drivers initially ++# allocate a buffer size that is larger than the largest possible ++# packet, this scheme returns that large buffer to the pool quickly, ++# and uses a smaller one. ++# ++# The primary benefit of copybreak is better memory utilization. On ++# systems where the data is ultimately going to be copied out to user ++# space, the copybreak scheme is "low cost" because it has the side ++# benefit of priming the cache for that later copy. But on a router ++# that only touches the header fields of a received packet, the cost ++# can be relatively higher. And on modern systems the memory savings ++# is rarely an important consideration. ++# ++# Some of the drivers that employ copybreak make the feature ++# configurable via a module parameter. This file disables copybreak ++# in some of those drivers. Generally this results in an improvement ++# in forwarding performance for traffic using these drivers. ++# ++ ++options 3c515 rx_copybreak=0 ++options 3c59x rx_copybreak=0 ++options bcm63xx copybreak=0 ++options cxgb copybreak=0 ++options e1000 copybreak=0 ++options e1000e copybreak=0 ++options epic100 rx_copybreak=0 ++options fealnx rx_copybreak=0 ++options hamachi rx_copybreak=0 ++options ixgb copybreak=0 ++options natsemi rx_copybreak=0 ++options pch_gbe copybreak=0 ++options pcnet32 rx_copybreak=0 ++options sis190 rx_copybreak=0 ++options sky2 copybreak=0 ++options starfire rx_copybreak=0 ++options sundance rx_copybreak=0 ++options typhoon rx_copybreak=0 ++options via-rhine rx_copybreak=0 ++options via-velocity rx_copybreak=0 ++options yellowfin rx_copybreak=0 +-- +2.39.2 + diff --git a/network/patches/0134-configure-Check-for-libsystemd.patch b/network/patches/0134-configure-Check-for-libsystemd.patch new file mode 100644 index 000000000..c47bd0bb8 --- /dev/null +++ b/network/patches/0134-configure-Check-for-libsystemd.patch @@ -0,0 +1,25 @@ +From ed993fc9d436da0788eca6f80374c9cd85b8bb9b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 22 Jan 2023 12:33:11 +0000 +Subject: [PATCH 134/304] configure: Check for libsystemd + +Signed-off-by: Michael Tremer +--- + configure.ac | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configure.ac b/configure.ac +index 37c17e3..f3a9c17 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -148,6 +148,7 @@ AM_CONDITIONAL(HAVE_UDEV, [test -n "$with_udevdir"]) + # ------------------------------------------------------------------------------ + + PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) ++PKG_CHECK_MODULES([SYSTEMD], [libsystemd]) + + # ------------------------------------------------------------------------------ + +-- +2.39.2 + diff --git a/network/patches/0135-Makefile-Add-scaffolding-for-networkd.patch b/network/patches/0135-Makefile-Add-scaffolding-for-networkd.patch new file mode 100644 index 000000000..1f716ffae --- /dev/null +++ b/network/patches/0135-Makefile-Add-scaffolding-for-networkd.patch @@ -0,0 +1,93 @@ +From 050f4ece8900b9212de57b3564381d82540323aa Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 22 Jan 2023 12:41:47 +0000 +Subject: [PATCH 135/304] Makefile: Add scaffolding for networkd + +Signed-off-by: Michael Tremer +--- + .gitignore | 1 + + Makefile.am | 18 ++++++++++++++++++ + src/networkd/main.c | 23 +++++++++++++++++++++++ + 3 files changed, 42 insertions(+) + create mode 100644 src/networkd/main.c + +diff --git a/.gitignore b/.gitignore +index bb093d3..e3bae67 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -3,6 +3,7 @@ + /config.* + /libtool + /missing ++/networkd + /src/functions/functions + /src/inetcalc + /src/libnetwork/libnetwork.pc +diff --git a/Makefile.am b/Makefile.am +index 4aa7314..64ad94d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -61,6 +61,7 @@ INSTALL_DIRS = + INSTALL_EXEC_HOOKS = + UNINSTALL_EXEC_HOOKS = + noinst_DATA = ++sbin_PROGRAMS = + + AM_CPPFLAGS = \ + $(OUR_CPPFLAGS) \ +@@ -299,6 +300,23 @@ EXTRA_DIST += \ + + # ------------------------------------------------------------------------------ + ++sbin_PROGRAMS += \ ++ networkd ++ ++dist_networkd_SOURCES = \ ++ src/networkd/main.c ++ ++networkd_CPPFLAGS = \ ++ $(AM_CPPFLAGS) ++ ++networkd_CFLAGS = \ ++ $(AM_CFLAGS) ++ ++networkd_LDFLAGS = \ ++ $(AM_LDFLAGS) ++ ++# ------------------------------------------------------------------------------ ++ + util_PROGRAMS = \ + src/utils/network-phy-list-channels \ + src/utils/network-phy-list-ciphers \ +diff --git a/src/networkd/main.c b/src/networkd/main.c +new file mode 100644 +index 0000000..14aafdd +--- /dev/null ++++ b/src/networkd/main.c +@@ -0,0 +1,23 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++int main(int argc, char** argv) { ++ return 0; ++} +-- +2.39.2 + diff --git a/network/patches/0136-networkd-Link-against-systemd.patch b/network/patches/0136-networkd-Link-against-systemd.patch new file mode 100644 index 000000000..0ff8ce40e --- /dev/null +++ b/network/patches/0136-networkd-Link-against-systemd.patch @@ -0,0 +1,34 @@ +From 5d326bbb3f564cdb7031d80850bd3fe3c7565233 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:18:34 +0000 +Subject: [PATCH 136/304] networkd: Link against systemd + +Signed-off-by: Michael Tremer +--- + Makefile.am | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 64ad94d..74b2fae 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -310,11 +310,15 @@ networkd_CPPFLAGS = \ + $(AM_CPPFLAGS) + + networkd_CFLAGS = \ +- $(AM_CFLAGS) ++ $(AM_CFLAGS) \ ++ $(SYSTEMD_CFLAGS) + + networkd_LDFLAGS = \ + $(AM_LDFLAGS) + ++networkd_LDADD = \ ++ $(SYSTEMD_LIBS) ++ + # ------------------------------------------------------------------------------ + + util_PROGRAMS = \ +-- +2.39.2 + diff --git a/network/patches/0137-networkd-Tell-systemd-about-the-daemon-status.patch b/network/patches/0137-networkd-Tell-systemd-about-the-daemon-status.patch new file mode 100644 index 000000000..005bffe4b --- /dev/null +++ b/network/patches/0137-networkd-Tell-systemd-about-the-daemon-status.patch @@ -0,0 +1,47 @@ +From 26acbb4e03e3a44e6046884eab25f6c7e376c105 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:18:53 +0000 +Subject: [PATCH 137/304] networkd: Tell systemd about the daemon status + +Signed-off-by: Michael Tremer +--- + src/networkd/main.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 14aafdd..2429ff5 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -18,6 +18,28 @@ + # # + #############################################################################*/ + ++#include ++#include ++ ++#include ++#include ++ + int main(int argc, char** argv) { +- return 0; ++ // XXX Drop privileges ++ ++ // We are now ready to process any requests ++ sd_notify(0, "READY=1\n" "STATUS=Processing requests..."); ++ ++ // Run event loop ++ // XXX TODO ++ ++ // Let systemd know that we are shutting down ++ sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); ++ ++ return EXIT_SUCCESS; ++ ++ERROR: ++ sd_notifyf(0, "ERRNO=%i", errno); ++ ++ return EXIT_FAILURE; + } +-- +2.39.2 + diff --git a/network/patches/0138-networkd-Create-a-simple-daemon-class.patch b/network/patches/0138-networkd-Create-a-simple-daemon-class.patch new file mode 100644 index 000000000..0ac30e734 --- /dev/null +++ b/network/patches/0138-networkd-Create-a-simple-daemon-class.patch @@ -0,0 +1,170 @@ +From 112358f3e2d40e148a259b1a7ab466c99947ed4b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:29:09 +0000 +Subject: [PATCH 138/304] networkd: Create a simple daemon class + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/daemon.c | 56 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/daemon.h | 31 ++++++++++++++++++++++++ + src/networkd/main.c | 16 ++++++++++++- + 4 files changed, 104 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/daemon.c + create mode 100644 src/networkd/daemon.h + +diff --git a/Makefile.am b/Makefile.am +index 74b2fae..40d900e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -304,6 +304,8 @@ sbin_PROGRAMS += \ + networkd + + dist_networkd_SOURCES = \ ++ src/networkd/daemon.c \ ++ src/networkd/daemon.h \ + src/networkd/main.c + + networkd_CPPFLAGS = \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +new file mode 100644 +index 0000000..f635f38 +--- /dev/null ++++ b/src/networkd/daemon.c +@@ -0,0 +1,56 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "daemon.h" ++ ++struct nw_daemon { ++ int nrefs; ++}; ++ ++int nw_daemon_create(struct nw_daemon** daemon) { ++ struct nw_daemon* d = calloc(1, sizeof(*d)); ++ if (!d) ++ return 1; ++ ++ // Initialize reference counter ++ d->nrefs = 1; ++ ++ return 0; ++} ++ ++static void nw_daemon_free(struct nw_daemon* daemon) { ++ free(daemon); ++} ++ ++struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon) { ++ daemon->nrefs++; ++ ++ return daemon; ++} ++ ++struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon) { ++ if (--daemon->nrefs > 0) ++ return daemon; ++ ++ nw_daemon_free(daemon); ++ return NULL; ++} +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +new file mode 100644 +index 0000000..309794e +--- /dev/null ++++ b/src/networkd/daemon.h +@@ -0,0 +1,31 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_DAEMON_H ++#define NETWORKD_DAEMON_H ++ ++struct nw_daemon; ++ ++int nw_daemon_create(struct nw_daemon** daemon); ++ ++struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon); ++struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon); ++ ++#endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 2429ff5..48fb2ae 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -24,9 +24,19 @@ + #include + #include + ++#include "daemon.h" ++ + int main(int argc, char** argv) { ++ struct nw_daemon* daemon = NULL; ++ int r; ++ + // XXX Drop privileges + ++ // Create the daemon ++ r = nw_daemon_create(&daemon); ++ if (r) ++ goto ERROR; ++ + // We are now ready to process any requests + sd_notify(0, "READY=1\n" "STATUS=Processing requests..."); + +@@ -36,10 +46,14 @@ int main(int argc, char** argv) { + // Let systemd know that we are shutting down + sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); + +- return EXIT_SUCCESS; ++ goto CLEANUP; + + ERROR: + sd_notifyf(0, "ERRNO=%i", errno); + ++CLEANUP: ++ if (daemon) ++ nw_daemon_unref(daemon); ++ + return EXIT_FAILURE; + } +-- +2.39.2 + diff --git a/network/patches/0139-networkd-Create-an-event-loop.patch b/network/patches/0139-networkd-Create-an-event-loop.patch new file mode 100644 index 000000000..aa45d9f2d --- /dev/null +++ b/network/patches/0139-networkd-Create-an-event-loop.patch @@ -0,0 +1,147 @@ +From c7e1b5db6903099797cf700516706a827ae9cc3e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:49:22 +0000 +Subject: [PATCH 139/304] networkd: Create an event loop + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 63 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/daemon.h | 2 ++ + src/networkd/main.c | 7 ++--- + 3 files changed, 69 insertions(+), 3 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index f635f38..25fdbdb 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -20,13 +20,44 @@ + + #include + ++#include ++ + #include "daemon.h" + + struct nw_daemon { + int nrefs; ++ ++ // Event Loop ++ sd_event* loop; + }; + ++static int nw_daemon_setup_loop(struct nw_daemon* daemon) { ++ int r; ++ ++ // Fetch a reference to the default event loop ++ r = sd_event_default(&daemon->loop); ++ if (r < 0) { ++ //ERROR("Could not setup event loop: %m\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int nw_daemon_setup(struct nw_daemon* daemon) { ++ int r; ++ ++ // Setup the event loop ++ r = nw_daemon_setup_loop(daemon); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + int nw_daemon_create(struct nw_daemon** daemon) { ++ int r; ++ + struct nw_daemon* d = calloc(1, sizeof(*d)); + if (!d) + return 1; +@@ -34,10 +65,26 @@ int nw_daemon_create(struct nw_daemon** daemon) { + // Initialize reference counter + d->nrefs = 1; + ++ // Setup the daemon ++ r = nw_daemon_setup(d); ++ if (r) ++ goto ERROR; ++ ++ // Set the reference ++ *daemon = d; ++ + return 0; ++ ++ERROR: ++ nw_daemon_unref(d); ++ ++ return r; + } + + static void nw_daemon_free(struct nw_daemon* daemon) { ++ if (daemon->loop) ++ sd_event_unref(daemon->loop); ++ + free(daemon); + } + +@@ -54,3 +101,19 @@ struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon) { + nw_daemon_free(daemon); + return NULL; + } ++ ++/* ++ This function contains the main loop of the daemon... ++*/ ++int nw_daemon_run(struct nw_daemon* daemon) { ++ int r; ++ ++ // Launch the event loop ++ r = sd_event_loop(daemon->loop); ++ if (r) { ++ //ERROR("Could not run the event loop: %m\n"); ++ return r; ++ } ++ ++ return 0; ++} +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 309794e..215972d 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -28,4 +28,6 @@ int nw_daemon_create(struct nw_daemon** daemon); + struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon); + struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon); + ++int nw_daemon_run(struct nw_daemon* daemon); ++ + #endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 48fb2ae..80123ad 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -22,7 +22,6 @@ + #include + + #include +-#include + + #include "daemon.h" + +@@ -40,8 +39,10 @@ int main(int argc, char** argv) { + // We are now ready to process any requests + sd_notify(0, "READY=1\n" "STATUS=Processing requests..."); + +- // Run event loop +- // XXX TODO ++ // Run the daemon ++ r = nw_daemon_run(daemon); ++ if (r) ++ goto ERROR; + + // Let systemd know that we are shutting down + sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); +-- +2.39.2 + diff --git a/network/patches/0140-networkd-Enable-the-service-watchdog.patch b/network/patches/0140-networkd-Enable-the-service-watchdog.patch new file mode 100644 index 000000000..6371661fe --- /dev/null +++ b/network/patches/0140-networkd-Enable-the-service-watchdog.patch @@ -0,0 +1,31 @@ +From 3b2316e448ad4353964779b4c31edfe20b96ea4f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:53:19 +0000 +Subject: [PATCH 140/304] networkd: Enable the service watchdog + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 25fdbdb..c6acefe 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -41,6 +41,13 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + return 1; + } + ++ // Enable the watchdog ++ r = sd_event_set_watchdog(daemon->loop, 1); ++ if (r < 0) { ++ //ERROR("Could not activate watchdog: %m\n"); ++ return 1; ++ } ++ + return 0; + } + +-- +2.39.2 + diff --git a/network/patches/0141-networkd-Add-some-very-simple-logging.patch b/network/patches/0141-networkd-Add-some-very-simple-logging.patch new file mode 100644 index 000000000..e7e9ecb9a --- /dev/null +++ b/network/patches/0141-networkd-Add-some-very-simple-logging.patch @@ -0,0 +1,104 @@ +From c251a9ddf0771b85af69f226e886bdd511e2353d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 21:57:32 +0000 +Subject: [PATCH 141/304] networkd: Add some very simple logging + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + src/networkd/daemon.c | 7 ++++--- + src/networkd/logging.h | 32 ++++++++++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 3 deletions(-) + create mode 100644 src/networkd/logging.h + +diff --git a/Makefile.am b/Makefile.am +index 40d900e..abba646 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -306,6 +306,7 @@ sbin_PROGRAMS += \ + dist_networkd_SOURCES = \ + src/networkd/daemon.c \ + src/networkd/daemon.h \ ++ src/networkd/logging.h \ + src/networkd/main.c + + networkd_CPPFLAGS = \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index c6acefe..4d21bb6 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -23,6 +23,7 @@ + #include + + #include "daemon.h" ++#include "logging.h" + + struct nw_daemon { + int nrefs; +@@ -37,14 +38,14 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + // Fetch a reference to the default event loop + r = sd_event_default(&daemon->loop); + if (r < 0) { +- //ERROR("Could not setup event loop: %m\n"); ++ ERROR("Could not setup event loop: %m\n"); + return 1; + } + + // Enable the watchdog + r = sd_event_set_watchdog(daemon->loop, 1); + if (r < 0) { +- //ERROR("Could not activate watchdog: %m\n"); ++ ERROR("Could not activate watchdog: %m\n"); + return 1; + } + +@@ -118,7 +119,7 @@ int nw_daemon_run(struct nw_daemon* daemon) { + // Launch the event loop + r = sd_event_loop(daemon->loop); + if (r) { +- //ERROR("Could not run the event loop: %m\n"); ++ ERROR("Could not run the event loop: %m\n"); + return r; + } + +diff --git a/src/networkd/logging.h b/src/networkd/logging.h +new file mode 100644 +index 0000000..9d51f21 +--- /dev/null ++++ b/src/networkd/logging.h +@@ -0,0 +1,32 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_LOGGING_H ++#define NETWORKD_LOGGING_H ++ ++#include ++ ++/* ++ This is just something simple which will work for now... ++*/ ++#define ERROR(...) fprintf(stderr, __VA_ARGS__) ++#define DEBUG(...) printf(__VA_ARGS__) ++ ++#endif /* NETWORKD_LOGGING_H */ +-- +2.39.2 + diff --git a/network/patches/0142-networkd-Register-SIGTERM-SIGINT-SIGHUP.patch b/network/patches/0142-networkd-Register-SIGTERM-SIGINT-SIGHUP.patch new file mode 100644 index 000000000..61ba97e7c --- /dev/null +++ b/network/patches/0142-networkd-Register-SIGTERM-SIGINT-SIGHUP.patch @@ -0,0 +1,90 @@ +From 025f60f1f2f22db43edd4bb52b6cff48ceb718a0 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 22:24:53 +0000 +Subject: [PATCH 142/304] networkd: Register SIGTERM/SIGINT/SIGHUP + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 46 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 44 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 4d21bb6..483252d 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -18,7 +18,9 @@ + # # + #############################################################################*/ + ++#include + #include ++#include + + #include + +@@ -32,20 +34,60 @@ struct nw_daemon { + sd_event* loop; + }; + ++static int nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, ++ void* data) { ++ DEBUG("Received signal to terminate...\n"); ++ ++ return sd_event_exit(sd_event_source_get_event(source), 0); ++} ++ ++static int nw_daemon_reload(sd_event_source* source, const struct signalfd_siginfo* si, ++ void* data) { ++ DEBUG("Received signal to reload...\n"); ++ ++ // TODO ++ ++ return 0; ++} ++ + static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + int r; + + // Fetch a reference to the default event loop + r = sd_event_default(&daemon->loop); + if (r < 0) { +- ERROR("Could not setup event loop: %m\n"); ++ ERROR("Could not setup event loop: %s\n", strerror(-r)); + return 1; + } + + // Enable the watchdog + r = sd_event_set_watchdog(daemon->loop, 1); + if (r < 0) { +- ERROR("Could not activate watchdog: %m\n"); ++ ERROR("Could not activate watchdog: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Listen for SIGTERM ++ r = sd_event_add_signal(daemon->loop, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, ++ nw_daemon_terminate, daemon); ++ if (r < 0) { ++ ERROR("Could not register handling SIGTERM: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Listen for SIGINT ++ r = sd_event_add_signal(daemon->loop, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, ++ nw_daemon_terminate, daemon); ++ if (r < 0) { ++ ERROR("Could not register handling SIGINT: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Listen for SIGHUP ++ r = sd_event_add_signal(daemon->loop, NULL, SIGHUP|SD_EVENT_SIGNAL_PROCMASK, ++ nw_daemon_reload, daemon); ++ if (r < 0) { ++ ERROR("Could not register handling SIGHUP: %s\n", strerror(-r)); + return 1; + } + +-- +2.39.2 + diff --git a/network/patches/0143-networkd-Add-scaffolding-to-reload-the-daemon.patch b/network/patches/0143-networkd-Add-scaffolding-to-reload-the-daemon.patch new file mode 100644 index 000000000..e83dae62c --- /dev/null +++ b/network/patches/0143-networkd-Add-scaffolding-to-reload-the-daemon.patch @@ -0,0 +1,93 @@ +From 27a3a5969dcc76cc7af7b0dd491703ee2c8baa70 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 22:29:05 +0000 +Subject: [PATCH 143/304] networkd: Add scaffolding to reload the daemon + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 23 +++++++++++++++++------ + src/networkd/daemon.h | 2 ++ + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 483252d..98fb5bd 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -34,18 +34,21 @@ struct nw_daemon { + sd_event* loop; + }; + +-static int nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, ++static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, + void* data) { + DEBUG("Received signal to terminate...\n"); + + return sd_event_exit(sd_event_source_get_event(source), 0); + } + +-static int nw_daemon_reload(sd_event_source* source, const struct signalfd_siginfo* si, ++static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_siginfo* si, + void* data) { ++ struct nw_daemon* daemon = (struct nw_daemon*)daemon; ++ + DEBUG("Received signal to reload...\n"); + +- // TODO ++ // Reload the daemon ++ nw_daemon_reload(daemon); + + return 0; + } +@@ -69,7 +72,7 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + + // Listen for SIGTERM + r = sd_event_add_signal(daemon->loop, NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, +- nw_daemon_terminate, daemon); ++ __nw_daemon_terminate, daemon); + if (r < 0) { + ERROR("Could not register handling SIGTERM: %s\n", strerror(-r)); + return 1; +@@ -77,7 +80,7 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + + // Listen for SIGINT + r = sd_event_add_signal(daemon->loop, NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, +- nw_daemon_terminate, daemon); ++ __nw_daemon_terminate, daemon); + if (r < 0) { + ERROR("Could not register handling SIGINT: %s\n", strerror(-r)); + return 1; +@@ -85,7 +88,7 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + + // Listen for SIGHUP + r = sd_event_add_signal(daemon->loop, NULL, SIGHUP|SD_EVENT_SIGNAL_PROCMASK, +- nw_daemon_reload, daemon); ++ __nw_daemon_reload, daemon); + if (r < 0) { + ERROR("Could not register handling SIGHUP: %s\n", strerror(-r)); + return 1; +@@ -167,3 +170,11 @@ int nw_daemon_run(struct nw_daemon* daemon) { + + return 0; + } ++ ++int nw_daemon_reload(struct nw_daemon* daemon) { ++ DEBUG("Reloading daemon...\n"); ++ ++ // XXX TODO ++ ++ return 0; ++} +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 215972d..5b14ef3 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -30,4 +30,6 @@ struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon); + + int nw_daemon_run(struct nw_daemon* daemon); + ++int nw_daemon_reload(struct nw_daemon* daemon); ++ + #endif /* NETWORKD_DAEMON_H */ +-- +2.39.2 + diff --git a/network/patches/0144-configure-Enable-system-extensions-to-define-_GNU_SO.patch b/network/patches/0144-configure-Enable-system-extensions-to-define-_GNU_SO.patch new file mode 100644 index 000000000..ced811542 --- /dev/null +++ b/network/patches/0144-configure-Enable-system-extensions-to-define-_GNU_SO.patch @@ -0,0 +1,27 @@ +From 374d06ada7c1a3381aa08496abc7c9f173fd8d2f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 29 Jan 2023 22:52:37 +0000 +Subject: [PATCH 144/304] configure: Enable system extensions to define + _GNU_SOURCE + +Signed-off-by: Michael Tremer +--- + configure.ac | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/configure.ac b/configure.ac +index f3a9c17..b820794 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -65,6 +65,8 @@ AC_PROG_CC_C99 + AC_PROG_CC_C_O + AC_PROG_GCC_TRADITIONAL + ++AC_USE_SYSTEM_EXTENSIONS ++ + CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ + -pipe \ + -Wall \ +-- +2.39.2 + diff --git a/network/patches/0145-networkd-Add-scaffolding-to-connect-to-dbus.patch b/network/patches/0145-networkd-Add-scaffolding-to-connect-to-dbus.patch new file mode 100644 index 000000000..d7729101a --- /dev/null +++ b/network/patches/0145-networkd-Add-scaffolding-to-connect-to-dbus.patch @@ -0,0 +1,255 @@ +From 09a6af1750714828bf109e17882ac0e7d0a6c738 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 02:08:50 +0000 +Subject: [PATCH 145/304] networkd: Add scaffolding to connect to dbus + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/bus.c | 131 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/bus.h | 35 +++++++++++ + src/networkd/daemon.c | 12 ++++ + 4 files changed, 180 insertions(+) + create mode 100644 src/networkd/bus.c + create mode 100644 src/networkd/bus.h + +diff --git a/Makefile.am b/Makefile.am +index abba646..60a1bcd 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -304,6 +304,8 @@ sbin_PROGRAMS += \ + networkd + + dist_networkd_SOURCES = \ ++ src/networkd/bus.c \ ++ src/networkd/bus.h \ + src/networkd/daemon.c \ + src/networkd/daemon.h \ + src/networkd/logging.h \ +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +new file mode 100644 +index 0000000..95862d2 +--- /dev/null ++++ b/src/networkd/bus.c +@@ -0,0 +1,131 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include "bus.h" ++#include "daemon.h" ++#include "logging.h" ++ ++static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* ret_error) { ++ return 1; ++} ++ ++static const sd_bus_vtable daemon_vtable[] = { ++ SD_BUS_VTABLE_START(0), ++ SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, ++ nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_VTABLE_END, ++}; ++ ++int nw_bus_connect(sd_bus* bus, sd_event* loop) { ++ int r; ++ ++ // Create a bus object ++ r = sd_bus_new(&bus); ++ if (r < 0) { ++ ERROR("Could not allocate a bus object: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Set description ++ r = sd_bus_set_description(bus, NETWORKD_BUS_DESCRIPTION); ++ if (r < 0) { ++ ERROR("Could not set bus description: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ const char* address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); ++ if (!address) ++ address = DEFAULT_SYSTEM_BUS_ADDRESS; ++ ++ // Set bus address ++ r = sd_bus_set_address(bus, address); ++ if (r < 0) { ++ ERROR("Could not set bus address: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Set bus client ++ r = sd_bus_set_bus_client(bus, 1); ++ if (r < 0) { ++ ERROR("Could not set bus client: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Request some credentials for all messages ++ r = sd_bus_negotiate_creds(bus, 1, ++ SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); ++ if (r < 0) { ++ ERROR("Could not negotiate creds: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Automatically bind when the socket is available ++ r = sd_bus_set_watch_bind(bus, 1); ++ if (r < 0) { ++ ERROR("Could not watch socket: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Emit a connected signal when we are connected ++ r = sd_bus_set_connected_signal(bus, 1); ++ if (r < 0) { ++ ERROR("Could not enable sending a connect signal: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Connect to the bus ++ r = sd_bus_start(bus); ++ if (r < 0) { ++ ERROR("Could not connect to bus: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Register any functions ++ r = sd_bus_add_object_vtable(bus, NULL, ++ NETWORKD_BUS_OBJECT_PATH, NETWORKD_BUS_INTERFACE_NAME, daemon_vtable, NULL); ++ if (r < 0) { ++ ERROR("Could not add object vtable: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Request interface name ++ // XXX Should this be async? ++ // XXX How do we get the actual error message from dbus? ++ r = sd_bus_request_name(bus, NETWORKD_BUS_INTERFACE_NAME, 0); ++ if (r < 0) { ++ ERROR("Could not request bus name: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ // Attach the event loop ++ r = sd_bus_attach_event(bus, loop, 0); ++ if (r < 0) { ++ ERROR("Could not attach bus to event loop: %s\n", strerror(-r)); ++ return 1; ++ } ++ ++ return 0; ++} +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +new file mode 100644 +index 0000000..90c1556 +--- /dev/null ++++ b/src/networkd/bus.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_BUS_H ++#define NETWORKD_BUS_H ++ ++#define NETWORKD_BUS_DESCRIPTION "networkd" ++#define NETWORKD_BUS_OBJECT_PATH "/org/ipfire/network1" ++#define NETWORKD_BUS_INTERFACE_NAME "org.ipfire.network1" ++ ++#define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket" ++ ++#include ++#include ++ ++int nw_bus_connect(sd_bus* bus, sd_event* loop); ++ ++#endif /* NETWORKD_BUS_H */ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 98fb5bd..3aee8ca 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -22,8 +22,10 @@ + #include + #include + ++#include + #include + ++#include "bus.h" + #include "daemon.h" + #include "logging.h" + +@@ -32,6 +34,9 @@ struct nw_daemon { + + // Event Loop + sd_event* loop; ++ ++ // DBus Connection ++ sd_bus* bus; + }; + + static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, +@@ -105,6 +110,11 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Connect to the system bus ++ r = nw_bus_connect(daemon->bus, daemon->loop); ++ if (r) ++ return r; ++ + return 0; + } + +@@ -135,6 +145,8 @@ ERROR: + } + + static void nw_daemon_free(struct nw_daemon* daemon) { ++ if (daemon->bus) ++ sd_bus_unref(daemon->bus); + if (daemon->loop) + sd_event_unref(daemon->loop); + +-- +2.39.2 + diff --git a/network/patches/0146-networkd-Add-scaffolding-for-config-objects.patch b/network/patches/0146-networkd-Add-scaffolding-for-config-objects.patch new file mode 100644 index 000000000..c50840ce3 --- /dev/null +++ b/network/patches/0146-networkd-Add-scaffolding-for-config-objects.patch @@ -0,0 +1,131 @@ +From 6b666d6221c5797f78fa4942561c931609d8f656 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 02:16:06 +0000 +Subject: [PATCH 146/304] networkd: Add scaffolding for config objects + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/config.c | 58 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/config.h | 31 +++++++++++++++++++++++ + 3 files changed, 91 insertions(+) + create mode 100644 src/networkd/config.c + create mode 100644 src/networkd/config.h + +diff --git a/Makefile.am b/Makefile.am +index 60a1bcd..50a6034 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -306,6 +306,8 @@ sbin_PROGRAMS += \ + dist_networkd_SOURCES = \ + src/networkd/bus.c \ + src/networkd/bus.h \ ++ src/networkd/config.c \ ++ src/networkd/config.h \ + src/networkd/daemon.c \ + src/networkd/daemon.h \ + src/networkd/logging.h \ +diff --git a/src/networkd/config.c b/src/networkd/config.c +new file mode 100644 +index 0000000..d18fb12 +--- /dev/null ++++ b/src/networkd/config.c +@@ -0,0 +1,58 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "config.h" ++ ++struct nw_config { ++ int nrefs; ++}; ++ ++static void nw_config_free(struct nw_config* config) { ++ free(config); ++} ++ ++int nw_config_create(struct nw_config** config) { ++ struct nw_config* c = calloc(1, sizeof(*c)); ++ if (!c) ++ return 1; ++ ++ // Initialize reference counter ++ c->nrefs = 1; ++ ++ *config = c; ++ ++ return 0; ++} ++ ++struct nw_config* nw_config_ref(struct nw_config* config) { ++ config->nrefs++; ++ ++ return config; ++} ++ ++struct nw_config* nw_config_unref(struct nw_config* config) { ++ if (--config->nrefs > 0) ++ return config; ++ ++ nw_config_free(config); ++ return NULL; ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +new file mode 100644 +index 0000000..a8aed7f +--- /dev/null ++++ b/src/networkd/config.h +@@ -0,0 +1,31 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_CONFIG_H ++#define NETWORKD_CONFIG_H ++ ++struct nw_config; ++ ++int nw_config_create(struct nw_config** config); ++ ++struct nw_config* nw_config_ref(struct nw_config* config); ++struct nw_config* nw_config_unref(struct nw_config* config); ++ ++#endif /* NETWORKD_CONFIG_H */ +-- +2.39.2 + diff --git a/network/patches/0147-networkd-Add-scaffolding-to-read-configuration-files.patch b/network/patches/0147-networkd-Add-scaffolding-to-read-configuration-files.patch new file mode 100644 index 000000000..18b7e2aa7 --- /dev/null +++ b/network/patches/0147-networkd-Add-scaffolding-to-read-configuration-files.patch @@ -0,0 +1,94 @@ +From c81a6335fd0e1912fa3e8268ba85b9cd048cf243 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 02:26:41 +0000 +Subject: [PATCH 147/304] networkd: Add scaffolding to read configuration files + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 50 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/config.h | 3 +++ + 2 files changed, 53 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index d18fb12..e808531 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -18,9 +18,11 @@ + # # + #############################################################################*/ + ++#include + #include + + #include "config.h" ++#include "logging.h" + + struct nw_config { + int nrefs; +@@ -56,3 +58,51 @@ struct nw_config* nw_config_unref(struct nw_config* config) { + nw_config_free(config); + return NULL; + } ++ ++static int nw_config_parse(struct nw_config* config, FILE* f) { ++ // XXX TODO ++ ++ return 0; ++} ++ ++int nw_config_readf(struct nw_config** config, FILE* f) { ++ int r; ++ ++ // Create a new config object ++ r = nw_config_create(config); ++ if (r) ++ return r; ++ ++ // Parse the configuration ++ r = nw_config_parse(*config, f); ++ if (r) ++ goto ERROR; ++ ++ return 0; ++ ++ERROR: ++ nw_config_free(*config); ++ return r; ++} ++ ++int nw_config_read(struct nw_config** config, const char* path) { ++ FILE* f = NULL; ++ int r; ++ ++ // Open the file ++ f = fopen(path, "r"); ++ if (!f) { ++ ERROR("Could not read configuration file %s: %m\n", path); ++ r = 1; ++ goto ERROR; ++ } ++ ++ // Read from file ++ r = nw_config_readf(config, f); ++ ++ERROR: ++ if (f) ++ fclose(f); ++ ++ return r; ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index a8aed7f..559ba94 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -28,4 +28,7 @@ int nw_config_create(struct nw_config** config); + struct nw_config* nw_config_ref(struct nw_config* config); + struct nw_config* nw_config_unref(struct nw_config* config); + ++int nw_config_readf(struct nw_config** config, FILE* f); ++int nw_config_read(struct nw_config** config, const char* path); ++ + #endif /* NETWORKD_CONFIG_H */ +-- +2.39.2 + diff --git a/network/patches/0148-networkd-Implement-setting-configuration-values.patch b/network/patches/0148-networkd-Implement-setting-configuration-values.patch new file mode 100644 index 000000000..cc2641125 --- /dev/null +++ b/network/patches/0148-networkd-Implement-setting-configuration-values.patch @@ -0,0 +1,283 @@ +From 4237caa2ed47385e3471822348d908846c745b29 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:04:01 +0000 +Subject: [PATCH 148/304] networkd: Implement setting configuration values + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 +- + src/networkd/config.c | 114 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/config.h | 7 +++ + src/networkd/string.h | 76 ++++++++++++++++++++++++++++ + 4 files changed, 199 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/string.h + +diff --git a/Makefile.am b/Makefile.am +index 50a6034..1b18f62 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -311,7 +311,8 @@ dist_networkd_SOURCES = \ + src/networkd/daemon.c \ + src/networkd/daemon.h \ + src/networkd/logging.h \ +- src/networkd/main.c ++ src/networkd/main.c \ ++ src/networkd/string.h + + networkd_CPPFLAGS = \ + $(AM_CPPFLAGS) +diff --git a/src/networkd/config.c b/src/networkd/config.c +index e808531..72a0cfb 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -18,17 +18,72 @@ + # # + #############################################################################*/ + ++#include + #include + #include ++#include ++#include + + #include "config.h" + #include "logging.h" ++#include "string.h" ++ ++struct nw_config_entry { ++ STAILQ_ENTRY(nw_config_entry) nodes; ++ ++ char key[NETWORK_CONFIG_KEY_MAX_LENGTH]; ++ char value[NETWORK_CONFIG_KEY_MAX_LENGTH]; ++}; + + struct nw_config { + int nrefs; ++ ++ STAILQ_HEAD(entries, nw_config_entry) entries; + }; + ++static void nw_config_entry_free(struct nw_config_entry* entry) { ++ free(entry); ++} ++ ++static struct nw_config_entry* nw_config_entry_create( ++ struct nw_config* config, const char* key) { ++ int r; ++ ++ // Check input value ++ if (!key) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ // Allocate a new object ++ struct nw_config_entry* entry = calloc(1, sizeof(*entry)); ++ if (!entry) ++ return NULL; ++ ++ // Store the key ++ r = nw_string_set(entry->key, key); ++ if (r) ++ goto ERROR; ++ ++ // Append the new entry ++ STAILQ_INSERT_TAIL(&config->entries, entry, nodes); ++ ++ERROR: ++ nw_config_entry_free(entry); ++ return NULL; ++} ++ + static void nw_config_free(struct nw_config* config) { ++ struct nw_config_entry* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&config->entries)) { ++ entry = STAILQ_FIRST(&config->entries); ++ STAILQ_REMOVE_HEAD(&config->entries, nodes); ++ ++ // Free the entry ++ nw_config_entry_free(entry); ++ } ++ + free(config); + } + +@@ -40,6 +95,9 @@ int nw_config_create(struct nw_config** config) { + // Initialize reference counter + c->nrefs = 1; + ++ // Initialise entries ++ STAILQ_INIT(&c->entries); ++ + *config = c; + + return 0; +@@ -106,3 +164,59 @@ ERROR: + + return r; + } ++ ++static struct nw_config_entry* nw_config_find(struct nw_config* config, const char* key) { ++ struct nw_config_entry* entry = NULL; ++ ++ STAILQ_FOREACH(entry, &config->entries, nodes) { ++ // Key must match ++ if (strcmp(entry->key, key) != 0) ++ continue; ++ ++ // Match! ++ return entry; ++ } ++ ++ // No match ++ return NULL; ++} ++ ++int nw_config_del(struct nw_config* config, const char* key) { ++ struct nw_config_entry* entry = NULL; ++ ++ // Find an entry matching the key ++ entry = nw_config_find(config, key); ++ ++ // If there is no entry, there is nothing to do ++ if (!entry) ++ return 0; ++ ++ // Otherwise remove the object ++ STAILQ_REMOVE(&config->entries, entry, nw_config_entry, nodes); ++ ++ // Free the entry ++ nw_config_entry_free(entry); ++ ++ return 0; ++} ++ ++int nw_config_set(struct nw_config* config, const char* key, const char* value) { ++ struct nw_config_entry* entry = NULL; ++ ++ // Delete the entry if val is NULL ++ if (!value) ++ return nw_config_del(config, key); ++ ++ // Find any existing entries ++ entry = nw_config_find(config, key); ++ ++ // Create a new entry if it doesn't exist, yet ++ if (!entry) { ++ entry = nw_config_entry_create(config, key); ++ if (!entry) ++ return 1; ++ } ++ ++ // Store the new value ++ return nw_string_set(entry->value, value); ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 559ba94..a793229 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -21,6 +21,9 @@ + #ifndef NETWORKD_CONFIG_H + #define NETWORKD_CONFIG_H + ++#define NETWORK_CONFIG_KEY_MAX_LENGTH 128 ++#define NETWORK_CONFIG_VALUE_MAX_LENGTH 2048 ++ + struct nw_config; + + int nw_config_create(struct nw_config** config); +@@ -31,4 +34,8 @@ struct nw_config* nw_config_unref(struct nw_config* config); + int nw_config_readf(struct nw_config** config, FILE* f); + int nw_config_read(struct nw_config** config, const char* path); + ++int nw_config_del(struct nw_config* config, const char* key); ++ ++int nw_config_set(struct nw_config* config, const char* key, const char* value); ++ + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/string.h b/src/networkd/string.h +new file mode 100644 +index 0000000..3ac4846 +--- /dev/null ++++ b/src/networkd/string.h +@@ -0,0 +1,76 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_STRING_H ++#define NETWORKD_STRING_H ++ ++#include ++ ++static inline int __nw_string_vformat(char* s, const size_t length, ++ const char* format, va_list args) { ++ // Write string to buffer ++ const ssize_t required = vsnprintf(s, length, format, args); ++ ++ // Catch any errors ++ if (required < 0) ++ return 1; ++ ++ // Check if the entire string could be written ++ if ((size_t)required >= length) { ++ errno = ENOMEM; ++ return 1; ++ } ++ ++ // Success ++ return 0; ++} ++ ++#define nw_string_format(s, format, ...) \ ++ __nw_string_format(s, sizeof(s), format, __VA_ARGS__) ++ ++static inline int __nw_string_format(char* s, const size_t length, ++ const char* format, ...) { ++ va_list args; ++ int r; ++ ++ // Call __nw_string_vformat ++ va_start(args, format); ++ r = __nw_string_vformat(s, length, format, args); ++ va_end(args); ++ ++ return r; ++} ++ ++#define nw_string_set(s, value) __nw_string_set(s, sizeof(s), value) ++ ++static inline int __nw_string_set(char* s, const size_t length, const char* value) { ++ // If value is NULL, we will overwrite the buffer with just zeros ++ if (!value) { ++ for (unsigned int i = 0; i < length; i++) ++ s[i] = '\0'; ++ ++ return 0; ++ } ++ ++ // Otherwise just copy ++ return __nw_string_format(s, length, "%s", value); ++} ++ ++#endif /* NETWORKD_STRING_H */ +-- +2.39.2 + diff --git a/network/patches/0149-networkd-Implement-reading-configuration-values.patch b/network/patches/0149-networkd-Implement-reading-configuration-values.patch new file mode 100644 index 000000000..b008145bd --- /dev/null +++ b/network/patches/0149-networkd-Implement-reading-configuration-values.patch @@ -0,0 +1,55 @@ +From d39683a626fd7f5fe2aea15365a27b3f7727ad0b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:09:57 +0000 +Subject: [PATCH 149/304] networkd: Implement reading configuration values + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 21 +++++++++++++++++++++ + src/networkd/config.h | 3 +++ + 2 files changed, 24 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 72a0cfb..a3db7c6 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -220,3 +220,24 @@ int nw_config_set(struct nw_config* config, const char* key, const char* value) + // Store the new value + return nw_string_set(entry->value, value); + } ++ ++const char* nw_config_get(struct nw_config* config, const char* key) { ++ struct nw_config_entry* entry = nw_config_find(config, key); ++ ++ // Return the value if found and set ++ if (entry && *entry->value) ++ return entry->value; ++ ++ // Otherwise return NULL ++ return NULL; ++} ++ ++unsigned int nw_config_get_unsigned_int(struct nw_config* config, const char* key) { ++ const char* value = nw_config_get(config, key); ++ ++ // Return zero if not set ++ if (!value) ++ return 0; ++ ++ return strtoul(value, NULL, 10); ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index a793229..c5a2f7f 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -38,4 +38,7 @@ int nw_config_del(struct nw_config* config, const char* key); + + int nw_config_set(struct nw_config* config, const char* key, const char* value); + ++const char* nw_config_get(struct nw_config* config, const char* key); ++unsigned int nw_config_get_unsigned_int(struct nw_config* config, const char* key); ++ + #endif /* NETWORKD_CONFIG_H */ +-- +2.39.2 + diff --git a/network/patches/0150-networkd-Implement-writing-configuration-files.patch b/network/patches/0150-networkd-Implement-writing-configuration-files.patch new file mode 100644 index 000000000..c66dda673 --- /dev/null +++ b/network/patches/0150-networkd-Implement-writing-configuration-files.patch @@ -0,0 +1,79 @@ +From d3dfdb77779004950cf3afb19e456b7d5c39c940 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:17:30 +0000 +Subject: [PATCH 150/304] networkd: Implement writing configuration files + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 40 ++++++++++++++++++++++++++++++++++++++++ + src/networkd/config.h | 3 +++ + 2 files changed, 43 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index a3db7c6..b2a23f0 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -165,6 +165,46 @@ ERROR: + return r; + } + ++int nw_config_writef(struct nw_config* config, FILE* f) { ++ struct nw_config_entry* entry = NULL; ++ int r; ++ ++ STAILQ_FOREACH(entry, &config->entries, nodes) { ++ // Skip if value is NULL ++ if (!*entry->value) ++ continue; ++ ++ // Write the entry ++ r = fprintf(f, "%s=\"%s\"\n", entry->key, entry->value); ++ if (r < 0) { ++ ERROR("Failed to write configuration: %m\n"); ++ return r; ++ } ++ } ++ ++ return 0; ++} ++ ++int nw_config_write(struct nw_config* config, const char* path) { ++ int r; ++ ++ FILE* f = fopen(path, "w"); ++ if (!f) { ++ ERROR("Failed to open %s for writing: %m\n", path); ++ r = 1; ++ goto ERROR; ++ } ++ ++ // Write configuration ++ r = nw_config_writef(config, f); ++ ++ERROR: ++ if (f) ++ fclose(f); ++ ++ return r; ++} ++ + static struct nw_config_entry* nw_config_find(struct nw_config* config, const char* key) { + struct nw_config_entry* entry = NULL; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index c5a2f7f..90e73f4 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -34,6 +34,9 @@ struct nw_config* nw_config_unref(struct nw_config* config); + int nw_config_readf(struct nw_config** config, FILE* f); + int nw_config_read(struct nw_config** config, const char* path); + ++int nw_config_writef(struct nw_config* config, FILE* f); ++int nw_config_write(struct nw_config* config, const char* path); ++ + int nw_config_del(struct nw_config* config, const char* key); + + int nw_config_set(struct nw_config* config, const char* key, const char* value); +-- +2.39.2 + diff --git a/network/patches/0151-networkd-Read-main-configuration-file.patch b/network/patches/0151-networkd-Read-main-configuration-file.patch new file mode 100644 index 000000000..4a6a2ee67 --- /dev/null +++ b/network/patches/0151-networkd-Read-main-configuration-file.patch @@ -0,0 +1,54 @@ +From 2ac78f288a7c1f8b363cf0c86fc196aeeb8e8264 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:20:23 +0000 +Subject: [PATCH 151/304] networkd: Read main configuration file + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 3aee8ca..bd5f1f0 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -26,12 +26,15 @@ + #include + + #include "bus.h" ++#include "config.h" + #include "daemon.h" + #include "logging.h" + + struct nw_daemon { + int nrefs; + ++ struct nw_config* config; ++ + // Event Loop + sd_event* loop; + +@@ -105,6 +108,11 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + ++ // Read configuration file ++ r = nw_config_read(&daemon->config, "/etc/network/settings"); ++ if (r) ++ return r; ++ + // Setup the event loop + r = nw_daemon_setup_loop(daemon); + if (r) +@@ -145,6 +153,8 @@ ERROR: + } + + static void nw_daemon_free(struct nw_daemon* daemon) { ++ if (daemon->config) ++ nw_config_unref(daemon->config); + if (daemon->bus) + sd_bus_unref(daemon->bus); + if (daemon->loop) +-- +2.39.2 + diff --git a/network/patches/0152-networkd-Set-configuration-path-from-build-scripts.patch b/network/patches/0152-networkd-Set-configuration-path-from-build-scripts.patch new file mode 100644 index 000000000..a06cb3b29 --- /dev/null +++ b/network/patches/0152-networkd-Set-configuration-path-from-build-scripts.patch @@ -0,0 +1,41 @@ +From 5c1452a43a6a8d3d3596fa8be38741e62852ce5c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:29:45 +0000 +Subject: [PATCH 152/304] networkd: Set configuration path from build scripts + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 ++- + src/networkd/daemon.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 1b18f62..3cc7ce9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -315,7 +315,8 @@ dist_networkd_SOURCES = \ + src/networkd/string.h + + networkd_CPPFLAGS = \ +- $(AM_CPPFLAGS) ++ $(AM_CPPFLAGS) \ ++ -DCONFIG_DIR="\"$(configdir)\"" + + networkd_CFLAGS = \ + $(AM_CFLAGS) \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index bd5f1f0..9077c54 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -109,7 +109,7 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + + // Read configuration file +- r = nw_config_read(&daemon->config, "/etc/network/settings"); ++ r = nw_config_read(&daemon->config, CONFIG_DIR "/settings"); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0153-networkd-Add-scaffolding-for-zones.patch b/network/patches/0153-networkd-Add-scaffolding-for-zones.patch new file mode 100644 index 000000000..8b720d38f --- /dev/null +++ b/network/patches/0153-networkd-Add-scaffolding-for-zones.patch @@ -0,0 +1,192 @@ +From e4eebc6e6a0091729831fd1361d0a9fd0d205114 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 03:42:57 +0000 +Subject: [PATCH 153/304] networkd: Add scaffolding for zones + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++- + src/networkd/config.h | 2 ++ + src/networkd/string.h | 3 ++ + src/networkd/zone.c | 83 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/zone.h | 35 ++++++++++++++++++ + 5 files changed, 126 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/zone.c + create mode 100644 src/networkd/zone.h + +diff --git a/Makefile.am b/Makefile.am +index 3cc7ce9..5bb9c4d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -312,7 +312,9 @@ dist_networkd_SOURCES = \ + src/networkd/daemon.h \ + src/networkd/logging.h \ + src/networkd/main.c \ +- src/networkd/string.h ++ src/networkd/string.h \ ++ src/networkd/zone.c \ ++ src/networkd/zone.h + + networkd_CPPFLAGS = \ + $(AM_CPPFLAGS) \ +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 90e73f4..3474ae1 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_CONFIG_H + #define NETWORKD_CONFIG_H + ++#include ++ + #define NETWORK_CONFIG_KEY_MAX_LENGTH 128 + #define NETWORK_CONFIG_VALUE_MAX_LENGTH 2048 + +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 3ac4846..52b5add 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -21,7 +21,10 @@ + #ifndef NETWORKD_STRING_H + #define NETWORKD_STRING_H + ++#include + #include ++#include ++#include + + static inline int __nw_string_vformat(char* s, const size_t length, + const char* format, va_list args) { +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +new file mode 100644 +index 0000000..5066c4b +--- /dev/null ++++ b/src/networkd/zone.c +@@ -0,0 +1,83 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "config.h" ++#include "string.h" ++#include "zone.h" ++ ++struct nw_zone { ++ int nrefs; ++ ++ char name[NETWORK_ZONE_NAME_MAX_LENGTH]; ++ ++ // Configuration ++ struct nw_config *config; ++}; ++ ++static void nw_zone_free(struct nw_zone* zone) { ++ if (zone->config) ++ nw_config_unref(zone->config); ++ ++ free(zone); ++} ++ ++int nw_zone_create(struct nw_zone** zone, const char* name) { ++ int r; ++ ++ // Allocate a new object ++ struct nw_zone* z = calloc(1, sizeof(*z)); ++ if (!z) ++ return 1; ++ ++ // Initialize reference counter ++ z->nrefs = 1; ++ ++ // Store the name ++ r = nw_string_set(z->name, name); ++ if (r) ++ goto ERROR; ++ ++ *zone = z; ++ return 0; ++ ++ERROR: ++ nw_zone_free(z); ++ return r; ++} ++ ++struct nw_zone* nw_zone_ref(struct nw_zone* zone) { ++ zone->nrefs++; ++ ++ return zone; ++} ++ ++struct nw_zone* nw_zone_unref(struct nw_zone* zone) { ++ if (--zone->nrefs > 0) ++ return zone; ++ ++ nw_zone_free(zone); ++ return NULL; ++} ++ ++const char* nw_zone_name(struct nw_zone* zone) { ++ return zone->name; ++} +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +new file mode 100644 +index 0000000..78287ab +--- /dev/null ++++ b/src/networkd/zone.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_ZONE_H ++#define NETWORKD_ZONE_H ++ ++#define NETWORK_ZONE_NAME_MAX_LENGTH 16 ++ ++struct nw_zone; ++ ++int nw_zone_create(struct nw_zone** zone, const char* name); ++ ++struct nw_zone* nw_zone_ref(struct nw_zone* zone); ++struct nw_zone* nw_zone_unref(struct nw_zone* zone); ++ ++const char* nw_zone_name(struct nw_zone* zone); ++ ++#endif /* NETWORKD_ZONE_H */ +-- +2.39.2 + diff --git a/network/patches/0154-networkd-Install-a-dbus-service-file.patch b/network/patches/0154-networkd-Install-a-dbus-service-file.patch new file mode 100644 index 000000000..c5fdc33df --- /dev/null +++ b/network/patches/0154-networkd-Install-a-dbus-service-file.patch @@ -0,0 +1,82 @@ +From 063eb4d841e8fc4625d889a9d5f8ac832bd60f0d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 04:05:07 +0000 +Subject: [PATCH 154/304] networkd: Install a dbus service file + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++++ + configure.ac | 15 +++++++++++++++ + src/networkd/org.ipfire.network1.service | 5 +++++ + 3 files changed, 24 insertions(+) + create mode 100644 src/networkd/org.ipfire.network1.service + +diff --git a/Makefile.am b/Makefile.am +index 5bb9c4d..5cfeefa 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -62,6 +62,7 @@ INSTALL_EXEC_HOOKS = + UNINSTALL_EXEC_HOOKS = + noinst_DATA = + sbin_PROGRAMS = ++dist_dbussystembusdir_DATA = + + AM_CPPFLAGS = \ + $(OUR_CPPFLAGS) \ +@@ -330,6 +331,9 @@ networkd_LDFLAGS = \ + networkd_LDADD = \ + $(SYSTEMD_LIBS) + ++dist_dbussystembusdir_DATA += \ ++ src/networkd/org.ipfire.network1.service ++ + # ------------------------------------------------------------------------------ + + util_PROGRAMS = \ +diff --git a/configure.ac b/configure.ac +index b820794..8634a39 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -133,6 +133,20 @@ AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-man-pages], + AS_IF([test "x$enable_manpages" != xno], [have_manpages=yes]) + AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"]) + ++# ------------------------------------------------------------------------------ ++ ++AC_ARG_WITH([dbussystembusdir], AS_HELP_STRING([--with-dbussystembusdir=DIR], ++ [path to D-Bus system bus services directory]), [with_dbussystembusdir=${withval}]) ++if test -z "${with_dbussystembusdir}"; then ++ AC_MSG_CHECKING([D-Bus system bus services dir]) ++ with_dbussystembusdir="$($PKG_CONFIG --variable=system_bus_services_dir dbus-1)" ++ if test -z "${with_dbussystembusdir}"; then ++ AC_MSG_ERROR([D-Bus system bus services directory is required]) ++ fi ++ AC_MSG_RESULT([${with_dbussystembusdir}]) ++fi ++AC_SUBST(dbussystembusdir, [${with_dbussystembusdir}]) ++ + # ------------------------------------------------------------------------------ + AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), +@@ -176,6 +190,7 @@ AC_MSG_RESULT([ + + prefix: $prefix + ++ dbussystembusdir: ${dbussystembusdir} + systemdsystemunitdir: $systemdsystemunitdir + udevdir: $udevdir + +diff --git a/src/networkd/org.ipfire.network1.service b/src/networkd/org.ipfire.network1.service +new file mode 100644 +index 0000000..fdeda66 +--- /dev/null ++++ b/src/networkd/org.ipfire.network1.service +@@ -0,0 +1,5 @@ ++[D-BUS Service] ++Name=org.ipfire.network1 ++Exec=/bin/false ++User=root ++SystemdService=dbus-org.ipfire.network1.service +-- +2.39.2 + diff --git a/network/patches/0155-networkd-Install-a-dbus-policy.patch b/network/patches/0155-networkd-Install-a-dbus-policy.patch new file mode 100644 index 000000000..5185e467a --- /dev/null +++ b/network/patches/0155-networkd-Install-a-dbus-policy.patch @@ -0,0 +1,87 @@ +From d5fab986b9ac9a692b26e5f5d49a51dce85ccf59 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 18:47:30 +0000 +Subject: [PATCH 155/304] networkd: Install a dbus policy + +Signed-off-by: Michael Tremer +--- + Makefile.am | 8 ++++++-- + configure.ac | 12 ++++++++++++ + src/networkd/org.ipfire.network1.conf | 16 ++++++++++++++++ + 3 files changed, 34 insertions(+), 2 deletions(-) + create mode 100644 src/networkd/org.ipfire.network1.conf + +diff --git a/Makefile.am b/Makefile.am +index 5cfeefa..eeda5ba 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -62,7 +62,8 @@ INSTALL_EXEC_HOOKS = + UNINSTALL_EXEC_HOOKS = + noinst_DATA = + sbin_PROGRAMS = +-dist_dbussystembusdir_DATA = ++dist_dbuspolicy_DATA = ++dist_dbussystembus_DATA = + + AM_CPPFLAGS = \ + $(OUR_CPPFLAGS) \ +@@ -331,7 +332,10 @@ networkd_LDFLAGS = \ + networkd_LDADD = \ + $(SYSTEMD_LIBS) + +-dist_dbussystembusdir_DATA += \ ++dist_dbuspolicy_DATA += \ ++ src/networkd/org.ipfire.network1.conf ++ ++dist_dbussystembus_DATA += \ + src/networkd/org.ipfire.network1.service + + # ------------------------------------------------------------------------------ +diff --git a/configure.ac b/configure.ac +index 8634a39..e612ff8 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -135,6 +135,18 @@ AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"]) + + # ------------------------------------------------------------------------------ + ++AC_ARG_WITH( ++ [dbuspolicydir], ++ AS_HELP_STRING( ++ [--with-dbuspolicydir=arg], ++ [directory for D-Bus policies (default: ${dbusdatadir|datarootdir}/dbus-1/system.d)] ++ ), ++ [dbuspolicydir="$withval"], ++ [PKG_CHECK_VAR([dbusdatadir], [dbus-1], [datadir],, [dbusdatadir="${datarootdir}"]) ++ dbuspolicydir="${dbusdatadir}/dbus-1/system.d"] ++) ++AC_SUBST(dbuspolicydir) ++ + AC_ARG_WITH([dbussystembusdir], AS_HELP_STRING([--with-dbussystembusdir=DIR], + [path to D-Bus system bus services directory]), [with_dbussystembusdir=${withval}]) + if test -z "${with_dbussystembusdir}"; then +diff --git a/src/networkd/org.ipfire.network1.conf b/src/networkd/org.ipfire.network1.conf +new file mode 100644 +index 0000000..96e8e15 +--- /dev/null ++++ b/src/networkd/org.ipfire.network1.conf +@@ -0,0 +1,16 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.2 + diff --git a/network/patches/0156-configure-Tidy-up-dbus-path-detection.patch b/network/patches/0156-configure-Tidy-up-dbus-path-detection.patch new file mode 100644 index 000000000..887870a32 --- /dev/null +++ b/network/patches/0156-configure-Tidy-up-dbus-path-detection.patch @@ -0,0 +1,53 @@ +From 9ca8914ef2c65a669aa05e37f2dbe232f54ecbf1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 18:51:34 +0000 +Subject: [PATCH 156/304] configure: Tidy up dbus path detection + +Signed-off-by: Michael Tremer +--- + configure.ac | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/configure.ac b/configure.ac +index e612ff8..ba5967d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -147,17 +147,16 @@ AC_ARG_WITH( + ) + AC_SUBST(dbuspolicydir) + +-AC_ARG_WITH([dbussystembusdir], AS_HELP_STRING([--with-dbussystembusdir=DIR], +- [path to D-Bus system bus services directory]), [with_dbussystembusdir=${withval}]) +-if test -z "${with_dbussystembusdir}"; then +- AC_MSG_CHECKING([D-Bus system bus services dir]) +- with_dbussystembusdir="$($PKG_CONFIG --variable=system_bus_services_dir dbus-1)" +- if test -z "${with_dbussystembusdir}"; then +- AC_MSG_ERROR([D-Bus system bus services directory is required]) +- fi +- AC_MSG_RESULT([${with_dbussystembusdir}]) +-fi +-AC_SUBST(dbussystembusdir, [${with_dbussystembusdir}]) ++AC_ARG_WITH( ++ [dbussystembusdir], ++ AS_HELP_STRING( ++ [--with-dbussystembusdir=arg], ++ [path to D-Bus system bus services directory] ++ ), ++ [dbussystembusdir="$withval"], ++ [PKG_CHECK_VAR([dbussystembusdir], [dbus-1], [system_bus_services_dir],, [dbussystembusdir="${datarootdir}"])] ++) ++AC_SUBST(dbuspolicydir) + + # ------------------------------------------------------------------------------ + AC_ARG_WITH([systemdsystemunitdir], +@@ -202,6 +201,7 @@ AC_MSG_RESULT([ + + prefix: $prefix + ++ dbuspolicydir: ${dbuspolicydir} + dbussystembusdir: ${dbussystembusdir} + systemdsystemunitdir: $systemdsystemunitdir + udevdir: $udevdir +-- +2.39.2 + diff --git a/network/patches/0157-configure-Drop-non-sensical-CFLAGS-and-add-more-warn.patch b/network/patches/0157-configure-Drop-non-sensical-CFLAGS-and-add-more-warn.patch new file mode 100644 index 000000000..3e608f6af --- /dev/null +++ b/network/patches/0157-configure-Drop-non-sensical-CFLAGS-and-add-more-warn.patch @@ -0,0 +1,77 @@ +From a465e68bd8bf11f7cd41089941ad558dbda34f19 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 18:54:54 +0000 +Subject: [PATCH 157/304] configure: Drop non-sensical CFLAGS and add more + warnings + +Signed-off-by: Michael Tremer +--- + configure.ac | 42 ++++++++++++++---------------------------- + 1 file changed, 14 insertions(+), 28 deletions(-) + +diff --git a/configure.ac b/configure.ac +index ba5967d..9560838 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -28,6 +28,8 @@ AC_INIT([network], + + AC_CONFIG_AUX_DIR([build-aux]) + ++AC_USE_SYSTEM_EXTENSIONS ++AC_SYS_LARGEFILE + AC_PREFIX_DEFAULT([/usr]) + + AM_INIT_AUTOMAKE([ +@@ -65,37 +67,21 @@ AC_PROG_CC_C99 + AC_PROG_CC_C_O + AC_PROG_GCC_TRADITIONAL + +-AC_USE_SYSTEM_EXTENSIONS +- + CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ +- -pipe \ + -Wall \ +- -Wextra \ +- -Wno-inline \ +- -Wundef \ +- "-Wformat=2 -Wformat-security -Wformat-nonliteral" \ +- -Wno-unused-parameter \ +- -Wno-unused-result \ +- -fno-strict-aliasing \ +- -ffunction-sections \ +- -fdata-sections \ +- -fstack-protector-all \ +- --param=ssp-buffer-size=4]) +-AC_SUBST([OUR_CFLAGS], $with_cflags) ++ -Wchar-subscripts \ ++ -Wformat-security \ ++ -Wmissing-declarations \ ++ -Wmissing-prototypes \ ++ -Wnested-externs \ ++ -Wpointer-arith \ ++ -Wshadow \ ++ -Wsign-compare \ ++ -Wstrict-prototypes \ ++ -Wtype-limits \ ++]) + +-AS_CASE([$CFLAGS], [*-O[[12345g\ ]]*], +- [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\ +- -Wp,-D_FORTIFY_SOURCE=2])], +- [AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])]) +-AC_SUBST([OUR_CPPFLAGS], $with_cppflags) +- +-CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\ +- -Wl,--as-needed \ +- -Wl,--no-undefined \ +- -Wl,--gc-sections \ +- -Wl,-z,relro \ +- -Wl,-z,now]) +-AC_SUBST([OUR_LDFLAGS], $with_ldflags) ++AC_SUBST([OUR_CFLAGS], $with_cflags) + + # ------------------------------------------------------------------------------ + +-- +2.39.2 + diff --git a/network/patches/0158-libnetwork-Fix-prototype-of-network_version.patch b/network/patches/0158-libnetwork-Fix-prototype-of-network_version.patch new file mode 100644 index 000000000..6dbfcad59 --- /dev/null +++ b/network/patches/0158-libnetwork-Fix-prototype-of-network_version.patch @@ -0,0 +1,26 @@ +From ac17b7ef5c2dc801dc9eb179927096bc18e7bc58 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 18:56:17 +0000 +Subject: [PATCH 158/304] libnetwork: Fix prototype of network_version() + +Signed-off-by: Michael Tremer +--- + src/libnetwork/network/libnetwork.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libnetwork/network/libnetwork.h b/src/libnetwork/network/libnetwork.h +index 2919fc9..e69fd04 100644 +--- a/src/libnetwork/network/libnetwork.h ++++ b/src/libnetwork/network/libnetwork.h +@@ -36,7 +36,7 @@ void network_set_log_fn(struct network_ctx* ctx, + int network_get_log_priority(struct network_ctx* ctx); + void network_set_log_priority(struct network_ctx* ctx, int priority); + +-const char* network_version(); ++const char* network_version(void); + + #ifdef NETWORK_PRIVATE + +-- +2.39.2 + diff --git a/network/patches/0159-networkd-Move-systemd-notifications-into-daemon-obje.patch b/network/patches/0159-networkd-Move-systemd-notifications-into-daemon-obje.patch new file mode 100644 index 000000000..3c3051800 --- /dev/null +++ b/network/patches/0159-networkd-Move-systemd-notifications-into-daemon-obje.patch @@ -0,0 +1,104 @@ +From 8a88982f6823b376f2eace8c718dc930072de667 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 19:00:51 +0000 +Subject: [PATCH 159/304] networkd: Move systemd notifications into daemon + object + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 19 ++++++++++++++++--- + src/networkd/main.c | 24 ++++-------------------- + 2 files changed, 20 insertions(+), 23 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 9077c54..b93877e 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -23,6 +23,7 @@ + #include + + #include ++#include + #include + + #include "bus.h" +@@ -183,14 +184,26 @@ struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon) { + int nw_daemon_run(struct nw_daemon* daemon) { + int r; + ++ // We are now ready to process any requests ++ sd_notify(0, "READY=1\n" "STATUS=Processing requests..."); ++ + // Launch the event loop + r = sd_event_loop(daemon->loop); +- if (r) { +- ERROR("Could not run the event loop: %m\n"); +- return r; ++ if (r < 0) { ++ ERROR("Could not run the event loop: %s\n", strerror(-r)); ++ goto ERROR; + } + ++ ++ // Let systemd know that we are shutting down ++ sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); ++ + return 0; ++ ++ERROR: ++ sd_notifyf(0, "ERRNO=%i", -r); ++ ++ return 1; + } + + int nw_daemon_reload(struct nw_daemon* daemon) { +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 80123ad..51a9bba 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -18,10 +18,7 @@ + # # + #############################################################################*/ + +-#include +-#include +- +-#include ++#include + + #include "daemon.h" + +@@ -34,27 +31,14 @@ int main(int argc, char** argv) { + // Create the daemon + r = nw_daemon_create(&daemon); + if (r) +- goto ERROR; +- +- // We are now ready to process any requests +- sd_notify(0, "READY=1\n" "STATUS=Processing requests..."); ++ return r; + + // Run the daemon + r = nw_daemon_run(daemon); +- if (r) +- goto ERROR; +- +- // Let systemd know that we are shutting down +- sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); +- +- goto CLEANUP; +- +-ERROR: +- sd_notifyf(0, "ERRNO=%i", errno); + +-CLEANUP: ++ // Cleanup + if (daemon) + nw_daemon_unref(daemon); + +- return EXIT_FAILURE; ++ return r; + } +-- +2.39.2 + diff --git a/network/patches/0160-man-Fix-incorrect-name-on-IPsec-man-page.patch b/network/patches/0160-man-Fix-incorrect-name-on-IPsec-man-page.patch new file mode 100644 index 000000000..ba3b4f6bf --- /dev/null +++ b/network/patches/0160-man-Fix-incorrect-name-on-IPsec-man-page.patch @@ -0,0 +1,45 @@ +From fbe46265eecc9064df8819d9bd08e5fcb0ea985c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 19:03:41 +0000 +Subject: [PATCH 160/304] man: Fix incorrect name on IPsec man page + +Signed-off-by: Michael Tremer +--- + man/network-vpn-ipsec.txt | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/man/network-vpn-ipsec.txt b/man/network-vpn-ipsec.txt +index 25347a8..d60d41d 100644 +--- a/man/network-vpn-ipsec.txt ++++ b/man/network-vpn-ipsec.txt +@@ -1,7 +1,7 @@ +-= network-vpn-security-policies(8) ++= network-vpn-ipsec(8) + + == NAME +-network-ipsec - Configure IPsec VPN connections ++network-vpn-ipsec - Configure IPsec VPN connections + + == SYNOPSIS + [verse] +@@ -27,7 +27,7 @@ The following commands are understood: + For all other commands, the name of the IPsec VPN connection needs to be passed first: + + 'NAME show':: +- Shows the configuration of the IPsec VPN connection ++ Shows the configuration of the IPsec VPN connection + + 'NAME authentication mode':: + Set the authentication mode out of the following available modes: +@@ -58,7 +58,7 @@ include::include-description.txt[] + Specify the subnets of the local system which should be made available to the remote peer. + + 'NAME mode [transport|tunnel]':: +- Set the mode of the IPsec VPN connection. ++ Set the mode of the IPsec VPN connection. + + 'NAME peer PEER':: + Set the peer to which the IPsec VPN connection should be etablished. +-- +2.39.2 + diff --git a/network/patches/0161-networkd-Install-some-simple-PolicyKit-policy.patch b/network/patches/0161-networkd-Install-some-simple-PolicyKit-policy.patch new file mode 100644 index 000000000..68634a0e1 --- /dev/null +++ b/network/patches/0161-networkd-Install-some-simple-PolicyKit-policy.patch @@ -0,0 +1,94 @@ +From bf98bd657165f87eafae1442a6396239d74cd88e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 19:26:35 +0000 +Subject: [PATCH 161/304] networkd: Install some simple PolicyKit policy + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++++ + configure.ac | 13 +++++++++++++ + src/networkd/org.ipfire.network1.policy | 19 +++++++++++++++++++ + 3 files changed, 36 insertions(+) + create mode 100644 src/networkd/org.ipfire.network1.policy + +diff --git a/Makefile.am b/Makefile.am +index eeda5ba..4802de3 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -64,6 +64,7 @@ noinst_DATA = + sbin_PROGRAMS = + dist_dbuspolicy_DATA = + dist_dbussystembus_DATA = ++dist_polkitpolicy_DATA = + + AM_CPPFLAGS = \ + $(OUR_CPPFLAGS) \ +@@ -338,6 +339,9 @@ dist_dbuspolicy_DATA += \ + dist_dbussystembus_DATA += \ + src/networkd/org.ipfire.network1.service + ++dist_polkitpolicy_DATA += \ ++ src/networkd/org.ipfire.network1.policy ++ + # ------------------------------------------------------------------------------ + + util_PROGRAMS = \ +diff --git a/configure.ac b/configure.ac +index 9560838..16f0724 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -144,6 +144,18 @@ AC_ARG_WITH( + ) + AC_SUBST(dbuspolicydir) + ++AC_ARG_WITH( ++ [polkitpolicydir], ++ AS_HELP_STRING( ++ [--with-polkitpolicydir=arg], ++ [directory for PolicyKit policies] ++ ), ++ [polkitpolicydir="$withval"], ++ [PKG_CHECK_VAR([polkitpolicydir], [polkit], [actiondir]) ++ polkitpolicydir="${datadir}/polkit-1/actions"] ++) ++AC_SUBST(polkitpolicydir) ++ + # ------------------------------------------------------------------------------ + AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), +@@ -189,6 +201,7 @@ AC_MSG_RESULT([ + + dbuspolicydir: ${dbuspolicydir} + dbussystembusdir: ${dbussystembusdir} ++ polkitpolicydir: ${polkitpolicydir} + systemdsystemunitdir: $systemdsystemunitdir + udevdir: $udevdir + +diff --git a/src/networkd/org.ipfire.network1.policy b/src/networkd/org.ipfire.network1.policy +new file mode 100644 +index 0000000..46318f1 +--- /dev/null ++++ b/src/networkd/org.ipfire.network1.policy +@@ -0,0 +1,19 @@ ++ ++ ++ ++ ++ The IPFire Project ++ https://www.ipfire.org ++ ++ ++ Reload Network Settings ++ Authentication is required to reload network settings. ++ ++ auth_admin ++ auth_admin ++ auth_admin_keep ++ ++ unix-user:network ++ ++ +-- +2.39.2 + diff --git a/network/patches/0162-networkd-Call-function-when-we-are-connected-to-dbus.patch b/network/patches/0162-networkd-Call-function-when-we-are-connected-to-dbus.patch new file mode 100644 index 000000000..62c5161e8 --- /dev/null +++ b/network/patches/0162-networkd-Call-function-when-we-are-connected-to-dbus.patch @@ -0,0 +1,51 @@ +From bf42846c2ac47b5ecb8eea5cba618b130a6401ab Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 30 Jan 2023 20:55:42 +0000 +Subject: [PATCH 162/304] networkd: Call function when we are connected to dbus + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 95862d2..36ae7c9 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -28,10 +28,18 @@ + #include "daemon.h" + #include "logging.h" + +-static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* ret_error) { ++static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) { + return 1; + } + ++static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ DEBUG("Connected to D-Bus\n"); ++ ++ return 0; ++} ++ + static const sd_bus_vtable daemon_vtable[] = { + SD_BUS_VTABLE_START(0), + SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, +@@ -127,5 +135,13 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop) { + return 1; + } + ++ // Request receiving a connect signal ++ r = sd_bus_match_signal_async(bus, NULL, "org.freedesktop.DBus.Local", ++ NULL, "org.freedesktop.DBus.Local", "Connected", nw_bus_on_connect, NULL, NULL); ++ if (r < 0) { ++ ERROR("Could not request match on Connected signal: %s\n", strerror(-r)); ++ return 1; ++ } ++ + return 0; + } +-- +2.39.2 + diff --git a/network/patches/0163-networkd-Install-a-systemd-service-file.patch b/network/patches/0163-networkd-Install-a-systemd-service-file.patch new file mode 100644 index 000000000..460834fea --- /dev/null +++ b/network/patches/0163-networkd-Install-a-systemd-service-file.patch @@ -0,0 +1,116 @@ +From 5d968c0188b8181db6f392f925d7875e12e7e21b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 15:26:34 +0000 +Subject: [PATCH 163/304] networkd: Install a systemd service file + +Signed-off-by: Michael Tremer +--- + .gitignore | 1 + + Makefile.am | 12 ++++++++- + src/networkd/networkd.service.in | 45 ++++++++++++++++++++++++++++++++ + 3 files changed, 57 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/networkd.service.in + +diff --git a/.gitignore b/.gitignore +index e3bae67..9194c93 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -8,6 +8,7 @@ + /src/inetcalc + /src/libnetwork/libnetwork.pc + /src/network.pc ++/src/networkd/networkd.service + /src/ppp/ip-updown + /src/systemd/*.service + /test/nitsi/test/settings +diff --git a/Makefile.am b/Makefile.am +index 4802de3..3a3f82c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -65,6 +65,7 @@ sbin_PROGRAMS = + dist_dbuspolicy_DATA = + dist_dbussystembus_DATA = + dist_polkitpolicy_DATA = ++systemdsystemunit_DATA = + + AM_CPPFLAGS = \ + $(OUR_CPPFLAGS) \ +@@ -342,6 +343,15 @@ dist_dbussystembus_DATA += \ + dist_polkitpolicy_DATA += \ + src/networkd/org.ipfire.network1.policy + ++systemdsystemunit_DATA += \ ++ src/networkd/networkd.service ++ ++EXTRA_DIST += \ ++ src/networkd/networkd.service.in ++ ++CLEANFILES += \ ++ src/networkd/networkd.service ++ + # ------------------------------------------------------------------------------ + + util_PROGRAMS = \ +@@ -406,7 +416,7 @@ UNINSTALL_EXEC_HOOKS += ppp-uninstall-hook + # ------------------------------------------------------------------------------ + + if HAVE_SYSTEMD +-systemdsystemunit_DATA = \ ++systemdsystemunit_DATA += \ + src/systemd/firewall.service \ + src/systemd/firewall-init.service \ + src/systemd/network-init.service \ +diff --git a/src/networkd/networkd.service.in b/src/networkd/networkd.service.in +new file mode 100644 +index 0000000..4361023 +--- /dev/null ++++ b/src/networkd/networkd.service.in +@@ -0,0 +1,45 @@ ++[Unit] ++Description=Network Configuration ++Documentation=man:networkd.service(8) ++ ++ConditionCapability=CAP_NET_ADMIN ++DefaultDependencies=no ++# systemd-udevd.service can be dropped once tuntap is moved to netlink ++After=systemd-udevd.service network-pre.target systemd-sysusers.service systemd-sysctl.service ++Before=network.target multi-user.target shutdown.target ++Conflicts=shutdown.target ++Wants=network.target ++ ++[Service] ++AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW ++BusName=org.ipfire.network1 ++CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW ++DeviceAllow=char-* rw ++ExecStart=@sbindir@/networkd ++FileDescriptorStoreMax=512 ++LockPersonality=yes ++MemoryDenyWriteExecute=yes ++NoNewPrivileges=yes ++ProtectProc=invisible ++ProtectClock=yes ++ProtectControlGroups=yes ++ProtectHome=yes ++ProtectKernelLogs=yes ++ProtectKernelModules=yes ++ProtectSystem=strict ++Restart=on-failure ++RestartSec=0 ++RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET ++RestrictNamespaces=yes ++RestrictRealtime=yes ++RestrictSUIDSGID=yes ++SystemCallArchitectures=native ++SystemCallErrorNumber=EPERM ++SystemCallFilter=@system-service ++Type=notify-reload ++User=network ++WatchdogSec=3min ++ ++[Install] ++WantedBy=multi-user.target ++Alias=dbus-org.ipfire.network1.service +-- +2.39.2 + diff --git a/network/patches/0164-networkd-Fully-implement-bus-handler-for-Reload.patch b/network/patches/0164-networkd-Fully-implement-bus-handler-for-Reload.patch new file mode 100644 index 000000000..65054fa0b --- /dev/null +++ b/network/patches/0164-networkd-Fully-implement-bus-handler-for-Reload.patch @@ -0,0 +1,32 @@ +From 1dc98e400cd9c17edffa8f94f02a38ca1777cef8 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 15:26:57 +0000 +Subject: [PATCH 164/304] networkd: Fully implement bus handler for Reload + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 36ae7c9..56eda87 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -29,7 +29,13 @@ + #include "logging.h" + + static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) { +- return 1; ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Reload the daemon ++ nw_daemon_reload(daemon); ++ ++ // Respond with an empty message ++ return sd_bus_reply_method_return(m, NULL); + } + + static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { +-- +2.39.2 + diff --git a/network/patches/0165-networkd-Asynchronously-register-to-the-bus.patch b/network/patches/0165-networkd-Asynchronously-register-to-the-bus.patch new file mode 100644 index 000000000..c122a8ee2 --- /dev/null +++ b/network/patches/0165-networkd-Asynchronously-register-to-the-bus.patch @@ -0,0 +1,28 @@ +From 1e5ff643f2e18e5133ec932d5355f110ca1bfbf4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 15:27:18 +0000 +Subject: [PATCH 165/304] networkd: Asynchronously register to the bus + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 56eda87..5224aaa 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -126,9 +126,7 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop) { + } + + // Request interface name +- // XXX Should this be async? +- // XXX How do we get the actual error message from dbus? +- r = sd_bus_request_name(bus, NETWORKD_BUS_INTERFACE_NAME, 0); ++ r = sd_bus_request_name_async(bus, NULL, NETWORKD_BUS_INTERFACE_NAME, 0, NULL, NULL); + if (r < 0) { + ERROR("Could not request bus name: %s\n", strerror(-r)); + return 1; +-- +2.39.2 + diff --git a/network/patches/0166-networkd-config-Split-flushing-all-entries-into-a-fu.patch b/network/patches/0166-networkd-config-Split-flushing-all-entries-into-a-fu.patch new file mode 100644 index 000000000..e9601d3e8 --- /dev/null +++ b/network/patches/0166-networkd-config-Split-flushing-all-entries-into-a-fu.patch @@ -0,0 +1,71 @@ +From 91915f80f60943afec29743eda7258f5bf65e8e5 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 21:46:11 +0000 +Subject: [PATCH 166/304] networkd: config: Split flushing all entries into a + function + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 25 ++++++++++++++++--------- + src/networkd/config.h | 2 ++ + 2 files changed, 18 insertions(+), 9 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index b2a23f0..a11ee1c 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -74,15 +74,8 @@ ERROR: + } + + static void nw_config_free(struct nw_config* config) { +- struct nw_config_entry* entry = NULL; +- +- while (!STAILQ_EMPTY(&config->entries)) { +- entry = STAILQ_FIRST(&config->entries); +- STAILQ_REMOVE_HEAD(&config->entries, nodes); +- +- // Free the entry +- nw_config_entry_free(entry); +- } ++ // Flush all entries ++ nw_config_flush(config); + + free(config); + } +@@ -117,6 +110,20 @@ struct nw_config* nw_config_unref(struct nw_config* config) { + return NULL; + } + ++int nw_config_flush(struct nw_config* config) { ++ struct nw_config_entry* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&config->entries)) { ++ entry = STAILQ_FIRST(&config->entries); ++ STAILQ_REMOVE_HEAD(&config->entries, nodes); ++ ++ // Free the entry ++ nw_config_entry_free(entry); ++ } ++ ++ return 0; ++} ++ + static int nw_config_parse(struct nw_config* config, FILE* f) { + // XXX TODO + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 3474ae1..3878063 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -33,6 +33,8 @@ int nw_config_create(struct nw_config** config); + struct nw_config* nw_config_ref(struct nw_config* config); + struct nw_config* nw_config_unref(struct nw_config* config); + ++int nw_config_flush(struct nw_config* config); ++ + int nw_config_readf(struct nw_config** config, FILE* f); + int nw_config_read(struct nw_config** config, const char* path); + +-- +2.39.2 + diff --git a/network/patches/0167-networkd-Change-config-read-functions-to-not-create-.patch b/network/patches/0167-networkd-Change-config-read-functions-to-not-create-.patch new file mode 100644 index 000000000..5cc42ff66 --- /dev/null +++ b/network/patches/0167-networkd-Change-config-read-functions-to-not-create-.patch @@ -0,0 +1,70 @@ +From 3239c3b1a98103e79ae7ab524fc12386a781249f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 22:03:29 +0000 +Subject: [PATCH 167/304] networkd: Change config read functions to not create + a new instance + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 24 ++---------------------- + src/networkd/config.h | 4 ++-- + 2 files changed, 4 insertions(+), 24 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index a11ee1c..0048e44 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -124,33 +124,13 @@ int nw_config_flush(struct nw_config* config) { + return 0; + } + +-static int nw_config_parse(struct nw_config* config, FILE* f) { ++int nw_config_readf(struct nw_config* config, FILE* f) { + // XXX TODO + + return 0; + } + +-int nw_config_readf(struct nw_config** config, FILE* f) { +- int r; +- +- // Create a new config object +- r = nw_config_create(config); +- if (r) +- return r; +- +- // Parse the configuration +- r = nw_config_parse(*config, f); +- if (r) +- goto ERROR; +- +- return 0; +- +-ERROR: +- nw_config_free(*config); +- return r; +-} +- +-int nw_config_read(struct nw_config** config, const char* path) { ++int nw_config_read(struct nw_config* config, const char* path) { + FILE* f = NULL; + int r; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 3878063..c4f9125 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -35,8 +35,8 @@ struct nw_config* nw_config_unref(struct nw_config* config); + + int nw_config_flush(struct nw_config* config); + +-int nw_config_readf(struct nw_config** config, FILE* f); +-int nw_config_read(struct nw_config** config, const char* path); ++int nw_config_readf(struct nw_config* config, FILE* f); ++int nw_config_read(struct nw_config* config, const char* path); + + int nw_config_writef(struct nw_config* config, FILE* f); + int nw_config_write(struct nw_config* config, const char* path); +-- +2.39.2 + diff --git a/network/patches/0168-networkd-Store-the-path-with-the-configuration-objec.patch b/network/patches/0168-networkd-Store-the-path-with-the-configuration-objec.patch new file mode 100644 index 000000000..5b745e3f8 --- /dev/null +++ b/network/patches/0168-networkd-Store-the-path-with-the-configuration-objec.patch @@ -0,0 +1,200 @@ +From b076fa8b6b7aa4b5746b8ef01469e074b6a228ae Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 22:37:06 +0000 +Subject: [PATCH 168/304] networkd: Store the path with the configuration + object + +This makes it easier to call read and write functions without +re-composing the path again and again... + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 64 +++++++++++++++++++++++++++++++++++++------ + src/networkd/config.h | 11 ++++---- + src/networkd/daemon.c | 2 +- + 3 files changed, 61 insertions(+), 16 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 0048e44..e531ec6 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -19,6 +19,7 @@ + #############################################################################*/ + + #include ++#include + #include + #include + #include +@@ -38,6 +39,9 @@ struct nw_config_entry { + struct nw_config { + int nrefs; + ++ // The path to the configuration file ++ char path[PATH_MAX]; ++ + STAILQ_HEAD(entries, nw_config_entry) entries; + }; + +@@ -80,7 +84,9 @@ static void nw_config_free(struct nw_config* config) { + free(config); + } + +-int nw_config_create(struct nw_config** config) { ++int nw_config_create(struct nw_config** config, const char* path) { ++ int r; ++ + struct nw_config* c = calloc(1, sizeof(*c)); + if (!c) + return 1; +@@ -91,9 +97,26 @@ int nw_config_create(struct nw_config** config) { + // Initialise entries + STAILQ_INIT(&c->entries); + ++ // Store the path ++ if (path) { ++ r = nw_string_set(c->path, path); ++ if (r) ++ goto ERROR; ++ ++ // Try to read the configuration from path ++ r = nw_config_read(c); ++ if (r) ++ goto ERROR; ++ } ++ + *config = c; + + return 0; ++ ++ERROR: ++ nw_config_free(c); ++ ++ return r; + } + + struct nw_config* nw_config_ref(struct nw_config* config) { +@@ -110,6 +133,13 @@ struct nw_config* nw_config_unref(struct nw_config* config) { + return NULL; + } + ++const char* nw_config_path(struct nw_config* config) { ++ if (*config->path) ++ return config->path; ++ ++ return NULL; ++} ++ + int nw_config_flush(struct nw_config* config) { + struct nw_config_entry* entry = NULL; + +@@ -124,20 +154,30 @@ int nw_config_flush(struct nw_config* config) { + return 0; + } + +-int nw_config_readf(struct nw_config* config, FILE* f) { ++static int nw_config_readf(struct nw_config* config, FILE* f) { + // XXX TODO + + return 0; + } + +-int nw_config_read(struct nw_config* config, const char* path) { ++int nw_config_read(struct nw_config* config) { + FILE* f = NULL; + int r; + ++ // We cannot read if path is not set ++ if (!*config->path) { ++ errno = ENOTSUP; ++ return 1; ++ } ++ + // Open the file +- f = fopen(path, "r"); ++ f = fopen(config->path, "r"); + if (!f) { +- ERROR("Could not read configuration file %s: %m\n", path); ++ // Silently ignore if the file does not exist ++ if (errno == ENOENT) ++ return 0; ++ ++ ERROR("Could not read configuration file %s: %m\n", config->path); + r = 1; + goto ERROR; + } +@@ -152,7 +192,7 @@ ERROR: + return r; + } + +-int nw_config_writef(struct nw_config* config, FILE* f) { ++static int nw_config_writef(struct nw_config* config, FILE* f) { + struct nw_config_entry* entry = NULL; + int r; + +@@ -172,12 +212,18 @@ int nw_config_writef(struct nw_config* config, FILE* f) { + return 0; + } + +-int nw_config_write(struct nw_config* config, const char* path) { ++int nw_config_write(struct nw_config* config) { + int r; + +- FILE* f = fopen(path, "w"); ++ // We cannot write if path is not set ++ if (!*config->path) { ++ errno = ENOTSUP; ++ return 1; ++ } ++ ++ FILE* f = fopen(config->path, "w"); + if (!f) { +- ERROR("Failed to open %s for writing: %m\n", path); ++ ERROR("Failed to open %s for writing: %m\n", config->path); + r = 1; + goto ERROR; + } +diff --git a/src/networkd/config.h b/src/networkd/config.h +index c4f9125..5b9910b 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -28,18 +28,17 @@ + + struct nw_config; + +-int nw_config_create(struct nw_config** config); ++int nw_config_create(struct nw_config** config, const char* path); + + struct nw_config* nw_config_ref(struct nw_config* config); + struct nw_config* nw_config_unref(struct nw_config* config); + +-int nw_config_flush(struct nw_config* config); ++const char* nw_config_path(struct nw_config* config); + +-int nw_config_readf(struct nw_config* config, FILE* f); +-int nw_config_read(struct nw_config* config, const char* path); ++int nw_config_flush(struct nw_config* config); + +-int nw_config_writef(struct nw_config* config, FILE* f); +-int nw_config_write(struct nw_config* config, const char* path); ++int nw_config_read(struct nw_config* config); ++int nw_config_write(struct nw_config* config); + + int nw_config_del(struct nw_config* config, const char* key); + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index b93877e..5b097c2 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -110,7 +110,7 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + + // Read configuration file +- r = nw_config_read(&daemon->config, CONFIG_DIR "/settings"); ++ r = nw_config_create(&daemon->config, CONFIG_DIR "/settings"); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0169-networkd-zones-Try-to-read-configuration-automatical.patch b/network/patches/0169-networkd-zones-Try-to-read-configuration-automatical.patch new file mode 100644 index 000000000..6d7eb9b40 --- /dev/null +++ b/network/patches/0169-networkd-zones-Try-to-read-configuration-automatical.patch @@ -0,0 +1,137 @@ +From 00b5de56ae30d4d8f0288ec160570ab6129aec79 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 22:39:34 +0000 +Subject: [PATCH 169/304] networkd: zones: Try to read configuration + automatically + +Signed-off-by: Michael Tremer +--- + src/networkd/string.h | 25 ++++++++++++++++++++++ + src/networkd/zone.c | 49 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 74 insertions(+) + +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 52b5add..4ae2dbf 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -26,6 +26,9 @@ + #include + #include + ++#define nw_string_vformat(s, format, ...) \ ++ __nw_string_vformat(s, sizeof(s), format, __VA_ARGS__) ++ + static inline int __nw_string_vformat(char* s, const size_t length, + const char* format, va_list args) { + // Write string to buffer +@@ -76,4 +79,26 @@ static inline int __nw_string_set(char* s, const size_t length, const char* valu + return __nw_string_format(s, length, "%s", value); + } + ++/* ++ Paths ++*/ ++ ++#define nw_path_join(s, first, second) \ ++ __nw_path_join(s, sizeof(s), first, second) ++ ++static inline int __nw_path_join(char* s, const size_t length, ++ const char* first, const char* second) { ++ if (!first) ++ return __nw_string_format(s, length, "%s", second); ++ ++ if (!second) ++ return __nw_string_format(s, length, "%s", first); ++ ++ // Remove leading slashes from second argument ++ while (*second == '/') ++ second++; ++ ++ return __nw_string_format(s, length, "%s/%s", first, second); ++} ++ + #endif /* NETWORKD_STRING_H */ +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 5066c4b..4790d33 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -18,6 +18,7 @@ + # # + #############################################################################*/ + ++#include + #include + + #include "config.h" +@@ -33,6 +34,32 @@ struct nw_zone { + struct nw_config *config; + }; + ++#define nw_zone_path(zone, path, format, ...) \ ++ __nw_zone_path(zone, path, sizeof(path), format, __VA_ARGS__) ++ ++static int __nw_zone_path(struct nw_zone* zone, char* p, const size_t length, ++ const char* format, ...) { ++ char prefix[NAME_MAX]; ++ char suffix[NAME_MAX]; ++ va_list args; ++ int r; ++ ++ // Format the prefix ++ r = nw_string_format(prefix, "%s/zones/%s", CONFIG_DIR, zone->name); ++ if (r) ++ return r; ++ ++ // Format the suffix ++ va_start(args, format); ++ r = nw_string_vformat(suffix, format, args); ++ va_end(args); ++ if (r) ++ return r; ++ ++ // Join the two parts together ++ return __nw_path_join(p, length, prefix, suffix); ++} ++ + static void nw_zone_free(struct nw_zone* zone) { + if (zone->config) + nw_config_unref(zone->config); +@@ -40,6 +67,23 @@ static void nw_zone_free(struct nw_zone* zone) { + free(zone); + } + ++static int nw_zone_setup(struct nw_zone* zone) { ++ char path[PATH_MAX]; ++ int r; ++ ++ // Compose the path to the main configuration file ++ r = nw_zone_path(zone, path, "%s", "settings"); ++ if (r) ++ return r; ++ ++ // Initialize the configuration ++ r = nw_config_create(&zone->config, path); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + int nw_zone_create(struct nw_zone** zone, const char* name) { + int r; + +@@ -56,6 +100,11 @@ int nw_zone_create(struct nw_zone** zone, const char* name) { + if (r) + goto ERROR; + ++ // Setup the zone ++ r = nw_zone_setup(z); ++ if (r) ++ goto ERROR; ++ + *zone = z; + return 0; + +-- +2.39.2 + diff --git a/network/patches/0170-networkd-Read-all-zones-from-configuration.patch b/network/patches/0170-networkd-Read-all-zones-from-configuration.patch new file mode 100644 index 000000000..bbf4a09c5 --- /dev/null +++ b/network/patches/0170-networkd-Read-all-zones-from-configuration.patch @@ -0,0 +1,201 @@ +From 19e74c9b5d7e9372a3ea9d27579ba8608626459d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 22:40:04 +0000 +Subject: [PATCH 170/304] networkd: Read all zones from configuration + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 131 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 130 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 5b097c2..86731d1 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -18,9 +18,11 @@ + # # + #############################################################################*/ + ++#include + #include + #include + #include ++#include + + #include + #include +@@ -30,6 +32,14 @@ + #include "config.h" + #include "daemon.h" + #include "logging.h" ++#include "zone.h" ++ ++struct nw_daemon_zone { ++ struct nw_zone* zone; ++ ++ // Link to the other zones ++ STAILQ_ENTRY(nw_daemon_zone) nodes; ++}; + + struct nw_daemon { + int nrefs; +@@ -41,6 +51,9 @@ struct nw_daemon { + + // DBus Connection + sd_bus* bus; ++ ++ // Zones ++ STAILQ_HEAD(zones, nw_daemon_zone) zones; + }; + + static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, +@@ -106,7 +119,85 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + return 0; + } + +-static int nw_daemon_setup(struct nw_daemon* daemon) { ++static int nw_daemon_load_zone_filter(const struct dirent* path) { ++ const char* fn = path->d_name; ++ ++ // Ignore everything starting with '.' ++ if (*fn == '.') ++ return 0; ++ ++ // Ignore anything that isn't a directory ++ if (path->d_type != DT_DIR) ++ return 0; ++ ++ return 1; ++} ++ ++static int nw_daemon_add_zone(struct nw_daemon* daemon, struct nw_zone* zone) { ++ // Allocate a new entry ++ struct nw_daemon_zone* entry = calloc(1, sizeof(*entry)); ++ if (!entry) ++ return 1; ++ ++ // Reference the zone ++ entry->zone = nw_zone_ref(zone); ++ ++ // Add it to the list ++ STAILQ_INSERT_TAIL(&daemon->zones, entry, nodes); ++ ++ return 0; ++} ++ ++static int nw_daemon_load_zones(struct nw_daemon* daemon) { ++ struct dirent** paths = NULL; ++ int n; ++ int r = 0; ++ ++ struct nw_zone* zone = NULL; ++ ++ // Scan the zones directory ++ n = scandir(CONFIG_DIR "/zones", &paths, nw_daemon_load_zone_filter, alphasort); ++ if (n < 0) { ++ ERROR("Could not load zones: %m\n"); ++ return 1; ++ } ++ ++ DEBUG("Found %d zone(s)\n", n); ++ ++ // Load all zones ++ for (int i = 0; i < n; i++) { ++ const char* name = paths[i]->d_name; ++ ++ DEBUG("Loading zone '%s'...\n", name); ++ ++ // Create a new zone object ++ r = nw_zone_create(&zone, name); ++ if (r) ++ goto ERROR; ++ ++ // Store the zone ++ r = nw_daemon_add_zone(daemon, zone); ++ if (r) { ++ nw_zone_unref(zone); ++ goto ERROR; ++ } ++ ++ nw_zone_unref(zone); ++ } ++ ++ERROR: ++ // Free paths ++ if (paths) { ++ for (int i = 0; i < n; i++) { ++ free(paths[i]); ++ } ++ free(paths); ++ } ++ ++ return r; ++} ++ ++static int nw_daemon_load_config(struct nw_daemon* daemon) { + int r; + + // Read configuration file +@@ -114,6 +205,22 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Load zones ++ r = nw_daemon_load_zones(daemon); ++ if (r) ++ return r; ++ ++ return r; ++} ++ ++static int nw_daemon_setup(struct nw_daemon* daemon) { ++ int r; ++ ++ // Read the configuration ++ r = nw_daemon_load_config(daemon); ++ if (r) ++ return r; ++ + // Setup the event loop + r = nw_daemon_setup_loop(daemon); + if (r) +@@ -137,6 +244,9 @@ int nw_daemon_create(struct nw_daemon** daemon) { + // Initialize reference counter + d->nrefs = 1; + ++ // Initialize zones ++ STAILQ_INIT(&d->zones); ++ + // Setup the daemon + r = nw_daemon_setup(d); + if (r) +@@ -153,7 +263,26 @@ ERROR: + return r; + } + ++static void nw_daemon_free_zones(struct nw_daemon* daemon) { ++ struct nw_daemon_zone* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&daemon->zones)) { ++ entry = STAILQ_FIRST(&daemon->zones); ++ ++ // Dereference the zone ++ nw_zone_unref(entry->zone); ++ ++ // Remove the entry from the list ++ STAILQ_REMOVE_HEAD(&daemon->zones, nodes); ++ ++ // Free the entry ++ free(entry); ++ } ++} ++ + static void nw_daemon_free(struct nw_daemon* daemon) { ++ nw_daemon_free_zones(daemon); ++ + if (daemon->config) + nw_config_unref(daemon->config); + if (daemon->bus) +-- +2.39.2 + diff --git a/network/patches/0171-networkd-bus-Create-a-unified-function-to-register-a.patch b/network/patches/0171-networkd-bus-Create-a-unified-function-to-register-a.patch new file mode 100644 index 000000000..3cca53689 --- /dev/null +++ b/network/patches/0171-networkd-bus-Create-a-unified-function-to-register-a.patch @@ -0,0 +1,128 @@ +From 9806a600f4cdf68aa2c0e509e40be6ed9ad08b44 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 23:04:27 +0000 +Subject: [PATCH 171/304] networkd: bus: Create a unified function to register + an interface + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 52 +++++++++++++++++++++++++++++++++------------- + src/networkd/bus.h | 14 +++++++++++-- + 2 files changed, 49 insertions(+), 17 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 5224aaa..eab123c 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -38,6 +38,19 @@ static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* err + return sd_bus_reply_method_return(m, NULL); + } + ++static const sd_bus_vtable daemon_vtable[] = { ++ SD_BUS_VTABLE_START(0), ++ SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, ++ nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_VTABLE_END, ++}; ++ ++const struct nw_bus_implementation daemon_implementation = { ++ .path = "/org/ipfire/network1", ++ .interface = "org.ipfire.network1", ++ .vtables = BUS_VTABLES(daemon_vtable), ++}; ++ + static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { + struct nw_daemon* daemon = (struct nw_daemon*)data; + +@@ -46,13 +59,6 @@ static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) + return 0; + } + +-static const sd_bus_vtable daemon_vtable[] = { +- SD_BUS_VTABLE_START(0), +- SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, +- nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_VTABLE_END, +-}; +- + int nw_bus_connect(sd_bus* bus, sd_event* loop) { + int r; + +@@ -117,16 +123,13 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop) { + return 1; + } + +- // Register any functions +- r = sd_bus_add_object_vtable(bus, NULL, +- NETWORKD_BUS_OBJECT_PATH, NETWORKD_BUS_INTERFACE_NAME, daemon_vtable, NULL); +- if (r < 0) { +- ERROR("Could not add object vtable: %s\n", strerror(-r)); +- return 1; +- } ++ // Register the implementation ++ r = nw_bus_register_implementation(bus, &daemon_implementation, NULL); ++ if (r) ++ return r; + + // Request interface name +- r = sd_bus_request_name_async(bus, NULL, NETWORKD_BUS_INTERFACE_NAME, 0, NULL, NULL); ++ r = sd_bus_request_name_async(bus, NULL, "org.ipfire.network1", 0, NULL, NULL); + if (r < 0) { + ERROR("Could not request bus name: %s\n", strerror(-r)); + return 1; +@@ -149,3 +152,22 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop) { + + return 0; + } ++ ++int nw_bus_register_implementation(sd_bus* bus, ++ const struct nw_bus_implementation* impl, void* data) { ++ int r; ++ ++ DEBUG("Registering bus object implementation for path=%s iface=%s\n", ++ impl->path, impl->interface); ++ ++ for (const sd_bus_vtable** vtable = impl->vtables; vtable && *vtable; vtable++) { ++ r = sd_bus_add_object_vtable(bus, NULL, impl->path, impl->interface, *vtable, data); ++ if (r < 0) { ++ ERROR("Could not register bus path %s with interface %s: %m\n", ++ impl->path, impl->interface); ++ return 1; ++ } ++ } ++ ++ return 0; ++} +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 90c1556..05846e5 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -22,8 +22,6 @@ + #define NETWORKD_BUS_H + + #define NETWORKD_BUS_DESCRIPTION "networkd" +-#define NETWORKD_BUS_OBJECT_PATH "/org/ipfire/network1" +-#define NETWORKD_BUS_INTERFACE_NAME "org.ipfire.network1" + + #define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/run/dbus/system_bus_socket" + +@@ -32,4 +30,16 @@ + + int nw_bus_connect(sd_bus* bus, sd_event* loop); + ++struct nw_bus_implementation { ++ const char* path; ++ const char* interface; ++ ++ const sd_bus_vtable** vtables; ++}; ++ ++#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL }) ++ ++int nw_bus_register_implementation(sd_bus* bus, ++ const struct nw_bus_implementation* impl, void* data); ++ + #endif /* NETWORKD_BUS_H */ +-- +2.39.2 + diff --git a/network/patches/0172-networkd-Add-a-dummy-bus-implementation-for-zones.patch b/network/patches/0172-networkd-Add-a-dummy-bus-implementation-for-zones.patch new file mode 100644 index 000000000..6aeef4273 --- /dev/null +++ b/network/patches/0172-networkd-Add-a-dummy-bus-implementation-for-zones.patch @@ -0,0 +1,99 @@ +From ed00ef209405d6da4478a8eb050e8792187a2619 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 23:19:03 +0000 +Subject: [PATCH 172/304] networkd: Add a dummy bus implementation for zones + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 +++- + src/networkd/zone-bus.c | 27 +++++++++++++++++++++++++++ + src/networkd/zone-bus.h | 28 ++++++++++++++++++++++++++++ + 3 files changed, 58 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/zone-bus.c + create mode 100644 src/networkd/zone-bus.h + +diff --git a/Makefile.am b/Makefile.am +index 3a3f82c..2046fef 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -318,7 +318,9 @@ dist_networkd_SOURCES = \ + src/networkd/main.c \ + src/networkd/string.h \ + src/networkd/zone.c \ +- src/networkd/zone.h ++ src/networkd/zone.h \ ++ src/networkd/zone-bus.c \ ++ src/networkd/zone-bus.h + + networkd_CPPFLAGS = \ + $(AM_CPPFLAGS) \ +diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c +new file mode 100644 +index 0000000..97396c5 +--- /dev/null ++++ b/src/networkd/zone-bus.c +@@ -0,0 +1,27 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include "bus.h" ++#include "zone-bus.h" ++ ++const struct nw_bus_implementation zone_bus_impl = { ++ "/org/ipfire/network1/zone", ++ "org.ipfire.network1.Zone", ++}; +diff --git a/src/networkd/zone-bus.h b/src/networkd/zone-bus.h +new file mode 100644 +index 0000000..0d5583e +--- /dev/null ++++ b/src/networkd/zone-bus.h +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_ZONE_BUS_H ++#define NETWORKD_ZONE_BUS_H ++ ++#include "bus.h" ++ ++extern const struct nw_bus_implementation zone_bus_impl; ++ ++#endif /* NETWORKD_ZONE_BUS_H */ +-- +2.39.2 + diff --git a/network/patches/0173-networkd-Pass-daemon-to-all-functions-called-by-the-.patch b/network/patches/0173-networkd-Pass-daemon-to-all-functions-called-by-the-.patch new file mode 100644 index 000000000..d8ff55d71 --- /dev/null +++ b/network/patches/0173-networkd-Pass-daemon-to-all-functions-called-by-the-.patch @@ -0,0 +1,66 @@ +From eaeca0f9f44f0c791f21add7162ee6c7eea5ee4a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Feb 2023 23:25:17 +0000 +Subject: [PATCH 173/304] networkd: Pass daemon to all functions called by the + bus + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 4 ++-- + src/networkd/bus.h | 4 +++- + src/networkd/daemon.c | 2 +- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index eab123c..e854f7b 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -59,7 +59,7 @@ static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) + return 0; + } + +-int nw_bus_connect(sd_bus* bus, sd_event* loop) { ++int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon) { + int r; + + // Create a bus object +@@ -124,7 +124,7 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop) { + } + + // Register the implementation +- r = nw_bus_register_implementation(bus, &daemon_implementation, NULL); ++ r = nw_bus_register_implementation(bus, &daemon_implementation, daemon); + if (r) + return r; + +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 05846e5..55e65b8 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -28,7 +28,9 @@ + #include + #include + +-int nw_bus_connect(sd_bus* bus, sd_event* loop); ++#include "daemon.h" ++ ++int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon); + + struct nw_bus_implementation { + const char* path; +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 86731d1..a478e60 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -227,7 +227,7 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + return r; + + // Connect to the system bus +- r = nw_bus_connect(daemon->bus, daemon->loop); ++ r = nw_bus_connect(daemon->bus, daemon->loop, daemon); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0174-networkd-Move-zone-list-into-an-own-object.patch b/network/patches/0174-networkd-Move-zone-list-into-an-own-object.patch new file mode 100644 index 000000000..6145c971e --- /dev/null +++ b/network/patches/0174-networkd-Move-zone-list-into-an-own-object.patch @@ -0,0 +1,493 @@ +From 0c8e7342a7da002e877ed445d0223453acd4b93d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 2 Feb 2023 00:38:13 +0000 +Subject: [PATCH 174/304] networkd: Move zone list into an own object + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/daemon.c | 121 ++---------------------- + src/networkd/daemon.h | 4 + + src/networkd/zones.c | 213 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/zones.h | 35 +++++++ + 5 files changed, 263 insertions(+), 112 deletions(-) + create mode 100644 src/networkd/zones.c + create mode 100644 src/networkd/zones.h + +diff --git a/Makefile.am b/Makefile.am +index 2046fef..ae4cb85 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -317,6 +317,8 @@ dist_networkd_SOURCES = \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/string.h \ ++ src/networkd/zones.c \ ++ src/networkd/zones.h \ + src/networkd/zone.c \ + src/networkd/zone.h \ + src/networkd/zone-bus.c \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index a478e60..588aa4e 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -18,11 +18,8 @@ + # # + #############################################################################*/ + +-#include + #include + #include +-#include +-#include + + #include + #include +@@ -33,13 +30,7 @@ + #include "daemon.h" + #include "logging.h" + #include "zone.h" +- +-struct nw_daemon_zone { +- struct nw_zone* zone; +- +- // Link to the other zones +- STAILQ_ENTRY(nw_daemon_zone) nodes; +-}; ++#include "zones.h" + + struct nw_daemon { + int nrefs; +@@ -53,7 +44,7 @@ struct nw_daemon { + sd_bus* bus; + + // Zones +- STAILQ_HEAD(zones, nw_daemon_zone) zones; ++ struct nw_zones* zones; + }; + + static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, +@@ -119,84 +110,6 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + return 0; + } + +-static int nw_daemon_load_zone_filter(const struct dirent* path) { +- const char* fn = path->d_name; +- +- // Ignore everything starting with '.' +- if (*fn == '.') +- return 0; +- +- // Ignore anything that isn't a directory +- if (path->d_type != DT_DIR) +- return 0; +- +- return 1; +-} +- +-static int nw_daemon_add_zone(struct nw_daemon* daemon, struct nw_zone* zone) { +- // Allocate a new entry +- struct nw_daemon_zone* entry = calloc(1, sizeof(*entry)); +- if (!entry) +- return 1; +- +- // Reference the zone +- entry->zone = nw_zone_ref(zone); +- +- // Add it to the list +- STAILQ_INSERT_TAIL(&daemon->zones, entry, nodes); +- +- return 0; +-} +- +-static int nw_daemon_load_zones(struct nw_daemon* daemon) { +- struct dirent** paths = NULL; +- int n; +- int r = 0; +- +- struct nw_zone* zone = NULL; +- +- // Scan the zones directory +- n = scandir(CONFIG_DIR "/zones", &paths, nw_daemon_load_zone_filter, alphasort); +- if (n < 0) { +- ERROR("Could not load zones: %m\n"); +- return 1; +- } +- +- DEBUG("Found %d zone(s)\n", n); +- +- // Load all zones +- for (int i = 0; i < n; i++) { +- const char* name = paths[i]->d_name; +- +- DEBUG("Loading zone '%s'...\n", name); +- +- // Create a new zone object +- r = nw_zone_create(&zone, name); +- if (r) +- goto ERROR; +- +- // Store the zone +- r = nw_daemon_add_zone(daemon, zone); +- if (r) { +- nw_zone_unref(zone); +- goto ERROR; +- } +- +- nw_zone_unref(zone); +- } +- +-ERROR: +- // Free paths +- if (paths) { +- for (int i = 0; i < n; i++) { +- free(paths[i]); +- } +- free(paths); +- } +- +- return r; +-} +- + static int nw_daemon_load_config(struct nw_daemon* daemon) { + int r; + +@@ -206,7 +119,7 @@ static int nw_daemon_load_config(struct nw_daemon* daemon) { + return r; + + // Load zones +- r = nw_daemon_load_zones(daemon); ++ r = nw_zones_load(&daemon->zones); + if (r) + return r; + +@@ -244,9 +157,6 @@ int nw_daemon_create(struct nw_daemon** daemon) { + // Initialize reference counter + d->nrefs = 1; + +- // Initialize zones +- STAILQ_INIT(&d->zones); +- + // Setup the daemon + r = nw_daemon_setup(d); + if (r) +@@ -263,26 +173,9 @@ ERROR: + return r; + } + +-static void nw_daemon_free_zones(struct nw_daemon* daemon) { +- struct nw_daemon_zone* entry = NULL; +- +- while (!STAILQ_EMPTY(&daemon->zones)) { +- entry = STAILQ_FIRST(&daemon->zones); +- +- // Dereference the zone +- nw_zone_unref(entry->zone); +- +- // Remove the entry from the list +- STAILQ_REMOVE_HEAD(&daemon->zones, nodes); +- +- // Free the entry +- free(entry); +- } +-} +- + static void nw_daemon_free(struct nw_daemon* daemon) { +- nw_daemon_free_zones(daemon); +- ++ if (daemon->zones) ++ nw_zones_unref(daemon->zones); + if (daemon->config) + nw_config_unref(daemon->config); + if (daemon->bus) +@@ -342,3 +235,7 @@ int nw_daemon_reload(struct nw_daemon* daemon) { + + return 0; + } ++ ++struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon) { ++ return nw_zones_ref(daemon->zones); ++} +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 5b14ef3..bc69795 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_DAEMON_H + #define NETWORKD_DAEMON_H + ++#include "zone.h" ++ + struct nw_daemon; + + int nw_daemon_create(struct nw_daemon** daemon); +@@ -32,4 +34,6 @@ int nw_daemon_run(struct nw_daemon* daemon); + + int nw_daemon_reload(struct nw_daemon* daemon); + ++struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon); ++ + #endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +new file mode 100644 +index 0000000..7d04267 +--- /dev/null ++++ b/src/networkd/zones.c +@@ -0,0 +1,213 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++#include ++ ++#include "logging.h" ++#include "zone.h" ++#include "zones.h" ++ ++struct nw_zones_entry { ++ struct nw_zone* zone; ++ ++ // Link to the other entries ++ STAILQ_ENTRY(nw_zones_entry) nodes; ++}; ++ ++struct nw_zones { ++ int nrefs; ++ ++ STAILQ_HEAD(entries, nw_zones_entry) entries; ++}; ++ ++static int nw_zones_create(struct nw_zones** zones) { ++ struct nw_zones* z = calloc(1, sizeof(*z)); ++ if (!z) ++ return 1; ++ ++ // Initialize the reference counter ++ z->nrefs = 1; ++ ++ // Initialize entries ++ STAILQ_INIT(&z->entries); ++ ++ // Reference the pointer ++ *zones = z; ++ ++ return 0; ++} ++ ++static void nw_zones_free(struct nw_zones* zones) { ++ struct nw_zones_entry* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&zones->entries)) { ++ entry = STAILQ_FIRST(&zones->entries); ++ ++ // Dereference the zone ++ nw_zone_unref(entry->zone); ++ ++ // Remove the entry from the list ++ STAILQ_REMOVE_HEAD(&zones->entries, nodes); ++ ++ // Free the entry ++ free(entry); ++ } ++} ++ ++struct nw_zones* nw_zones_ref(struct nw_zones* zones) { ++ zones->nrefs++; ++ ++ return zones; ++} ++ ++struct nw_zones* nw_zones_unref(struct nw_zones* zones) { ++ if (--zones->nrefs > 0) ++ return zones; ++ ++ nw_zones_free(zones); ++ return NULL; ++} ++ ++static int nw_zones_add_zone(struct nw_zones* zones, struct nw_zone* zone) { ++ // Allocate a new entry ++ struct nw_zones_entry* entry = calloc(1, sizeof(*entry)); ++ if (!entry) ++ return 1; ++ ++ // Reference the zone ++ entry->zone = nw_zone_ref(zone); ++ ++ // Add it to the list ++ STAILQ_INSERT_TAIL(&zones->entries, entry, nodes); ++ ++ return 0; ++} ++ ++static int nw_zones_load_filter(const struct dirent* path) { ++ const char* fn = path->d_name; ++ ++ // Ignore everything starting with '.' ++ if (*fn == '.') ++ return 0; ++ ++ // Ignore anything that isn't a directory ++ if (path->d_type != DT_DIR) ++ return 0; ++ ++ return 1; ++} ++ ++static int __nw_zones_load(struct nw_zones* zones) { ++ struct dirent** paths = NULL; ++ int n; ++ int r = 0; ++ ++ struct nw_zone* zone = NULL; ++ ++ // Scan the zones directory ++ n = scandir(CONFIG_DIR "/zones", &paths, nw_zones_load_filter, alphasort); ++ if (n < 0) { ++ ERROR("Could not load zones: %m\n"); ++ return 1; ++ } ++ ++ DEBUG("Found %d zone(s)\n", n); ++ ++ // Load all zones ++ for (int i = 0; i < n; i++) { ++ const char* name = paths[i]->d_name; ++ ++ DEBUG("Loading zone '%s'...\n", name); ++ ++ // Create a new zone object ++ r = nw_zone_create(&zone, name); ++ if (r) ++ goto ERROR; ++ ++ // Store the zone ++ r = nw_zones_add_zone(zones, zone); ++ if (r) { ++ nw_zone_unref(zone); ++ goto ERROR; ++ } ++ ++ nw_zone_unref(zone); ++ } ++ ++ERROR: ++ // Free paths ++ if (paths) { ++ for (int i = 0; i < n; i++) { ++ free(paths[i]); ++ } ++ free(paths); ++ } ++ ++ return r; ++} ++ ++int nw_zones_load(struct nw_zones** zones) { ++ int r; ++ ++ // Create a new zones object ++ r = nw_zones_create(zones); ++ if (r) ++ return r; ++ ++ // Load all zones ++ r = __nw_zones_load(*zones); ++ if (r) ++ goto ERROR; ++ ++ return 0; ++ ++ERROR: ++ nw_zones_unref(*zones); ++ return r; ++} ++ ++size_t nw_zones_num(struct nw_zones* zones) { ++ struct nw_zones_entry* entry = NULL; ++ size_t length = 0; ++ ++ // Count all zones ++ STAILQ_FOREACH(entry, &zones->entries, nodes) ++ length++; ++ ++ return length; ++} ++ ++struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) { ++ struct nw_zones_entry* entry = NULL; ++ ++ STAILQ_FOREACH(entry, &zones->entries, nodes) { ++ const char* __name = nw_zone_name(entry->zone); ++ ++ // If the name matches, return a reference to the zone ++ if (strcmp(name, __name) == 0) ++ return nw_zone_ref(entry->zone); ++ } ++ ++ // No match found ++ return NULL; ++} +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +new file mode 100644 +index 0000000..0d34c3e +--- /dev/null ++++ b/src/networkd/zones.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_ZONES_H ++#define NETWORKD_ZONES_H ++ ++struct nw_zones; ++ ++struct nw_zones* nw_zones_ref(struct nw_zones* zones); ++struct nw_zones* nw_zones_unref(struct nw_zones* zones); ++ ++int nw_zones_load(struct nw_zones** zones); ++ ++size_t nw_zones_num(struct nw_zones* zones); ++ ++struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name); ++ ++#endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0175-networkd-Implement-enumerating-zones-on-the-bus.patch b/network/patches/0175-networkd-Implement-enumerating-zones-on-the-bus.patch new file mode 100644 index 000000000..490d257c6 --- /dev/null +++ b/network/patches/0175-networkd-Implement-enumerating-zones-on-the-bus.patch @@ -0,0 +1,238 @@ +From ebc65f19ecbf67f9c8a739316afe4892d4f6a732 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 2 Feb 2023 00:53:21 +0000 +Subject: [PATCH 175/304] networkd: Implement enumerating zones on the bus + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 18 +++++++++++++++++ + src/networkd/bus.h | 3 +++ + src/networkd/zone-bus.c | 29 +++++++++++++++++++++++++++ + src/networkd/zone.c | 14 +++++++++++++ + src/networkd/zone.h | 2 ++ + src/networkd/zones.c | 44 +++++++++++++++++++++++++++++++++++++++++ + src/networkd/zones.h | 2 ++ + 7 files changed, 112 insertions(+) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index e854f7b..26876fa 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -27,6 +27,7 @@ + #include "bus.h" + #include "daemon.h" + #include "logging.h" ++#include "zone-bus.h" + + static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) { + struct nw_daemon* daemon = (struct nw_daemon*)data; +@@ -49,6 +50,7 @@ const struct nw_bus_implementation daemon_implementation = { + .path = "/org/ipfire/network1", + .interface = "org.ipfire.network1", + .vtables = BUS_VTABLES(daemon_vtable), ++ .children = BUS_IMPLEMENTATIONS(&zone_bus_impl), + }; + + static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { +@@ -169,5 +171,21 @@ int nw_bus_register_implementation(sd_bus* bus, + } + } + ++ // Register the node enumerator ++ if (impl->node_enumerator) { ++ r = sd_bus_add_node_enumerator(bus, NULL, impl->path, impl->node_enumerator, data); ++ if (r < 0) { ++ ERROR("Could not add the node enumerator for %s: %m\n", impl->path); ++ return 1; ++ } ++ } ++ ++ // Register any child implementations ++ for (int i = 0; impl->children && impl->children[i]; i++) { ++ r = nw_bus_register_implementation(bus, impl->children[i], data); ++ if (r) ++ return r; ++ } ++ + return 0; + } +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 55e65b8..6232ebb 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -37,8 +37,11 @@ struct nw_bus_implementation { + const char* interface; + + const sd_bus_vtable** vtables; ++ sd_bus_node_enumerator_t node_enumerator; ++ const struct nw_bus_implementation** children; + }; + ++#define BUS_IMPLEMENTATIONS(...) ((const struct nw_bus_implementation* []) { __VA_ARGS__, NULL }) + #define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL }) + + int nw_bus_register_implementation(sd_bus* bus, +diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c +index 97396c5..ebd8789 100644 +--- a/src/networkd/zone-bus.c ++++ b/src/networkd/zone-bus.c +@@ -19,9 +19,38 @@ + #############################################################################*/ + + #include "bus.h" ++#include "daemon.h" ++#include "logging.h" ++#include "zone.h" + #include "zone-bus.h" ++#include "zones.h" ++ ++static int nw_zone_node_enumerator(sd_bus* bus, const char* path, void* data, ++ char*** nodes, sd_bus_error* error) { ++ int r; ++ ++ DEBUG("Enumerating zones...\n"); ++ ++ // Fetch a reference to the daemon ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Fetch zones ++ struct nw_zones* zones = nw_daemon_zones(daemon); ++ ++ // Make bus paths for all zones ++ r = nw_zones_bus_paths(zones, nodes); ++ if (r) ++ goto ERROR; ++ ++ERROR: ++ nw_zones_unref(zones); ++ ++ return r; ++} + + const struct nw_bus_implementation zone_bus_impl = { + "/org/ipfire/network1/zone", + "org.ipfire.network1.Zone", ++ //.fallback_vtables = BUS_FALLBACK_VTABLES({zone_bus_vtable, nw_zone_object_find}), ++ .node_enumerator = nw_zone_node_enumerator, + }; +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 4790d33..f78334e 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + #include "config.h" + #include "string.h" + #include "zone.h" +@@ -130,3 +132,15 @@ struct nw_zone* nw_zone_unref(struct nw_zone* zone) { + const char* nw_zone_name(struct nw_zone* zone) { + return zone->name; + } ++ ++char* nw_zone_bus_path(struct nw_zone* zone) { ++ char* p = NULL; ++ int r; ++ ++ // Encode the bus path ++ r = sd_bus_path_encode("/org/ipfire/network1/zone", zone->name, &p); ++ if (r < 0) ++ return NULL; ++ ++ return p; ++} +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 78287ab..081a720 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -32,4 +32,6 @@ struct nw_zone* nw_zone_unref(struct nw_zone* zone); + + const char* nw_zone_name(struct nw_zone* zone); + ++char* nw_zone_bus_path(struct nw_zone* zone); ++ + #endif /* NETWORKD_ZONE_H */ +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 7d04267..4f739f5 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -37,7 +37,11 @@ struct nw_zones_entry { + struct nw_zones { + int nrefs; + ++ // Zone Entries + STAILQ_HEAD(entries, nw_zones_entry) entries; ++ ++ // A counter of the zone entries ++ unsigned int num; + }; + + static int nw_zones_create(struct nw_zones** zones) { +@@ -100,6 +104,9 @@ static int nw_zones_add_zone(struct nw_zones* zones, struct nw_zone* zone) { + // Add it to the list + STAILQ_INSERT_TAIL(&zones->entries, entry, nodes); + ++ // Increment the counter ++ zones->num++; ++ + return 0; + } + +@@ -211,3 +218,40 @@ struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) { + // No match found + return NULL; + } ++ ++int nw_zones_bus_paths(struct nw_zones* zones, char*** paths) { ++ struct nw_zones_entry* entry = NULL; ++ char* path = NULL; ++ ++ // Allocate an array for all paths ++ char** p = calloc(zones->num + 1, sizeof(*p)); ++ if (!p) ++ return 1; ++ ++ unsigned int i = 0; ++ ++ // Walk through all zones ++ STAILQ_FOREACH(entry, &zones->entries, nodes) { ++ // Generate the bus path ++ path = nw_zone_bus_path(entry->zone); ++ if (!path) ++ goto ERROR; ++ ++ // Append the bus path to the array ++ p[i++] = path; ++ } ++ ++ // Return pointer ++ *paths = p; ++ ++ return 0; ++ ++ERROR: ++ if (p) { ++ for (char** e = p; *e; e++) ++ free(*e); ++ free(p); ++ } ++ ++ return 1; ++} +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index 0d34c3e..6e2686d 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -32,4 +32,6 @@ size_t nw_zones_num(struct nw_zones* zones); + + struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name); + ++int nw_zones_bus_paths(struct nw_zones* zones, char*** paths); ++ + #endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0176-networkd-Return-zone-when-it-is-being-accessed-by-it.patch b/network/patches/0176-networkd-Return-zone-when-it-is-being-accessed-by-it.patch new file mode 100644 index 000000000..0f442e34b --- /dev/null +++ b/network/patches/0176-networkd-Return-zone-when-it-is-being-accessed-by-it.patch @@ -0,0 +1,159 @@ +From bd9ffd6a19a8bf403a534998e0c2d3e2bf9b51c1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 2 Feb 2023 01:07:51 +0000 +Subject: [PATCH 176/304] networkd: Return zone when it is being accessed by + its path + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 12 ++++++++++++ + src/networkd/bus.h | 8 +++++++- + src/networkd/daemon.c | 11 +++++++++++ + src/networkd/daemon.h | 4 ++++ + src/networkd/zone-bus.c | 34 +++++++++++++++++++++++++++++++++- + 5 files changed, 67 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 26876fa..cab2ae6 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -162,6 +162,7 @@ int nw_bus_register_implementation(sd_bus* bus, + DEBUG("Registering bus object implementation for path=%s iface=%s\n", + impl->path, impl->interface); + ++ // Register vtables + for (const sd_bus_vtable** vtable = impl->vtables; vtable && *vtable; vtable++) { + r = sd_bus_add_object_vtable(bus, NULL, impl->path, impl->interface, *vtable, data); + if (r < 0) { +@@ -171,6 +172,17 @@ int nw_bus_register_implementation(sd_bus* bus, + } + } + ++ // Register fallback vtables ++ for (const struct nw_bus_vtable_pair* p = impl->fallback_vtables; p && p->vtable; p++) { ++ r = sd_bus_add_fallback_vtable(bus, NULL, impl->path, impl->interface, ++ p->vtable, p->object_find, data); ++ if (r < 0) { ++ ERROR("Could not register bus path %s with interface %s: %m\n", ++ impl->path, impl->interface); ++ return 1; ++ } ++ } ++ + // Register the node enumerator + if (impl->node_enumerator) { + r = sd_bus_add_node_enumerator(bus, NULL, impl->path, impl->node_enumerator, data); +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 6232ebb..42ab2d3 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -32,15 +32,21 @@ + + int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon); + ++struct nw_bus_vtable_pair { ++ const sd_bus_vtable* vtable; ++ sd_bus_object_find_t object_find; ++}; ++ + struct nw_bus_implementation { + const char* path; + const char* interface; +- + const sd_bus_vtable** vtables; ++ const struct nw_bus_vtable_pair* fallback_vtables; + sd_bus_node_enumerator_t node_enumerator; + const struct nw_bus_implementation** children; + }; + ++#define BUS_FALLBACK_VTABLES(...) ((const struct nw_bus_vtable_pair[]) { __VA_ARGS__, {} }) + #define BUS_IMPLEMENTATIONS(...) ((const struct nw_bus_implementation* []) { __VA_ARGS__, NULL }) + #define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL }) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 588aa4e..5b5cbb4 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -236,6 +236,17 @@ int nw_daemon_reload(struct nw_daemon* daemon) { + return 0; + } + ++/* ++ Zones ++*/ ++ + struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon) { + return nw_zones_ref(daemon->zones); + } ++ ++struct nw_zone* nw_daemon_get_zone_by_name(struct nw_daemon* daemon, const char* name) { ++ if (!daemon->zones) ++ return NULL; ++ ++ return nw_zones_get_by_name(daemon->zones, name); ++} +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index bc69795..891c297 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -34,6 +34,10 @@ int nw_daemon_run(struct nw_daemon* daemon); + + int nw_daemon_reload(struct nw_daemon* daemon); + ++/* ++ Zones ++*/ + struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon); ++struct nw_zone* nw_daemon_get_zone_by_name(struct nw_daemon* daemon, const char* name); + + #endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c +index ebd8789..aafbfaf 100644 +--- a/src/networkd/zone-bus.c ++++ b/src/networkd/zone-bus.c +@@ -48,9 +48,41 @@ ERROR: + return r; + } + ++static int nw_zone_object_find(sd_bus* bus, const char* path, const char* interface, ++ void* data, void** found, sd_bus_error* error) { ++ char* name = NULL; ++ int r; ++ ++ // Fetch a reference to the daemon ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Decode the path of the requested object ++ r = sd_bus_path_decode(path, "/org/ipfire/network1/zone", &name); ++ if (r <= 0) ++ return 0; ++ ++ // Find the zone ++ struct nw_zone* zone = nw_daemon_get_zone_by_name(daemon, name); ++ if (!zone) ++ return 0; ++ ++ // Match! ++ *found = zone; ++ ++ nw_zone_unref(zone); ++ ++ return 1; ++} ++ ++static const sd_bus_vtable zone_vtable[] = { ++ SD_BUS_VTABLE_START(0), ++ ++ SD_BUS_VTABLE_END ++}; ++ + const struct nw_bus_implementation zone_bus_impl = { + "/org/ipfire/network1/zone", + "org.ipfire.network1.Zone", +- //.fallback_vtables = BUS_FALLBACK_VTABLES({zone_bus_vtable, nw_zone_object_find}), ++ .fallback_vtables = BUS_FALLBACK_VTABLES({zone_vtable, nw_zone_object_find}), + .node_enumerator = nw_zone_node_enumerator, + }; +-- +2.39.2 + diff --git a/network/patches/0177-networkd-Split-daemon-bus-implementation-into-a-sepa.patch b/network/patches/0177-networkd-Split-daemon-bus-implementation-into-a-sepa.patch new file mode 100644 index 000000000..d1219c248 --- /dev/null +++ b/network/patches/0177-networkd-Split-daemon-bus-implementation-into-a-sepa.patch @@ -0,0 +1,175 @@ +From d6edaf630588fbc6b54a315f49f252e226c15342 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 2 Feb 2023 01:23:31 +0000 +Subject: [PATCH 177/304] networkd: Split daemon bus implementation into a + separate file + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/bus.c | 29 ++--------------------- + src/networkd/daemon-bus.c | 49 +++++++++++++++++++++++++++++++++++++++ + src/networkd/daemon-bus.h | 28 ++++++++++++++++++++++ + 4 files changed, 81 insertions(+), 27 deletions(-) + create mode 100644 src/networkd/daemon-bus.c + create mode 100644 src/networkd/daemon-bus.h + +diff --git a/Makefile.am b/Makefile.am +index ae4cb85..3972d8d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -314,6 +314,8 @@ dist_networkd_SOURCES = \ + src/networkd/config.h \ + src/networkd/daemon.c \ + src/networkd/daemon.h \ ++ src/networkd/daemon-bus.c \ ++ src/networkd/daemon-bus.h \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/string.h \ +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index cab2ae6..258aacd 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -19,39 +19,14 @@ + #############################################################################*/ + + #include +-#include + + #include + #include + + #include "bus.h" + #include "daemon.h" ++#include "daemon-bus.h" + #include "logging.h" +-#include "zone-bus.h" +- +-static int nw_bus_daemon_reload(sd_bus_message* m, void* data, sd_bus_error* error) { +- struct nw_daemon* daemon = (struct nw_daemon*)data; +- +- // Reload the daemon +- nw_daemon_reload(daemon); +- +- // Respond with an empty message +- return sd_bus_reply_method_return(m, NULL); +-} +- +-static const sd_bus_vtable daemon_vtable[] = { +- SD_BUS_VTABLE_START(0), +- SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, +- nw_bus_daemon_reload, SD_BUS_VTABLE_UNPRIVILEGED), +- SD_BUS_VTABLE_END, +-}; +- +-const struct nw_bus_implementation daemon_implementation = { +- .path = "/org/ipfire/network1", +- .interface = "org.ipfire.network1", +- .vtables = BUS_VTABLES(daemon_vtable), +- .children = BUS_IMPLEMENTATIONS(&zone_bus_impl), +-}; + + static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { + struct nw_daemon* daemon = (struct nw_daemon*)data; +@@ -126,7 +101,7 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon) { + } + + // Register the implementation +- r = nw_bus_register_implementation(bus, &daemon_implementation, daemon); ++ r = nw_bus_register_implementation(bus, &daemon_bus_impl, daemon); + if (r) + return r; + +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +new file mode 100644 +index 0000000..aac9775 +--- /dev/null ++++ b/src/networkd/daemon-bus.c +@@ -0,0 +1,49 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "bus.h" ++#include "daemon.h" ++#include "zone-bus.h" ++ ++static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* error) { ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Reload the daemon ++ nw_daemon_reload(daemon); ++ ++ // Respond with an empty message ++ return sd_bus_reply_method_return(m, NULL); ++} ++ ++static const sd_bus_vtable daemon_vtable[] = { ++ SD_BUS_VTABLE_START(0), ++ SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, ++ nw_daemon_bus_reload, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_VTABLE_END, ++}; ++ ++const struct nw_bus_implementation daemon_bus_impl = { ++ .path = "/org/ipfire/network1", ++ .interface = "org.ipfire.network1", ++ .vtables = BUS_VTABLES(daemon_vtable), ++ .children = BUS_IMPLEMENTATIONS(&zone_bus_impl), ++}; +diff --git a/src/networkd/daemon-bus.h b/src/networkd/daemon-bus.h +new file mode 100644 +index 0000000..787e92a +--- /dev/null ++++ b/src/networkd/daemon-bus.h +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_DAEMON_BUS_H ++#define NETWORKD_DAEMON_BUS_H ++ ++#include "bus.h" ++ ++extern const struct nw_bus_implementation daemon_bus_impl; ++ ++#endif /* NETWORKD_DAEMON_BUS_H */ +-- +2.39.2 + diff --git a/network/patches/0178-networkd-Add-a-test-bus-property-to-set-the-MTU.patch b/network/patches/0178-networkd-Add-a-test-bus-property-to-set-the-MTU.patch new file mode 100644 index 000000000..2e5452d76 --- /dev/null +++ b/network/patches/0178-networkd-Add-a-test-bus-property-to-set-the-MTU.patch @@ -0,0 +1,201 @@ +From 9368a163388c9f8665dbdedaccae70ee168df714 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 4 Feb 2023 22:10:56 +0000 +Subject: [PATCH 178/304] networkd: Add a test bus property to set the MTU + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 38 +++++++++++++++++++++++++------------- + src/networkd/config.h | 5 +++-- + src/networkd/zone-bus.c | 34 ++++++++++++++++++++++++++++++++++ + src/networkd/zone.c | 14 ++++++++++++++ + src/networkd/zone.h | 7 +++++++ + 5 files changed, 83 insertions(+), 15 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index e531ec6..788308f 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -273,6 +273,17 @@ int nw_config_del(struct nw_config* config, const char* key) { + return 0; + } + ++const char* nw_config_get(struct nw_config* config, const char* key) { ++ struct nw_config_entry* entry = nw_config_find(config, key); ++ ++ // Return the value if found and set ++ if (entry && *entry->value) ++ return entry->value; ++ ++ // Otherwise return NULL ++ return NULL; ++} ++ + int nw_config_set(struct nw_config* config, const char* key, const char* value) { + struct nw_config_entry* entry = NULL; + +@@ -294,23 +305,24 @@ int nw_config_set(struct nw_config* config, const char* key, const char* value) + return nw_string_set(entry->value, value); + } + +-const char* nw_config_get(struct nw_config* config, const char* key) { +- struct nw_config_entry* entry = nw_config_find(config, key); +- +- // Return the value if found and set +- if (entry && *entry->value) +- return entry->value; +- +- // Otherwise return NULL +- return NULL; +-} +- +-unsigned int nw_config_get_unsigned_int(struct nw_config* config, const char* key) { ++int nw_config_get_int(struct nw_config* config, const char* key, const int __default) { + const char* value = nw_config_get(config, key); + + // Return zero if not set + if (!value) +- return 0; ++ return __default; + + return strtoul(value, NULL, 10); + } ++ ++int nw_config_set_int(struct nw_config* config, const char* key, const int value) { ++ char __value[1024]; ++ int r; ++ ++ // Format the value as string ++ r = nw_string_format(__value, "%d\n", value); ++ if (r) ++ return r; ++ ++ return nw_config_set(config, key, __value); ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 5b9910b..b8d8555 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -42,9 +42,10 @@ int nw_config_write(struct nw_config* config); + + int nw_config_del(struct nw_config* config, const char* key); + ++const char* nw_config_get(struct nw_config* config, const char* key); + int nw_config_set(struct nw_config* config, const char* key, const char* value); + +-const char* nw_config_get(struct nw_config* config, const char* key); +-unsigned int nw_config_get_unsigned_int(struct nw_config* config, const char* key); ++int nw_config_get_int(struct nw_config* config, const char* key, const int __default); ++int nw_config_set_int(struct nw_config* config, const char* key, const int value); + + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c +index aafbfaf..e9c2ecc 100644 +--- a/src/networkd/zone-bus.c ++++ b/src/networkd/zone-bus.c +@@ -18,6 +18,8 @@ + # # + #############################################################################*/ + ++#include ++ + #include "bus.h" + #include "daemon.h" + #include "logging.h" +@@ -74,9 +76,41 @@ static int nw_zone_object_find(sd_bus* bus, const char* path, const char* interf + return 1; + } + ++/* ++ MTU ++*/ ++static int nw_zone_bus_get_mtu(sd_bus* bus, const char *path, const char *interface, ++ const char* property, sd_bus_message* reply, void* data, sd_bus_error *error) { ++ struct nw_zone* zone = (struct nw_zone*)data; ++ ++ return sd_bus_message_append(reply, "u", nw_zone_mtu(zone)); ++} ++ ++static int nw_zone_bus_set_mtu(sd_bus* bus, const char* path, const char* interface, ++ const char* property, sd_bus_message* value, void* data, sd_bus_error* error) { ++ unsigned int mtu = 0; ++ int r; ++ ++ struct nw_zone* zone = (struct nw_zone*)data; ++ ++ // Parse the value ++ r = sd_bus_message_read(value, "u", &mtu); ++ if (r < 0) ++ return r; ++ ++ if (!nw_zone_set_mtu(zone, mtu)) ++ return -errno; ++ ++ return 0; ++} ++ + static const sd_bus_vtable zone_vtable[] = { + SD_BUS_VTABLE_START(0), + ++ // MTU ++ SD_BUS_WRITABLE_PROPERTY("MTU", "u", nw_zone_bus_get_mtu, nw_zone_bus_set_mtu, ++ 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), ++ + SD_BUS_VTABLE_END + }; + +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index f78334e..c64706f 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -24,6 +24,7 @@ + #include + + #include "config.h" ++#include "logging.h" + #include "string.h" + #include "zone.h" + +@@ -144,3 +145,16 @@ char* nw_zone_bus_path(struct nw_zone* zone) { + + return p; + } ++ ++/* ++ MTU ++*/ ++unsigned int nw_zone_mtu(struct nw_zone* zone) { ++ return nw_config_get_int(zone->config, "MTU", NETWORK_ZONE_DEFAULT_MTU); ++} ++ ++int nw_zone_set_mtu(struct nw_zone* zone, unsigned int mtu) { ++ DEBUG("Change MTU of %s to %u\n", zone->name, mtu); ++ ++ return nw_config_set_int(zone->config, "MTU", mtu); ++} +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 081a720..4a00412 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -22,6 +22,7 @@ + #define NETWORKD_ZONE_H + + #define NETWORK_ZONE_NAME_MAX_LENGTH 16 ++#define NETWORK_ZONE_DEFAULT_MTU 1500 + + struct nw_zone; + +@@ -34,4 +35,10 @@ const char* nw_zone_name(struct nw_zone* zone); + + char* nw_zone_bus_path(struct nw_zone* zone); + ++/* ++ MTU ++*/ ++unsigned int nw_zone_mtu(struct nw_zone* zone); ++int nw_zone_set_mtu(struct nw_zone* zone, unsigned int mtu); ++ + #endif /* NETWORKD_ZONE_H */ +-- +2.39.2 + diff --git a/network/patches/0179-networkd-Connect-to-udev.patch b/network/patches/0179-networkd-Connect-to-udev.patch new file mode 100644 index 000000000..e5e06191b --- /dev/null +++ b/network/patches/0179-networkd-Connect-to-udev.patch @@ -0,0 +1,203 @@ +From b286cd831946a3134f5355fe45901a8a4057dce1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 5 Feb 2023 11:05:23 +0000 +Subject: [PATCH 179/304] networkd: Connect to udev + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/daemon.c | 64 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/devmon.c | 27 ++++++++++++++++++ + src/networkd/devmon.h | 28 +++++++++++++++++++ + 4 files changed, 121 insertions(+) + create mode 100644 src/networkd/devmon.c + create mode 100644 src/networkd/devmon.h + +diff --git a/Makefile.am b/Makefile.am +index 3972d8d..2ebe622 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -316,6 +316,8 @@ dist_networkd_SOURCES = \ + src/networkd/daemon.h \ + src/networkd/daemon-bus.c \ + src/networkd/daemon-bus.h \ ++ src/networkd/devmon.c \ ++ src/networkd/devmon.h \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/string.h \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 5b5cbb4..960fd96 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -23,15 +23,20 @@ + + #include + #include ++#include + #include + + #include "bus.h" + #include "config.h" + #include "daemon.h" ++#include "devmon.h" + #include "logging.h" + #include "zone.h" + #include "zones.h" + ++// Increase the receive buffer to 128 MiB ++#define RCVBUF_SIZE 128 * 1024 * 1024 ++ + struct nw_daemon { + int nrefs; + +@@ -43,6 +48,9 @@ struct nw_daemon { + // DBus Connection + sd_bus* bus; + ++ // udev Connection ++ sd_device_monitor* devmon; ++ + // Zones + struct nw_zones* zones; + }; +@@ -126,6 +134,57 @@ static int nw_daemon_load_config(struct nw_daemon* daemon) { + return r; + } + ++static int nw_start_device_monitor(struct nw_daemon* daemon) { ++ int r; ++ ++ const char* subsystems[] = { ++ "net", ++ "ieee80211", ++ "rfkill", ++ NULL, ++ }; ++ ++ // Create a new connection to monitor any devices ++ r = sd_device_monitor_new(&daemon->devmon); ++ if (r < 0) { ++ ERROR("Could not inititalize the device monitor: %m\n"); ++ return 1; ++ } ++ ++ // Increase the receive buffer ++ r = sd_device_monitor_set_receive_buffer_size(daemon->devmon, RCVBUF_SIZE); ++ if (r < 0) { ++ ERROR("Could not increase buffer size for the device monitor: %m\n"); ++ return 1; ++ } ++ ++ // Filter for events for all relevant subsystems ++ for (const char** subsystem = subsystems; *subsystem; subsystem++) { ++ r = sd_device_monitor_filter_add_match_subsystem_devtype( ++ daemon->devmon, *subsystem, NULL); ++ if (r < 1) { ++ ERROR("Could not add device monitor for the %s subsystem: %m\n", *subsystem); ++ return 1; ++ } ++ } ++ ++ // Attach the device monitor to the event loop ++ r = sd_device_monitor_attach_event(daemon->devmon, daemon->loop); ++ if (r < 0) { ++ ERROR("Could not attach the device monitor to the event loop: %m\n"); ++ return 1; ++ } ++ ++ // Start processing events... ++ r = sd_device_monitor_start(daemon->devmon, nw_devmon_handle_uevent, daemon); ++ if (r < 0) { ++ ERROR("Could not start the device monitor: %m\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + +@@ -144,6 +203,11 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Connect to udev ++ r = nw_start_device_monitor(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +diff --git a/src/networkd/devmon.c b/src/networkd/devmon.c +new file mode 100644 +index 0000000..0a8c26d +--- /dev/null ++++ b/src/networkd/devmon.c +@@ -0,0 +1,27 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "devmon.h" ++ ++int nw_devmon_handle_uevent(sd_device_monitor* monitor, sd_device* device, void* data) { ++ return 0; ++} +diff --git a/src/networkd/devmon.h b/src/networkd/devmon.h +new file mode 100644 +index 0000000..0d8970a +--- /dev/null ++++ b/src/networkd/devmon.h +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_DEVMON_H ++#define NETWORKD_DEVMON_H ++ ++#include ++ ++int nw_devmon_handle_uevent(sd_device_monitor* monitor, sd_device* device, void* data); ++ ++#endif /* NETWORKD_DEVMON_H */ +-- +2.39.2 + diff --git a/network/patches/0180-networkd-Change-to-a-non-privileged-user-right-away.patch b/network/patches/0180-networkd-Change-to-a-non-privileged-user-right-away.patch new file mode 100644 index 000000000..71fb343c5 --- /dev/null +++ b/network/patches/0180-networkd-Change-to-a-non-privileged-user-right-away.patch @@ -0,0 +1,105 @@ +From eb3f6449e9319715fbb6135b1a47d18eaac2169e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 5 Feb 2023 12:06:19 +0000 +Subject: [PATCH 180/304] networkd: Change to a non-privileged user right away + +Signed-off-by: Michael Tremer +--- + src/networkd/main.c | 73 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 72 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 51a9bba..fbd6c3b 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -18,15 +18,86 @@ + # # + #############################################################################*/ + ++#include ++#include + #include ++#include ++#include ++#include + + #include "daemon.h" ++#include "logging.h" ++ ++static int drop_privileges(const char* user) { ++ struct passwd* passwd = NULL; ++ int r; ++ ++ // Fetch the current user ++ uid_t current_uid = getuid(); ++ ++ // If we have not been launched by root, we will assume that we have already ++ // been launched with a minimal set of privileges. ++ if (current_uid > 0) ++ return 0; ++ ++ DEBUG("Dropping privileges...\n"); ++ ++ // Fetch information about the desired user ++ passwd = getpwnam(user); ++ if (!passwd) { ++ ERROR("Could not find user %s: %m\n", user); ++ return 1; ++ } ++ ++ uid_t uid = passwd->pw_uid; ++ gid_t gid = passwd->pw_gid; ++ ++ // Change group ++ r = setresgid(gid, gid, gid); ++ if (r) { ++ ERROR("Could not change group to %d: %m\n", gid); ++ return 1; ++ } ++ ++ // Set any supplementary groups ++ r = setgroups(0, NULL); ++ if (r) { ++ ERROR("Could not set supplementary groups: %m\n"); ++ return 1; ++ } ++ ++ // Do not drop any capabilities when we change to the new user ++ r = prctl(PR_SET_KEEPCAPS, 1); ++ if (r) { ++ ERROR("Could not set PR_SET_KEEPCAPS: %m\n"); ++ return 1; ++ } ++ ++ // Change to the new user ++ r = setresuid(uid, uid, uid); ++ if (r) { ++ ERROR("Could not change user to %d: %m\n", uid); ++ return 1; ++ } ++ ++ // Reset PR_SET_KEEPCAPS ++ r = prctl(PR_SET_KEEPCAPS, 0); ++ if (r) { ++ ERROR("Could not set PR_SET_KEEPCAPS: %m\n"); ++ return 1; ++ } ++ ++ return 0; ++} + + int main(int argc, char** argv) { + struct nw_daemon* daemon = NULL; + int r; + +- // XXX Drop privileges ++ // Drop privileges ++ r = drop_privileges("network"); ++ if (r) ++ return r; + + // Create the daemon + r = nw_daemon_create(&daemon); +-- +2.39.2 + diff --git a/network/patches/0181-networkd-Drop-all-capabilities-except-a-few-we-would.patch b/network/patches/0181-networkd-Drop-all-capabilities-except-a-few-we-would.patch new file mode 100644 index 000000000..50d627fdc --- /dev/null +++ b/network/patches/0181-networkd-Drop-all-capabilities-except-a-few-we-would.patch @@ -0,0 +1,195 @@ +From dabf344de60d568e304a7f4d10548813ee4ce588 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 5 Feb 2023 13:17:21 +0000 +Subject: [PATCH 181/304] networkd: Drop all capabilities except a few we would + like to keep + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + configure.ac | 1 + + src/networkd/main.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 124 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 2ebe622..df61552 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -334,12 +334,14 @@ networkd_CPPFLAGS = \ + + networkd_CFLAGS = \ + $(AM_CFLAGS) \ ++ $(CAP_CFLAGS) \ + $(SYSTEMD_CFLAGS) + + networkd_LDFLAGS = \ + $(AM_LDFLAGS) + + networkd_LDADD = \ ++ $(CAP_LIBS) \ + $(SYSTEMD_LIBS) + + dist_dbuspolicy_DATA += \ +diff --git a/configure.ac b/configure.ac +index 16f0724..e1baa64 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -172,6 +172,7 @@ AM_CONDITIONAL(HAVE_UDEV, [test -n "$with_udevdir"]) + + # ------------------------------------------------------------------------------ + ++PKG_CHECK_MODULES([CAP], [libcap]) + PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) + PKG_CHECK_MODULES([SYSTEMD], [libsystemd]) + +diff --git a/src/networkd/main.c b/src/networkd/main.c +index fbd6c3b..9a0fd74 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -19,8 +19,10 @@ + #############################################################################*/ + + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -28,6 +30,120 @@ + #include "daemon.h" + #include "logging.h" + ++static int cap_acquire_setpcap(void) { ++ cap_flag_value_t value; ++ int r; ++ ++ // Fetch current capabilities ++ cap_t caps = cap_get_proc(); ++ ++ // Check if CAP_SETPCAP is already enabled ++ r = cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &value); ++ if (r) { ++ ERROR("The kernel does not seem to know CAP_SETPCAP: %m\n"); ++ goto ERROR; ++ } ++ ++ // It CAP_SETPCAP isn't set, we will try to set it ++ if (value != CAP_SET) { ++ const cap_value_t cap = CAP_SETPCAP; ++ ++ r = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, CAP_SET); ++ if (r) { ++ ERROR("Could not set CAP_SETPCAP: %m\n"); ++ goto ERROR; ++ } ++ ++ // Store capabilities ++ r = cap_set_proc(caps); ++ if (r) { ++ ERROR("Could not acquire effective CAP_SETPCAP capability: %m\n"); ++ goto ERROR; ++ } ++ } ++ ++ERROR: ++ if (caps) ++ cap_free(caps); ++ ++ return r; ++} ++ ++static cap_flag_value_t keep_cap(const cap_value_t cap, const cap_value_t* keep_caps) { ++ for (const cap_value_t* c = keep_caps; *c; c++) { ++ if (cap == *c) ++ return CAP_SET; ++ } ++ ++ return CAP_CLEAR; ++} ++ ++static int drop_capabilities(void) { ++ int r; ++ ++ const cap_value_t keep_caps[] = { ++ CAP_NET_ADMIN, ++ CAP_NET_BIND_SERVICE, ++ CAP_NET_BROADCAST, ++ CAP_NET_RAW, ++ 0, ++ }; ++ ++ // Acquire CAP_SETPCAP ++ r = cap_acquire_setpcap(); ++ if (r) ++ return r; ++ ++ // Fetch the current set of capabilities ++ cap_t caps = cap_get_proc(); ++ ++ // Drop all capabilities that we do not need ++ for (cap_value_t cap = 1; cap <= CAP_LAST_CAP; cap++) { ++ // Skip any capabilities we would like to skip ++ cap_flag_value_t flag = keep_cap(cap, keep_caps); ++ ++ // Drop the capability from the bounding set ++ if (flag == CAP_CLEAR) { ++ r = prctl(PR_CAPBSET_DROP, cap); ++ if (r) { ++ ERROR("Could not drop capability from the bounding set: %m\n"); ++ goto ERROR; ++ } ++ } ++ ++ r = cap_set_flag(caps, CAP_INHERITABLE, 1, &cap, CAP_CLEAR); ++ if (r) { ++ ERROR("Could not set capability %d: %m\n", (int)cap); ++ goto ERROR; ++ } ++ ++ r = cap_set_flag(caps, CAP_PERMITTED, 1, &cap, flag); ++ if (r) { ++ ERROR("Could not set capability %d: %m\n", (int)cap); ++ goto ERROR; ++ } ++ ++ r = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag); ++ if (r) { ++ ERROR("Could not set capability %d: %m\n", (int)cap); ++ goto ERROR; ++ } ++ } ++ ++ // Restore capabilities ++ r = cap_set_proc(caps); ++ if (r) { ++ ERROR("Could not restore capabilities: %m\n"); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (caps) ++ cap_free(caps); ++ ++ return r; ++} ++ + static int drop_privileges(const char* user) { + struct passwd* passwd = NULL; + int r; +@@ -87,6 +203,11 @@ static int drop_privileges(const char* user) { + return 1; + } + ++ // Drop capabilities ++ r = drop_capabilities(); ++ if (r) ++ return r; ++ + return 0; + } + +-- +2.39.2 + diff --git a/network/patches/0182-networkd-Connect-to-the-kernel-s-netlink-interface.patch b/network/patches/0182-networkd-Connect-to-the-kernel-s-netlink-interface.patch new file mode 100644 index 000000000..ccee33026 --- /dev/null +++ b/network/patches/0182-networkd-Connect-to-the-kernel-s-netlink-interface.patch @@ -0,0 +1,95 @@ +From e62b300ef78484b882d2da8683ebe79896523a13 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 19:46:25 +0000 +Subject: [PATCH 182/304] networkd: Connect to the kernel's netlink interface + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 50 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 960fd96..13e1257 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "bus.h" + #include "config.h" +@@ -45,6 +46,9 @@ struct nw_daemon { + // Event Loop + sd_event* loop; + ++ // Netlink Connection ++ sd_netlink* rtnl; ++ + // DBus Connection + sd_bus* bus; + +@@ -185,6 +189,47 @@ static int nw_start_device_monitor(struct nw_daemon* daemon) { + return 0; + } + ++static int _rtnl_dummy(sd_netlink* rtnl, sd_netlink_message* message, void* data) { ++ DEBUG("_rtnl_dummy called\n"); ++ ++ return 0; ++} ++ ++static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { ++ int r; ++ ++ // Connect to Netlink ++ r = sd_netlink_open(&daemon->rtnl); ++ if (r < 0) { ++ ERROR("Could not connect to the kernel's netlink interface: %m\n"); ++ return 1; ++ } ++ ++ // Increase the receive buffer ++ r = sd_netlink_increase_rxbuf(daemon->rtnl, RCVBUF_SIZE); ++ if (r < 0) { ++ ERROR("Could not increase receive buffer for the netlink socket: %m\n"); ++ return 1; ++ } ++ ++ // Connect it to the event loop ++ r = sd_netlink_attach_event(daemon->rtnl, daemon->loop, 0); ++ if (r < 0) { ++ ERROR("Could not connect the netlink socket to the event loop: %m\n"); ++ return 1; ++ } ++ ++ // Register callback for new interfaces ++ r = sd_netlink_add_match(daemon->rtnl, NULL, RTM_NEWLINK, _rtnl_dummy, NULL, ++ daemon, "networkd-RTM_NEWLINK"); ++ if (r < 0) { ++ ERROR("Could not register RTM_NEWLINK: %m\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + +@@ -198,6 +243,11 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Connect to the kernel's netlink interface ++ r = nw_daemon_connect_rtnl(daemon, 0); ++ if (r) ++ return r; ++ + // Connect to the system bus + r = nw_bus_connect(daemon->bus, daemon->loop, daemon); + if (r) +-- +2.39.2 + diff --git a/network/patches/0183-networkd-Link-against-libnetwork.patch b/network/patches/0183-networkd-Link-against-libnetwork.patch new file mode 100644 index 000000000..73a400d3c --- /dev/null +++ b/network/patches/0183-networkd-Link-against-libnetwork.patch @@ -0,0 +1,25 @@ +From b53b186e84560a3376da5e858e41c23bb4526847 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 19:50:47 +0000 +Subject: [PATCH 183/304] networkd: Link against libnetwork + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile.am b/Makefile.am +index df61552..80218d9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -341,6 +341,7 @@ networkd_LDFLAGS = \ + $(AM_LDFLAGS) + + networkd_LDADD = \ ++ src/libnetwork.la \ + $(CAP_LIBS) \ + $(SYSTEMD_LIBS) + +-- +2.39.2 + diff --git a/network/patches/0184-networkd-Add-a-link-object.patch b/network/patches/0184-networkd-Add-a-link-object.patch new file mode 100644 index 000000000..33272bae2 --- /dev/null +++ b/network/patches/0184-networkd-Add-a-link-object.patch @@ -0,0 +1,145 @@ +From 87a1e1e0b052f814aac355b60aedf736eef0bead Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 20:05:00 +0000 +Subject: [PATCH 184/304] networkd: Add a link object + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/link.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ + src/networkd/link.h | 31 +++++++++++++++++++ + 3 files changed, 105 insertions(+) + create mode 100644 src/networkd/link.c + create mode 100644 src/networkd/link.h + +diff --git a/Makefile.am b/Makefile.am +index 80218d9..e8946b7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -318,6 +318,8 @@ dist_networkd_SOURCES = \ + src/networkd/daemon-bus.h \ + src/networkd/devmon.c \ + src/networkd/devmon.h \ ++ src/networkd/link.c \ ++ src/networkd/link.h \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/string.h \ +diff --git a/src/networkd/link.c b/src/networkd/link.c +new file mode 100644 +index 0000000..06e3101 +--- /dev/null ++++ b/src/networkd/link.c +@@ -0,0 +1,72 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++ ++#include "daemon.h" ++#include "link.h" ++ ++struct nw_link { ++ struct nw_daemon* daemon; ++ int nrefs; ++ ++ // Interface Index ++ int ifindex; ++}; ++ ++int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) { ++ // Allocate a new object ++ struct nw_link* l = calloc(1, sizeof(*l)); ++ if (!l) ++ return 1; ++ ++ // Store a reference to the daemon ++ l->daemon = nw_daemon_ref(daemon); ++ ++ // Initialize the reference counter ++ l->nrefs = 1; ++ ++ // Store the ifindex ++ l->ifindex = ifindex; ++ ++ *link = l; ++ ++ return 0; ++} ++ ++static void nw_link_free(struct nw_link* link) { ++ if (link->daemon) ++ nw_daemon_unref(link->daemon); ++} ++ ++struct nw_link* nw_link_ref(struct nw_link* link) { ++ link->nrefs++; ++ ++ return link; ++} ++ ++struct nw_link* nw_link_unref(struct nw_link* link) { ++ if (--link->nrefs > 0) ++ return link; ++ ++ nw_link_free(link); ++ return NULL; ++} +diff --git a/src/networkd/link.h b/src/networkd/link.h +new file mode 100644 +index 0000000..cd79fde +--- /dev/null ++++ b/src/networkd/link.h +@@ -0,0 +1,31 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_LINK_H ++#define NETWORKD_LINK_H ++ ++struct nw_link; ++ ++int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex); ++ ++struct nw_link* nw_link_ref(struct nw_link* link); ++struct nw_link* nw_link_unref(struct nw_link* link); ++ ++#endif /* NETWORKD_LINK_H */ +-- +2.39.2 + diff --git a/network/patches/0185-networkd-Add-a-container-for-links.patch b/network/patches/0185-networkd-Add-a-container-for-links.patch new file mode 100644 index 000000000..327ce5c39 --- /dev/null +++ b/network/patches/0185-networkd-Add-a-container-for-links.patch @@ -0,0 +1,303 @@ +From 18b8c8415c595442f796638f85a244915339c974 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 20:25:29 +0000 +Subject: [PATCH 185/304] networkd: Add a container for links + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/daemon.c | 48 ++++++++++++++++++- + src/networkd/link.h | 2 + + src/networkd/links.c | 105 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/links.h | 35 ++++++++++++++ + 5 files changed, 190 insertions(+), 2 deletions(-) + create mode 100644 src/networkd/links.c + create mode 100644 src/networkd/links.h + +diff --git a/Makefile.am b/Makefile.am +index e8946b7..024bf45 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -320,6 +320,8 @@ dist_networkd_SOURCES = \ + src/networkd/devmon.h \ + src/networkd/link.c \ + src/networkd/link.h \ ++ src/networkd/links.c \ ++ src/networkd/links.h \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/string.h \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 13e1257..27b118e 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -31,6 +31,7 @@ + #include "config.h" + #include "daemon.h" + #include "devmon.h" ++#include "links.h" + #include "logging.h" + #include "zone.h" + #include "zones.h" +@@ -55,6 +56,9 @@ struct nw_daemon { + // udev Connection + sd_device_monitor* devmon; + ++ // Links ++ struct nw_links* links; ++ + // Zones + struct nw_zones* zones; + }; +@@ -230,6 +234,28 @@ static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { + return 0; + } + ++static int nw_daemon_enumerate_links(struct nw_daemon* daemon) { ++ int r; ++ ++ // Create a new links container ++ r = nw_links_create(&daemon->links, daemon); ++ if (r) ++ return r; ++ ++ return nw_links_enumerate(daemon->links); ++} ++ ++static int nw_daemon_enumerate(struct nw_daemon* daemon) { ++ int r; ++ ++ // Links ++ r = nw_daemon_enumerate_links(daemon); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + static int nw_daemon_setup(struct nw_daemon* daemon) { + int r; + +@@ -258,6 +284,11 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Enumerate everything we need to know ++ r = nw_daemon_enumerate(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +@@ -287,11 +318,19 @@ ERROR: + return r; + } + +-static void nw_daemon_free(struct nw_daemon* daemon) { ++static void nw_daemon_cleanup(struct nw_daemon* daemon) { + if (daemon->zones) + nw_zones_unref(daemon->zones); ++ if (daemon->links) ++ nw_links_unref(daemon->links); + if (daemon->config) + nw_config_unref(daemon->config); ++} ++ ++static void nw_daemon_free(struct nw_daemon* daemon) { ++ // Cleanup common objects ++ nw_daemon_cleanup(daemon); ++ + if (daemon->bus) + sd_bus_unref(daemon->bus); + if (daemon->loop) +@@ -330,15 +369,20 @@ int nw_daemon_run(struct nw_daemon* daemon) { + goto ERROR; + } + +- + // Let systemd know that we are shutting down + sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); + ++ // Cleanup everything ++ nw_daemon_cleanup(daemon); ++ + return 0; + + ERROR: + sd_notifyf(0, "ERRNO=%i", -r); + ++ // Cleanup everything ++ nw_daemon_cleanup(daemon); ++ + return 1; + } + +diff --git a/src/networkd/link.h b/src/networkd/link.h +index cd79fde..6ffe843 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_LINK_H + #define NETWORKD_LINK_H + ++#include "daemon.h" ++ + struct nw_link; + + int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex); +diff --git a/src/networkd/links.c b/src/networkd/links.c +new file mode 100644 +index 0000000..b81d6a5 +--- /dev/null ++++ b/src/networkd/links.c +@@ -0,0 +1,105 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++ ++#include "daemon.h" ++#include "link.h" ++#include "links.h" ++ ++struct nw_links_entry { ++ struct nw_link* link; ++ ++ // Link to the other entries ++ STAILQ_ENTRY(nw_links_entry) nodes; ++}; ++ ++struct nw_links { ++ struct nw_daemon* daemon; ++ int nrefs; ++ ++ // Link Entries ++ STAILQ_HEAD(entries, nw_links_entry) entries; ++ ++ // A counter of the link entries ++ unsigned int num; ++}; ++ ++int nw_links_create(struct nw_links** links, struct nw_daemon* daemon) { ++ struct nw_links* l = calloc(1, sizeof(*l)); ++ if (!l) ++ return 1; ++ ++ // Store a reference to the daemon ++ l->daemon = nw_daemon_ref(daemon); ++ ++ // Initialize the reference counter ++ l->nrefs = 1; ++ ++ // Initialize entries ++ STAILQ_INIT(&l->entries); ++ ++ // Reference the pointer ++ *links = l; ++ ++ return 0; ++} ++ ++static void nw_links_free(struct nw_links* links) { ++ struct nw_links_entry* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&links->entries)) { ++ entry = STAILQ_FIRST(&links->entries); ++ ++ // Dereference the zone ++ nw_link_unref(entry->link); ++ ++ // Remove the entry from the list ++ STAILQ_REMOVE_HEAD(&links->entries, nodes); ++ ++ // Free the entry ++ free(entry); ++ } ++ ++ if (links->daemon) ++ nw_daemon_unref(links->daemon); ++} ++ ++struct nw_links* nw_links_ref(struct nw_links* links) { ++ links->nrefs++; ++ ++ return links; ++} ++ ++struct nw_links* nw_links_unref(struct nw_links* links) { ++ if (--links->nrefs > 0) ++ return links; ++ ++ nw_links_free(links); ++ return NULL; ++} ++ ++int nw_links_enumerate(struct nw_links* links) { ++ // TODO ++ ++ return 0; ++} +diff --git a/src/networkd/links.h b/src/networkd/links.h +new file mode 100644 +index 0000000..b2976e4 +--- /dev/null ++++ b/src/networkd/links.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_LINKS_H ++#define NETWORKD_LINKS_H ++ ++#include "daemon.h" ++ ++struct nw_links; ++ ++int nw_links_create(struct nw_links** links, struct nw_daemon* daemon); ++ ++struct nw_links* nw_links_ref(struct nw_links* links); ++struct nw_links* nw_links_unref(struct nw_links* links); ++ ++int nw_links_enumerate(struct nw_links* links); ++ ++#endif /* NETWORKD_LINKS_H */ +-- +2.39.2 + diff --git a/network/patches/0186-networkd-Enumerate-all-links-on-startup.patch b/network/patches/0186-networkd-Enumerate-all-links-on-startup.patch new file mode 100644 index 000000000..b547f60f4 --- /dev/null +++ b/network/patches/0186-networkd-Enumerate-all-links-on-startup.patch @@ -0,0 +1,172 @@ +From eaf649ee9bdfa7e20ba381a505e2c5b48501c242 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 20:41:02 +0000 +Subject: [PATCH 186/304] networkd: Enumerate all links on startup + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 16 +++++++++------- + src/networkd/daemon.h | 7 +++++++ + src/networkd/link.c | 7 +++++++ + src/networkd/link.h | 2 ++ + src/networkd/links.c | 39 +++++++++++++++++++++++++++++++++++++-- + 5 files changed, 62 insertions(+), 9 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 27b118e..88ce8e7 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -31,6 +31,7 @@ + #include "config.h" + #include "daemon.h" + #include "devmon.h" ++#include "link.h" + #include "links.h" + #include "logging.h" + #include "zone.h" +@@ -193,12 +194,6 @@ static int nw_start_device_monitor(struct nw_daemon* daemon) { + return 0; + } + +-static int _rtnl_dummy(sd_netlink* rtnl, sd_netlink_message* message, void* data) { +- DEBUG("_rtnl_dummy called\n"); +- +- return 0; +-} +- + static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { + int r; + +@@ -224,7 +219,7 @@ static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { + } + + // Register callback for new interfaces +- r = sd_netlink_add_match(daemon->rtnl, NULL, RTM_NEWLINK, _rtnl_dummy, NULL, ++ r = sd_netlink_add_match(daemon->rtnl, NULL, RTM_NEWLINK, nw_link_process, NULL, + daemon, "networkd-RTM_NEWLINK"); + if (r < 0) { + ERROR("Could not register RTM_NEWLINK: %m\n"); +@@ -394,6 +389,13 @@ int nw_daemon_reload(struct nw_daemon* daemon) { + return 0; + } + ++/* ++ Netlink ++*/ ++sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon) { ++ return daemon->rtnl; ++} ++ + /* + Zones + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 891c297..543685f 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_DAEMON_H + #define NETWORKD_DAEMON_H + ++#include ++ + #include "zone.h" + + struct nw_daemon; +@@ -34,6 +36,11 @@ int nw_daemon_run(struct nw_daemon* daemon); + + int nw_daemon_reload(struct nw_daemon* daemon); + ++/* ++ Netlink ++*/ ++sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon); ++ + /* + Zones + */ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 06e3101..ec0593b 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -23,6 +23,7 @@ + + #include "daemon.h" + #include "link.h" ++#include "logging.h" + + struct nw_link { + struct nw_daemon* daemon; +@@ -70,3 +71,9 @@ struct nw_link* nw_link_unref(struct nw_link* link) { + nw_link_free(link); + return NULL; + } ++ ++int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { ++ DEBUG("nw_link_process called\n"); ++ ++ return 0; ++} +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 6ffe843..6003133 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -30,4 +30,6 @@ int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) + struct nw_link* nw_link_ref(struct nw_link* link); + struct nw_link* nw_link_unref(struct nw_link* link); + ++int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); ++ + #endif /* NETWORKD_LINK_H */ +diff --git a/src/networkd/links.c b/src/networkd/links.c +index b81d6a5..22584f2 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -99,7 +99,42 @@ struct nw_links* nw_links_unref(struct nw_links* links) { + } + + int nw_links_enumerate(struct nw_links* links) { +- // TODO ++ sd_netlink_message* req = NULL; ++ sd_netlink_message* res = NULL; ++ int r; + +- return 0; ++ sd_netlink* rtnl = nw_daemon_get_rtnl(links->daemon); ++ if (!rtnl) ++ return 1; ++ ++ r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0); ++ if (r < 0) ++ return 1; ++ ++ r = sd_netlink_message_set_request_dump(req, 1); ++ if (r < 0) ++ return 1; ++ ++ r = sd_netlink_call(rtnl, req, 0, &res); ++ if (r < 0) ++ return 1; ++ ++ sd_netlink_message* m = res; ++ ++ // Iterate through all replies ++ do { ++ r = nw_link_process(rtnl, m, links->daemon); ++ if (r) ++ goto ERROR; ++ } while ((m = sd_netlink_message_next(m))); ++ ++ERROR: ++ if (m) ++ sd_netlink_message_unref(m); ++ if (req) ++ sd_netlink_message_unref(req); ++ if (res) ++ sd_netlink_message_unref(res); ++ ++ return r; + } +-- +2.39.2 + diff --git a/network/patches/0187-networkd-Create-a-link-object-for-each-interface.patch b/network/patches/0187-networkd-Create-a-link-object-for-each-interface.patch new file mode 100644 index 000000000..cfa266627 --- /dev/null +++ b/network/patches/0187-networkd-Create-a-link-object-for-each-interface.patch @@ -0,0 +1,362 @@ +From 766f08ca103698e6578228e11f81c1d73d687d65 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 9 Feb 2023 21:38:09 +0000 +Subject: [PATCH 187/304] networkd: Create a link object for each interface + +We are also listening for netlink events that add and delete any +interfaces. + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 29 +++++++++++ + src/networkd/daemon.h | 12 ++++- + src/networkd/link.c | 117 ++++++++++++++++++++++++++++++++++++++++-- + src/networkd/link.h | 2 + + src/networkd/links.c | 54 +++++++++++++++++++ + src/networkd/links.h | 6 +++ + 6 files changed, 215 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 88ce8e7..dc2aed6 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -226,6 +226,14 @@ static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { + return 1; + } + ++ // Register callback for deleted interfaces ++ r = sd_netlink_add_match(daemon->rtnl, NULL, RTM_DELLINK, nw_link_process, NULL, ++ daemon, "networkd-RTM_DELLINK"); ++ if (r < 0) { ++ ERROR("Could not register RTM_DELLINK: %m\n"); ++ return 1; ++ } ++ + return 0; + } + +@@ -396,6 +404,27 @@ sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon) { + return daemon->rtnl; + } + ++/* ++ Links ++*/ ++struct nw_links* nw_daemon_links(struct nw_daemon* daemon) { ++ return nw_links_ref(daemon->links); ++} ++ ++void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link) { ++ if (!daemon->links) ++ return; ++ ++ nw_links_drop_link(daemon->links, link); ++} ++ ++struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex) { ++ if (!daemon->links) ++ return NULL; ++ ++ return nw_links_get_by_ifindex(daemon->links, ifindex); ++} ++ + /* + Zones + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 543685f..8e534c5 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -23,10 +23,11 @@ + + #include + +-#include "zone.h" +- + struct nw_daemon; + ++#include "link.h" ++#include "zone.h" ++ + int nw_daemon_create(struct nw_daemon** daemon); + + struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon); +@@ -41,6 +42,13 @@ int nw_daemon_reload(struct nw_daemon* daemon); + */ + sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon); + ++/* ++ Links ++*/ ++struct nw_links* nw_daemon_links(struct nw_daemon* daemon); ++void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link); ++struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex); ++ + /* + Zones + */ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index ec0593b..b6ece82 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -21,8 +21,11 @@ + #include + #include + ++#include ++ + #include "daemon.h" + #include "link.h" ++#include "links.h" + #include "logging.h" + + struct nw_link { +@@ -48,12 +51,16 @@ int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) + // Store the ifindex + l->ifindex = ifindex; + ++ DEBUG("New link allocated (ifindex = %d)\n", l->ifindex); ++ + *link = l; + + return 0; + } + + static void nw_link_free(struct nw_link* link) { ++ DEBUG("Freeing link (ifindex = %d)\n", link->ifindex); ++ + if (link->daemon) + nw_daemon_unref(link->daemon); + } +@@ -72,8 +79,112 @@ struct nw_link* nw_link_unref(struct nw_link* link) { + return NULL; + } + +-int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { +- DEBUG("nw_link_process called\n"); ++int nw_link_ifindex(struct nw_link* link) { ++ return link->ifindex; ++} + +- return 0; ++int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { ++ struct nw_links* links = NULL; ++ struct nw_link* link = NULL; ++ const char* ifname = NULL; ++ int ifindex; ++ uint16_t type; ++ int r; ++ ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Fetch links ++ links = nw_daemon_links(daemon); ++ if (!links) { ++ r = 1; ++ goto ERROR; ++ } ++ ++ // Check if this message could be received ++ if (sd_netlink_message_is_error(message)) { ++ r = sd_netlink_message_get_errno(message); ++ if (r < 0) ++ ERROR("Could not receive link message: %m\n"); ++ ++ goto IGNORE; ++ } ++ ++ // Fetch the message type ++ r = sd_netlink_message_get_type(message, &type); ++ if (r < 0) { ++ ERROR("Could not fetch message type: %m\n"); ++ goto IGNORE; ++ } ++ ++ // Check type ++ switch (type) { ++ case RTM_NEWLINK: ++ case RTM_DELLINK: ++ break; ++ ++ default: ++ ERROR("Received an unexpected message (type %u)\n", type); ++ goto IGNORE; ++ } ++ ++ // Fetch the interface index ++ r = sd_rtnl_message_link_get_ifindex(message, &ifindex); ++ if (r < 0) { ++ ERROR("Could not fetch ifindex: %m\n"); ++ goto IGNORE; ++ } ++ ++ // Check interface index ++ if (ifindex <= 0) { ++ ERROR("Received an invalid ifindex\n"); ++ goto IGNORE; ++ } ++ ++ // Fetch the interface name ++ r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname); ++ if (r < 0) { ++ ERROR("Received a netlink message without interface name: %m\n"); ++ goto IGNORE; ++ } ++ ++ // Try finding an existing link ++ link = nw_daemon_get_link_by_ifindex(daemon, ifindex); ++ ++ switch (type) { ++ case RTM_NEWLINK: ++ // If the link doesn't exist, create it ++ if (!link) { ++ r = nw_link_create(&link, daemon, ifindex); ++ if (r) { ++ ERROR("Could not create link: %m\n"); ++ goto ERROR; ++ } ++ } ++ ++ // TODO Import any data from the netlink message ++ ++ // Add it to the list ++ r = nw_links_add_link(links, link); ++ if (r) ++ goto ERROR; ++ ++ break; ++ ++ case RTM_DELLINK: ++ if (link) ++ nw_links_drop_link(links, link); ++ ++ break; ++ } ++ ++IGNORE: ++ r = 0; ++ ++ERROR: ++ if (links) ++ nw_links_unref(links); ++ if (link) ++ nw_link_unref(link); ++ ++ return r; + } +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 6003133..e482d71 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -30,6 +30,8 @@ int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) + struct nw_link* nw_link_ref(struct nw_link* link); + struct nw_link* nw_link_unref(struct nw_link* link); + ++int nw_link_ifindex(struct nw_link* link); ++ + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + + #endif /* NETWORKD_LINK_H */ +diff --git a/src/networkd/links.c b/src/networkd/links.c +index 22584f2..044a27d 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -23,6 +23,7 @@ + #include + + #include "daemon.h" ++#include "logging.h" + #include "link.h" + #include "links.h" + +@@ -98,6 +99,49 @@ struct nw_links* nw_links_unref(struct nw_links* links) { + return NULL; + } + ++static struct nw_links_entry* nw_links_find_link(struct nw_links* links, const int ifindex) { ++ struct nw_links_entry* entry = NULL; ++ ++ STAILQ_FOREACH(entry, &links->entries, nodes) { ++ if (nw_link_ifindex(entry->link) == ifindex) ++ return entry; ++ } ++ ++ // No match found ++ return NULL; ++} ++ ++int nw_links_add_link(struct nw_links* links, struct nw_link* link) { ++ // Allocate a new entry ++ struct nw_links_entry* entry = calloc(1, sizeof(*entry)); ++ if (!entry) ++ return 1; ++ ++ // Reference the link ++ entry->link = nw_link_ref(link); ++ ++ // Add it to the list ++ STAILQ_INSERT_TAIL(&links->entries, entry, nodes); ++ ++ // Increment the counter ++ links->num++; ++ ++ return 0; ++} ++ ++void nw_links_drop_link(struct nw_links* links, struct nw_link* link) { ++ struct nw_links_entry* entry = NULL; ++ ++ entry = nw_links_find_link(links, nw_link_ifindex(link)); ++ if (!entry) ++ return; ++ ++ DEBUG("Dropping link %d\n", nw_link_ifindex(entry->link)); ++ ++ STAILQ_REMOVE(&links->entries, entry, nw_links_entry, nodes); ++ links->num--; ++} ++ + int nw_links_enumerate(struct nw_links* links) { + sd_netlink_message* req = NULL; + sd_netlink_message* res = NULL; +@@ -138,3 +182,13 @@ ERROR: + + return r; + } ++ ++struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex) { ++ struct nw_links_entry* entry = NULL; ++ ++ entry = nw_links_find_link(links, ifindex); ++ if (!entry) ++ return NULL; ++ ++ return nw_link_ref(entry->link); ++} +diff --git a/src/networkd/links.h b/src/networkd/links.h +index b2976e4..2f2bbea 100644 +--- a/src/networkd/links.h ++++ b/src/networkd/links.h +@@ -22,6 +22,7 @@ + #define NETWORKD_LINKS_H + + #include "daemon.h" ++#include "link.h" + + struct nw_links; + +@@ -30,6 +31,11 @@ int nw_links_create(struct nw_links** links, struct nw_daemon* daemon); + struct nw_links* nw_links_ref(struct nw_links* links); + struct nw_links* nw_links_unref(struct nw_links* links); + ++int nw_links_add_link(struct nw_links* links, struct nw_link* link); ++void nw_links_drop_link(struct nw_links* links, struct nw_link* link); ++ + int nw_links_enumerate(struct nw_links* links); + ++struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex); ++ + #endif /* NETWORKD_LINKS_H */ +-- +2.39.2 + diff --git a/network/patches/0188-networkd-Only-add-link-if-we-created-it.patch b/network/patches/0188-networkd-Only-add-link-if-we-created-it.patch new file mode 100644 index 000000000..844c432c0 --- /dev/null +++ b/network/patches/0188-networkd-Only-add-link-if-we-created-it.patch @@ -0,0 +1,38 @@ +From b8a1a68c48849accb658b926f3596857dba41654 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 09:53:47 +0000 +Subject: [PATCH 188/304] networkd: Only add link if we created it + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index b6ece82..32a66cd 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -159,15 +159,15 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { + ERROR("Could not create link: %m\n"); + goto ERROR; + } ++ ++ // Add it to the list ++ r = nw_links_add_link(links, link); ++ if (r) ++ goto ERROR; + } + + // TODO Import any data from the netlink message + +- // Add it to the list +- r = nw_links_add_link(links, link); +- if (r) +- goto ERROR; +- + break; + + case RTM_DELLINK: +-- +2.39.2 + diff --git a/network/patches/0189-networkd-Import-interface-name.patch b/network/patches/0189-networkd-Import-interface-name.patch new file mode 100644 index 000000000..00f801dd7 --- /dev/null +++ b/network/patches/0189-networkd-Import-interface-name.patch @@ -0,0 +1,106 @@ +From f650f6cd802686e545d41d00be4a0abd67765391 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 10:03:08 +0000 +Subject: [PATCH 189/304] networkd: Import interface name + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 52 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 51 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 32a66cd..40f809f 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -18,8 +18,10 @@ + # # + #############################################################################*/ + ++#include + #include + #include ++#include + + #include + +@@ -27,6 +29,7 @@ + #include "link.h" + #include "links.h" + #include "logging.h" ++#include "string.h" + + struct nw_link { + struct nw_daemon* daemon; +@@ -34,6 +37,9 @@ struct nw_link { + + // Interface Index + int ifindex; ++ ++ // Interface Name ++ char ifname[IF_NAMESIZE]; + }; + + int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) { +@@ -83,6 +89,47 @@ int nw_link_ifindex(struct nw_link* link) { + return link->ifindex; + } + ++static int nw_link_update_ifname(struct nw_link* link, sd_netlink_message* message) { ++ const char* ifname = NULL; ++ int r; ++ ++ r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname); ++ if (r < 0) { ++ ERROR("Could not read link name for link %d: %m\n", link->ifindex); ++ return 1; ++ } ++ ++ // Do nothing if the name is already set ++ if (strcmp(link->ifname, ifname) == 0) ++ return 0; ++ ++ // Otherwise update the name ++ r = nw_string_set(link->ifname, ifname); ++ if (r) { ++ ERROR("Could not set link name: %m\n"); ++ return 1; ++ } ++ ++ DEBUG("Link %d has been renamed to '%s'\n", link->ifindex, link->ifname); ++ ++ return 0; ++} ++ ++/* ++ This function is called whenever anything changes, so that we can ++ update our internal link object. ++*/ ++static int nw_link_update(struct nw_link* link, sd_netlink_message* message) { ++ int r; ++ ++ // Update the interface name ++ r = nw_link_update_ifname(link, message); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { + struct nw_links* links = NULL; + struct nw_link* link = NULL; +@@ -166,7 +213,10 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { + goto ERROR; + } + +- // TODO Import any data from the netlink message ++ // Import any data from the netlink message ++ r = nw_link_update(link, message); ++ if (r) ++ goto ERROR; + + break; + +-- +2.39.2 + diff --git a/network/patches/0190-networkd-Read-link-MTU.patch b/network/patches/0190-networkd-Read-link-MTU.patch new file mode 100644 index 000000000..9da1cd019 --- /dev/null +++ b/network/patches/0190-networkd-Read-link-MTU.patch @@ -0,0 +1,96 @@ +From f37df5ea0920add075e294db28a3ec5ed83b0fe5 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 10:13:37 +0000 +Subject: [PATCH 190/304] networkd: Read link MTU + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 40f809f..62be893 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -40,6 +40,11 @@ struct nw_link { + + // Interface Name + char ifname[IF_NAMESIZE]; ++ ++ // MTU ++ uint32_t mtu; ++ uint32_t min_mtu; ++ uint32_t max_mtu; + }; + + int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) { +@@ -115,6 +120,54 @@ static int nw_link_update_ifname(struct nw_link* link, sd_netlink_message* messa + return 0; + } + ++static int nw_link_update_mtu(struct nw_link* link, sd_netlink_message* message) { ++ uint32_t mtu = 0; ++ uint32_t min_mtu = 0; ++ uint32_t max_mtu = 0; ++ int r; ++ ++ // Read the MTU ++ r = sd_netlink_message_read_u32(message, IFLA_MTU, &mtu); ++ if (r < 0) { ++ ERROR("Could not read MTU for link %d: %m\n", link->ifindex); ++ return r; ++ } ++ ++ // Read the minimum MTU ++ r = sd_netlink_message_read_u32(message, IFLA_MIN_MTU, &min_mtu); ++ if (r < 0) { ++ ERROR("Could not read the minimum MTU for link %d: %m\n", link->ifindex); ++ return r; ++ } ++ ++ // Read the maximum MTU ++ r = sd_netlink_message_read_u32(message, IFLA_MAX_MTU, &max_mtu); ++ if (r < 0) { ++ ERROR("Could not read the maximum MTU for link %d: %m\n", link->ifindex); ++ return r; ++ } ++ ++ // Set the maximum MTU to infinity ++ if (!max_mtu) ++ max_mtu = UINT32_MAX; ++ ++ // Store min/max MTU ++ link->min_mtu = min_mtu; ++ link->max_mtu = max_mtu; ++ ++ // End here, if the MTU has not been changed ++ if (link->mtu == mtu) ++ return 0; ++ ++ DEBUG("Link %d: MTU has changed to %" PRIu32 " (min: %" PRIu32 ", max: %" PRIu32 ")\n", ++ link->ifindex, link->mtu, link->min_mtu, link->max_mtu); ++ ++ // Store MTU ++ link->mtu = mtu; ++ ++ return 0; ++} ++ + /* + This function is called whenever anything changes, so that we can + update our internal link object. +@@ -127,6 +180,11 @@ static int nw_link_update(struct nw_link* link, sd_netlink_message* message) { + if (r) + return r; + ++ // Update the MTU ++ r = nw_link_update_mtu(link, message); ++ if (r) ++ return r; ++ + return 0; + } + +-- +2.39.2 + diff --git a/network/patches/0191-networkd-config-Actually-return-entry-instead-of-fre.patch b/network/patches/0191-networkd-config-Actually-return-entry-instead-of-fre.patch new file mode 100644 index 000000000..19ebcc0fb --- /dev/null +++ b/network/patches/0191-networkd-config-Actually-return-entry-instead-of-fre.patch @@ -0,0 +1,27 @@ +From 82f84c5ff3079de8b57f5a10a118fb4ecab20ffb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 15:24:19 +0000 +Subject: [PATCH 191/304] networkd: config: Actually return entry instead of + freeing it straight away + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 788308f..ef6218e 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -72,6 +72,8 @@ static struct nw_config_entry* nw_config_entry_create( + // Append the new entry + STAILQ_INSERT_TAIL(&config->entries, entry, nodes); + ++ return entry; ++ + ERROR: + nw_config_entry_free(entry); + return NULL; +-- +2.39.2 + diff --git a/network/patches/0192-networkd-config-Implement-reading-configuration-file.patch b/network/patches/0192-networkd-config-Implement-reading-configuration-file.patch new file mode 100644 index 000000000..b8fc1dbef --- /dev/null +++ b/network/patches/0192-networkd-config-Implement-reading-configuration-file.patch @@ -0,0 +1,139 @@ +From 5ef56cff5e19dcda00a76a40846fe3def9e6239f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 15:24:53 +0000 +Subject: [PATCH 192/304] networkd: config: Implement reading configuration + files + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 46 ++++++++++++++++++++++++++++++++++++++++--- + src/networkd/string.h | 41 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 84 insertions(+), 3 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index ef6218e..17d6d89 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -157,9 +157,49 @@ int nw_config_flush(struct nw_config* config) { + } + + static int nw_config_readf(struct nw_config* config, FILE* f) { +- // XXX TODO ++ char* line = NULL; ++ size_t length = 0; ++ int r; + +- return 0; ++ ssize_t bytes_read = 0; ++ ++ char* key = NULL; ++ char* val = NULL; ++ ++ for (;;) { ++ // Read the next line ++ bytes_read = getline(&line, &length, f); ++ if (bytes_read < 0) ++ break; ++ ++ // Key starts at the beginning of the line ++ key = line; ++ ++ // Value starts after '=' ++ val = strchr(line, '='); ++ ++ // Invalid line without a '=' character ++ if (!val) ++ continue; ++ ++ // Split the string ++ *val++ = '\0'; ++ ++ // Strip any whitespace from value ++ r = nw_string_strip(val); ++ if (r) ++ break; ++ ++ // Store the setting ++ r = nw_config_set(config, key, val); ++ if (r) ++ break; ++ } ++ ++ if (line) ++ free(line); ++ ++ return r; + } + + int nw_config_read(struct nw_config* config) { +@@ -204,7 +244,7 @@ static int nw_config_writef(struct nw_config* config, FILE* f) { + continue; + + // Write the entry +- r = fprintf(f, "%s=\"%s\"\n", entry->key, entry->value); ++ r = fprintf(f, "%s=%s\n", entry->key, entry->value); + if (r < 0) { + ERROR("Failed to write configuration: %m\n"); + return r; +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 4ae2dbf..f3c5b71 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -21,6 +21,7 @@ + #ifndef NETWORKD_STRING_H + #define NETWORKD_STRING_H + ++#include + #include + #include + #include +@@ -79,6 +80,46 @@ static inline int __nw_string_set(char* s, const size_t length, const char* valu + return __nw_string_format(s, length, "%s", value); + } + ++static inline int nw_string_lstrip(char* s) { ++ char* p = s; ++ ++ // Count any leading spaces ++ while (*p && isspace(*p)) ++ p++; ++ ++ // Move the string to the beginning of the buffer ++ while (*p) ++ *s++ = *p++; ++ ++ // Terminate the string ++ *s = '\0'; ++ ++ return 0; ++} ++ ++static inline int nw_string_rstrip(char* s) { ++ ssize_t l = strlen(s) - 1; ++ ++ while (l >= 0 && isspace(s[l])) ++ s[l--] = '\0'; ++ ++ return 0; ++} ++ ++static inline int nw_string_strip(char* s) { ++ int r; ++ ++ r = nw_string_lstrip(s); ++ if (r) ++ return r; ++ ++ r = nw_string_rstrip(s); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + /* + Paths + */ +-- +2.39.2 + diff --git a/network/patches/0193-networkd-Add-scaffolding-for-ports.patch b/network/patches/0193-networkd-Add-scaffolding-for-ports.patch new file mode 100644 index 000000000..ca9832e08 --- /dev/null +++ b/network/patches/0193-networkd-Add-scaffolding-for-ports.patch @@ -0,0 +1,159 @@ +From abeab06924b22765dbc410c563f27077f348b5e9 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 16:15:46 +0000 +Subject: [PATCH 193/304] networkd: Add scaffolding for ports + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/port.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ + src/networkd/port.h | 33 ++++++++++++++++++ + 3 files changed, 119 insertions(+) + create mode 100644 src/networkd/port.c + create mode 100644 src/networkd/port.h + +diff --git a/Makefile.am b/Makefile.am +index 024bf45..4bd3975 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -324,6 +324,8 @@ dist_networkd_SOURCES = \ + src/networkd/links.h \ + src/networkd/logging.h \ + src/networkd/main.c \ ++ src/networkd/port.c \ ++ src/networkd/port.h \ + src/networkd/string.h \ + src/networkd/zones.c \ + src/networkd/zones.h \ +diff --git a/src/networkd/port.c b/src/networkd/port.c +new file mode 100644 +index 0000000..019521f +--- /dev/null ++++ b/src/networkd/port.c +@@ -0,0 +1,84 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++ ++#include "config.h" ++#include "string.h" ++#include "port.h" ++ ++struct nw_port { ++ int nrefs; ++ ++ char name[IF_NAMESIZE]; ++ ++ // Configuration ++ struct nw_config *config; ++}; ++ ++static void nw_port_free(struct nw_port* port) { ++ if (port->config) ++ nw_config_unref(port->config); ++ ++ free(port); ++} ++ ++int nw_port_create(struct nw_port** port, const char* name) { ++ int r; ++ ++ // Allocate a new object ++ struct nw_port* p = calloc(1, sizeof(*p)); ++ if (!p) ++ return 1; ++ ++ // Initialize reference counter ++ p->nrefs = 1; ++ ++ // Store the name ++ r = nw_string_set(p->name, name); ++ if (r) ++ goto ERROR; ++ ++ *port = p; ++ return 0; ++ ++ERROR: ++ nw_port_free(p); ++ return r; ++} ++ ++struct nw_port* nw_port_ref(struct nw_port* port) { ++ port->nrefs++; ++ ++ return port; ++} ++ ++struct nw_port* nw_port_unref(struct nw_port* port) { ++ if (--port->nrefs > 0) ++ return port; ++ ++ nw_port_free(port); ++ return NULL; ++} ++ ++const char* nw_port_name(struct nw_port* port) { ++ return port->name; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +new file mode 100644 +index 0000000..cea6203 +--- /dev/null ++++ b/src/networkd/port.h +@@ -0,0 +1,33 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_H ++#define NETWORKD_PORT_H ++ ++struct nw_port; ++ ++int nw_port_create(struct nw_port** port, const char* name); ++ ++struct nw_port* nw_port_ref(struct nw_port* port); ++struct nw_port* nw_port_unref(struct nw_port* port); ++ ++const char* nw_port_name(struct nw_port* port); ++ ++#endif /* NETWORKD_PORT_H */ +-- +2.39.2 + diff --git a/network/patches/0194-networkd-Add-port-container.patch b/network/patches/0194-networkd-Add-port-container.patch new file mode 100644 index 000000000..53004d0a9 --- /dev/null +++ b/network/patches/0194-networkd-Add-port-container.patch @@ -0,0 +1,240 @@ +From b8db2713c790000860e1c3b0d4f8e588cfa5ac04 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 10 Feb 2023 16:26:36 +0000 +Subject: [PATCH 194/304] networkd: Add port container + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/daemon.c | 23 ++++++++++ + src/networkd/ports.c | 100 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/ports.h | 35 +++++++++++++++ + 4 files changed, 160 insertions(+) + create mode 100644 src/networkd/ports.c + create mode 100644 src/networkd/ports.h + +diff --git a/Makefile.am b/Makefile.am +index 4bd3975..d78d61e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -326,6 +326,8 @@ dist_networkd_SOURCES = \ + src/networkd/main.c \ + src/networkd/port.c \ + src/networkd/port.h \ ++ src/networkd/ports.c \ ++ src/networkd/ports.h \ + src/networkd/string.h \ + src/networkd/zones.c \ + src/networkd/zones.h \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index dc2aed6..aee27e3 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -34,6 +34,7 @@ + #include "link.h" + #include "links.h" + #include "logging.h" ++#include "ports.h" + #include "zone.h" + #include "zones.h" + +@@ -62,6 +63,10 @@ struct nw_daemon { + + // Zones + struct nw_zones* zones; ++ ++ // Ports ++ struct nw_ports* ports; ++ + }; + + static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, +@@ -248,6 +253,17 @@ static int nw_daemon_enumerate_links(struct nw_daemon* daemon) { + return nw_links_enumerate(daemon->links); + } + ++static int nw_daemon_enumerate_ports(struct nw_daemon* daemon) { ++ int r; ++ ++ // Create a new ports container ++ r = nw_ports_create(&daemon->ports, daemon); ++ if (r) ++ return r; ++ ++ return nw_ports_enumerate(daemon->ports); ++} ++ + static int nw_daemon_enumerate(struct nw_daemon* daemon) { + int r; + +@@ -256,6 +272,11 @@ static int nw_daemon_enumerate(struct nw_daemon* daemon) { + if (r) + return r; + ++ // Ports ++ r = nw_daemon_enumerate_ports(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +@@ -322,6 +343,8 @@ ERROR: + } + + static void nw_daemon_cleanup(struct nw_daemon* daemon) { ++ if (daemon->ports) ++ nw_ports_unref(daemon->ports); + if (daemon->zones) + nw_zones_unref(daemon->zones); + if (daemon->links) +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +new file mode 100644 +index 0000000..500153a +--- /dev/null ++++ b/src/networkd/ports.c +@@ -0,0 +1,100 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++ ++#include "logging.h" ++#include "port.h" ++#include "ports.h" ++ ++struct nw_ports_entry { ++ struct nw_port* port; ++ ++ // Link to the other entries ++ STAILQ_ENTRY(nw_ports_entry) nodes; ++}; ++ ++struct nw_ports { ++ struct nw_daemon* daemon; ++ int nrefs; ++ ++ // Port Entries ++ STAILQ_HEAD(entries, nw_ports_entry) entries; ++ ++ // A counter of the port entries ++ unsigned int num; ++}; ++ ++int nw_ports_create(struct nw_ports** ports, struct nw_daemon* daemon) { ++ struct nw_ports* p = calloc(1, sizeof(*p)); ++ if (!p) ++ return 1; ++ ++ // Store a reference to the daemon ++ p->daemon = nw_daemon_ref(daemon); ++ ++ // Initialize the reference counter ++ p->nrefs = 1; ++ ++ // Initialize entries ++ STAILQ_INIT(&p->entries); ++ ++ // Reference the pointer ++ *ports = p; ++ ++ return 0; ++} ++ ++static void nw_ports_free(struct nw_ports* ports) { ++ struct nw_ports_entry* entry = NULL; ++ ++ while (!STAILQ_EMPTY(&ports->entries)) { ++ entry = STAILQ_FIRST(&ports->entries); ++ ++ // Dereference the port ++ nw_port_unref(entry->port); ++ ++ // Remove the entry from the list ++ STAILQ_REMOVE_HEAD(&ports->entries, nodes); ++ ++ // Free the entry ++ free(entry); ++ } ++} ++ ++struct nw_ports* nw_ports_ref(struct nw_ports* ports) { ++ ports->nrefs++; ++ ++ return ports; ++} ++ ++struct nw_ports* nw_ports_unref(struct nw_ports* ports) { ++ if (--ports->nrefs > 0) ++ return ports; ++ ++ nw_ports_free(ports); ++ return NULL; ++} ++ ++int nw_ports_enumerate(struct nw_ports* ports) { ++ return 0; // XXX TODO ++} +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +new file mode 100644 +index 0000000..76a4a3a +--- /dev/null ++++ b/src/networkd/ports.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORTS_H ++#define NETWORKD_PORTS_H ++ ++struct nw_ports; ++ ++#include "daemon.h" ++ ++int nw_ports_create(struct nw_ports** ports, struct nw_daemon* daemon); ++ ++struct nw_ports* nw_ports_ref(struct nw_ports* ports); ++struct nw_ports* nw_ports_unref(struct nw_ports* ports); ++ ++int nw_ports_enumerate(struct nw_ports* ports); ++ ++#endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0195-networkd-Enumerate-ports-on-startup.patch b/network/patches/0195-networkd-Enumerate-ports-on-startup.patch new file mode 100644 index 000000000..30b406c35 --- /dev/null +++ b/network/patches/0195-networkd-Enumerate-ports-on-startup.patch @@ -0,0 +1,247 @@ +From c791afc87a22936e9564e449182ee6452659887e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 10:59:03 +0000 +Subject: [PATCH 195/304] networkd: Enumerate ports on startup + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/port.h | 2 ++ + src/networkd/ports.c | 61 ++++++++++++++++++++++++++++++++++++++++++- + src/networkd/string.h | 8 ++++++ + src/networkd/util.c | 61 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/util.h | 29 ++++++++++++++++++++ + 6 files changed, 162 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/util.c + create mode 100644 src/networkd/util.h + +diff --git a/Makefile.am b/Makefile.am +index d78d61e..505d679 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -329,6 +329,8 @@ dist_networkd_SOURCES = \ + src/networkd/ports.c \ + src/networkd/ports.h \ + src/networkd/string.h \ ++ src/networkd/util.c \ ++ src/networkd/util.h \ + src/networkd/zones.c \ + src/networkd/zones.h \ + src/networkd/zone.c \ +diff --git a/src/networkd/port.h b/src/networkd/port.h +index cea6203..250a694 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_PORT_H + #define NETWORKD_PORT_H + ++#define PORT_CONFIG_DIR CONFIG_DIR "/ports" ++ + struct nw_port; + + int nw_port_create(struct nw_port** port, const char* name); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 500153a..19a3a59 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -21,10 +21,13 @@ + #include + #include + #include ++#include + + #include "logging.h" + #include "port.h" + #include "ports.h" ++#include "string.h" ++#include "util.h" + + struct nw_ports_entry { + struct nw_port* port; +@@ -95,6 +98,62 @@ struct nw_ports* nw_ports_unref(struct nw_ports* ports) { + return NULL; + } + ++static int nw_ports_add_port(struct nw_ports* ports, struct nw_port* port) { ++ // Allocate a new entry ++ struct nw_ports_entry* entry = calloc(1, sizeof(*entry)); ++ if (!entry) ++ return 1; ++ ++ // Reference the port ++ entry->port = nw_port_ref(port); ++ ++ // Add it to the list ++ STAILQ_INSERT_TAIL(&ports->entries, entry, nodes); ++ ++ // Increment the counter ++ ports->num++; ++ ++ return 0; ++} ++ ++static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { ++ struct nw_port* port = NULL; ++ int r; ++ ++ struct nw_ports* ports = (struct nw_ports*)data; ++ ++ // Skip anything that isn't a regular file ++ if (!S_ISREG(s->st_mode)) ++ return 0; ++ ++ // Find the basename of the file ++ const char* name = nw_path_basename(path); ++ ++ // Break on invalid paths ++ if (!name) ++ return 0; ++ ++ // Skip any hidden files ++ if (*name == '.') ++ return 0; ++ ++ // Create a new port ++ r = nw_port_create(&port, name); ++ if (r) ++ goto ERROR; ++ ++ // Add the port to the list ++ r = nw_ports_add_port(ports, port); ++ if (r) ++ goto ERROR; ++ ++ERROR: ++ if (port) ++ nw_port_unref(port); ++ ++ return r; ++} ++ + int nw_ports_enumerate(struct nw_ports* ports) { +- return 0; // XXX TODO ++ return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); + } +diff --git a/src/networkd/string.h b/src/networkd/string.h +index f3c5b71..6ff44f9 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -142,4 +142,12 @@ static inline int __nw_path_join(char* s, const size_t length, + return __nw_string_format(s, length, "%s/%s", first, second); + } + ++static inline const char* nw_path_basename(const char* path) { ++ const char* basename = strrchr(path, '/'); ++ if (!basename) ++ return NULL; ++ ++ return basename + 1; ++} ++ + #endif /* NETWORKD_STRING_H */ +diff --git a/src/networkd/util.c b/src/networkd/util.c +new file mode 100644 +index 0000000..0381ea8 +--- /dev/null ++++ b/src/networkd/util.c +@@ -0,0 +1,61 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "util.h" ++ ++int nw_ftw(const char* path, const char* filter, ++ int (*callback)(const char* path, const struct stat* s, void* data), void* data) { ++ /* ++ This is a nested function which allows us to pass some custom pointer to ++ the callback function as that isn't possible with nftw(). ++ */ ++ int __callback(const char* p, const struct stat* s, int type, struct FTW* ftw) { ++ int r; ++ ++ // Filter out anything we don't want ++ if (filter) { ++ r = fnmatch(filter, p, FNM_PATHNAME); ++ ++ switch (r) { ++ // Pattern didn't match ++ case FNM_NOMATCH: ++ return 0; ++ ++ // Pattern matched ++ case 0: ++ break; ++ ++ // Error ++ default: ++ return 1; ++ } ++ } ++ ++ return callback(p, s, data); ++ } ++ ++ return nftw(path, __callback, 0, 0); ++} +diff --git a/src/networkd/util.h b/src/networkd/util.h +new file mode 100644 +index 0000000..950afda +--- /dev/null ++++ b/src/networkd/util.h +@@ -0,0 +1,29 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_UTIL_H ++#define NETWORKD_UTIL_H ++ ++#include ++ ++int nw_ftw(const char* path, const char* filter, ++ int (*callback)(const char* path, const struct stat* s, void* data), void* data); ++ ++#endif /* NETWORKD_UTIL_H */ +-- +2.39.2 + diff --git a/network/patches/0196-networkd-Perform-port-setup-from-configuration.patch b/network/patches/0196-networkd-Perform-port-setup-from-configuration.patch new file mode 100644 index 000000000..96bc04918 --- /dev/null +++ b/network/patches/0196-networkd-Perform-port-setup-from-configuration.patch @@ -0,0 +1,147 @@ +From 827435c82f60ba1b7717d74faeac6cb6b85d6588 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 11:21:02 +0000 +Subject: [PATCH 196/304] networkd: Perform port setup from configuration + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ + src/networkd/port.h | 5 +++ + 2 files changed, 81 insertions(+) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 019521f..f78489b 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -18,10 +18,12 @@ + # # + #############################################################################*/ + ++#include + #include + #include + + #include "config.h" ++#include "logging.h" + #include "string.h" + #include "port.h" + +@@ -29,11 +31,31 @@ struct nw_port { + int nrefs; + + char name[IF_NAMESIZE]; ++ nw_port_type_t type; + + // Configuration + struct nw_config *config; + }; + ++static const struct nw_port_type_map { ++ nw_port_type_t type; ++ const char* name; ++} nw_port_type_map[] = { ++ { NW_PORT_DUMMY, "dummy" }, ++ { NW_PORT_UNKNOWN, NULL }, ++}; ++ ++static nw_port_type_t nw_port_type_from_string(const char* s) { ++ const struct nw_port_type_map* map = NULL; ++ ++ for (map = nw_port_type_map; *map->name; map++) { ++ if (strcmp(map->name, s) == 0) ++ return map->type; ++ } ++ ++ return NW_PORT_UNKNOWN; ++} ++ + static void nw_port_free(struct nw_port* port) { + if (port->config) + nw_config_unref(port->config); +@@ -41,6 +63,55 @@ static void nw_port_free(struct nw_port* port) { + free(port); + } + ++static int nw_port_setup_common(struct nw_port* port) { ++ return 0; // XXX TODO ++} ++ ++static nw_port_type_t nw_port_setup_type(struct nw_port* port) { ++ const char* type = nw_config_get(port->config, "TYPE"); ++ if (!type) ++ return NW_PORT_UNKNOWN; ++ ++ return nw_port_type_from_string(type); ++} ++ ++static int nw_port_setup(struct nw_port* port) { ++ char path[PATH_MAX]; ++ int r; ++ ++ // Compose the path to the main configuration file ++ r = nw_path_join(path, PORT_CONFIG_DIR, port->name); ++ if (r) ++ return r; ++ ++ // Initialize the configuration ++ r = nw_config_create(&port->config, path); ++ if (r) ++ return r; ++ ++ // Determine type ++ port->type = nw_port_setup_type(port); ++ if (!port->type) { ++ ERROR("Could not determine type of port %s\n", port->name); ++ return 0; ++ } ++ ++ // Perform some common initialization ++ r = nw_port_setup_common(port); ++ if (r) ++ return r; ++ ++ // Call any custom initialization ++ switch (port->type) { ++ // These do not need any special initialization ++ case NW_PORT_DUMMY: ++ case NW_PORT_UNKNOWN: ++ break; ++ } ++ ++ return 0; ++} ++ + int nw_port_create(struct nw_port** port, const char* name) { + int r; + +@@ -57,6 +128,11 @@ int nw_port_create(struct nw_port** port, const char* name) { + if (r) + goto ERROR; + ++ // Setup the port ++ r = nw_port_setup(p); ++ if (r) ++ goto ERROR; ++ + *port = p; + return 0; + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 250a694..af7fbdd 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -23,6 +23,11 @@ + + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" + ++typedef enum nw_port_type { ++ NW_PORT_UNKNOWN = 0, ++ NW_PORT_DUMMY, ++} nw_port_type_t; ++ + struct nw_port; + + int nw_port_create(struct nw_port** port, const char* name); +-- +2.39.2 + diff --git a/network/patches/0197-networkd-Read-Ethernet-address-from-configuration.patch b/network/patches/0197-networkd-Read-Ethernet-address-from-configuration.patch new file mode 100644 index 000000000..38ca85ee1 --- /dev/null +++ b/network/patches/0197-networkd-Read-Ethernet-address-from-configuration.patch @@ -0,0 +1,145 @@ +From 2e7f4705a61e8435e22d49fcff49ecf8dde389ef Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 11:48:23 +0000 +Subject: [PATCH 197/304] networkd: Read Ethernet address from configuration + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + src/networkd/address.h | 47 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/port.c | 36 +++++++++++++++++++++++++++++++- + 3 files changed, 83 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/address.h + +diff --git a/Makefile.am b/Makefile.am +index 505d679..a27736a 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -308,6 +308,7 @@ sbin_PROGRAMS += \ + networkd + + dist_networkd_SOURCES = \ ++ src/networkd/address.h \ + src/networkd/bus.c \ + src/networkd/bus.h \ + src/networkd/config.c \ +diff --git a/src/networkd/address.h b/src/networkd/address.h +new file mode 100644 +index 0000000..1d9fbfc +--- /dev/null ++++ b/src/networkd/address.h +@@ -0,0 +1,47 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_ADDRESS_H ++#define NETWORKD_ADDRESS_H ++ ++#include ++#include ++ ++typedef struct ether_addr nw_address_t; ++ ++static inline int nw_address_from_string(nw_address_t* addr, const char* s) { ++ struct ether_addr* p = ether_aton_r(s, addr); ++ if (!p) ++ return 1; ++ ++ return 0; ++} ++ ++static inline char* nw_address_to_string(const nw_address_t* addr) { ++ char buffer[ETH_ALEN]; ++ ++ char* p = ether_ntoa_r(addr, buffer); ++ if (!p) ++ return NULL; ++ ++ return strdup(buffer); ++} ++ ++#endif /* NETWORKD_ADDRESS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index f78489b..aff79a5 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -20,8 +20,10 @@ + + #include + #include ++#include + #include + ++#include "address.h" + #include "config.h" + #include "logging.h" + #include "string.h" +@@ -35,6 +37,9 @@ struct nw_port { + + // Configuration + struct nw_config *config; ++ ++ // Common attributes ++ nw_address_t address; + }; + + static const struct nw_port_type_map { +@@ -63,8 +68,37 @@ static void nw_port_free(struct nw_port* port) { + free(port); + } + ++static int nw_port_setup_address(struct nw_port* port) { ++ int r; ++ ++ // Read ADDRESS from configuration ++ const char* s = nw_config_get(port->config, "ADDRESS"); ++ if (!s) { ++ ERROR("Port %s: Address isn't set\n", port->name); ++ return 1; ++ } ++ ++ // Parse the address ++ r = nw_address_from_string(&port->address, s); ++ if (r) { ++ ERROR("Port %s: Could not parse address: %m\n", port->name); ++ return r; ++ } ++ ++ // XXX Do we need to check for multicast here? ++ ++ return 0; ++} ++ + static int nw_port_setup_common(struct nw_port* port) { +- return 0; // XXX TODO ++ int r; ++ ++ // Address ++ r = nw_port_setup_address(port); ++ if (r) ++ return r; ++ ++ return 0; + } + + static nw_port_type_t nw_port_setup_type(struct nw_port* port) { +-- +2.39.2 + diff --git a/network/patches/0198-networkd-Generate-a-random-Ethernet-address-for-port.patch b/network/patches/0198-networkd-Generate-a-random-Ethernet-address-for-port.patch new file mode 100644 index 000000000..8067e204d --- /dev/null +++ b/network/patches/0198-networkd-Generate-a-random-Ethernet-address-for-port.patch @@ -0,0 +1,93 @@ +From 9a93da54510ec2b49e0890d2b420a097316eaace Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 12:01:42 +0000 +Subject: [PATCH 198/304] networkd: Generate a random Ethernet address for + ports + +This happens when either no address was set, or it cannot be parsed. + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 25 +++++++++++++++++++++++++ + src/networkd/port.c | 14 ++++++++++++-- + 2 files changed, 37 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index 1d9fbfc..f875b26 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -23,6 +23,9 @@ + + #include + #include ++#include ++ ++#include "logging.h" + + typedef struct ether_addr nw_address_t; + +@@ -44,4 +47,26 @@ static inline char* nw_address_to_string(const nw_address_t* addr) { + return strdup(buffer); + } + ++static inline int nw_address_generate(nw_address_t* addr) { ++ ssize_t bytes = getrandom(addr, sizeof(*addr), 0); ++ if (bytes < 0) { ++ ERROR("getrandom() failed: %m\n"); ++ return 1; ++ } ++ ++ // Check if we filled the entire buffer ++ if (bytes < (ssize_t)sizeof(*addr)) { ++ ERROR("Could not gather enough randomness\n"); ++ return 1; ++ } ++ ++ // Clear the multicast bit ++ addr->ether_addr_octet[0] &= 0xfe; ++ ++ // Set the software-generated bit ++ addr->ether_addr_octet[1] |= 0x02; ++ ++ return 0; ++} ++ + #endif /* NETWORKD_ADDRESS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index aff79a5..4c32592 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -75,18 +75,28 @@ static int nw_port_setup_address(struct nw_port* port) { + const char* s = nw_config_get(port->config, "ADDRESS"); + if (!s) { + ERROR("Port %s: Address isn't set\n", port->name); +- return 1; ++ goto ERROR; + } + + // Parse the address + r = nw_address_from_string(&port->address, s); + if (r) { + ERROR("Port %s: Could not parse address: %m\n", port->name); +- return r; ++ goto ERROR; + } + + // XXX Do we need to check for multicast here? + ++ return 0; ++ ++ERROR: ++ // Generate a random Ethernet address ++ r = nw_address_generate(&port->address); ++ if (r) { ++ ERROR("Could not generate a random Ethernet address: %m\n"); ++ return r; ++ } ++ + return 0; + } + +-- +2.39.2 + diff --git a/network/patches/0199-networkd-Introduce-address-flags-for-better-readabil.patch b/network/patches/0199-networkd-Introduce-address-flags-for-better-readabil.patch new file mode 100644 index 000000000..35671509c --- /dev/null +++ b/network/patches/0199-networkd-Introduce-address-flags-for-better-readabil.patch @@ -0,0 +1,43 @@ +From 35fc59cd654c084cfe2550ed874d768f624b591e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 12:06:18 +0000 +Subject: [PATCH 199/304] networkd: Introduce address flags for better + readability + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index f875b26..0885d75 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -29,6 +29,11 @@ + + typedef struct ether_addr nw_address_t; + ++enum { ++ NW_ADDRESS_MULTICAST = (1 << 0), ++ NW_ADDRESS_SOFTWAREASSIGNED = (1 << 1), ++}; ++ + static inline int nw_address_from_string(nw_address_t* addr, const char* s) { + struct ether_addr* p = ether_aton_r(s, addr); + if (!p) +@@ -61,10 +66,10 @@ static inline int nw_address_generate(nw_address_t* addr) { + } + + // Clear the multicast bit +- addr->ether_addr_octet[0] &= 0xfe; ++ addr->ether_addr_octet[0] &= ~NW_ADDRESS_MULTICAST; + + // Set the software-generated bit +- addr->ether_addr_octet[1] |= 0x02; ++ addr->ether_addr_octet[0] |= NW_ADDRESS_SOFTWAREASSIGNED; + + return 0; + } +-- +2.39.2 + diff --git a/network/patches/0200-networkd-Check-if-Ethernet-addresses-from-config-are.patch b/network/patches/0200-networkd-Check-if-Ethernet-addresses-from-config-are.patch new file mode 100644 index 000000000..b1f3b2ab4 --- /dev/null +++ b/network/patches/0200-networkd-Check-if-Ethernet-addresses-from-config-are.patch @@ -0,0 +1,46 @@ +From d81d9cf5582b9be41968c10c01bf436b066d4e34 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 12:10:15 +0000 +Subject: [PATCH 200/304] networkd: Check if Ethernet addresses from config are + usable + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 4 ++++ + src/networkd/port.c | 7 ++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index 0885d75..d284a0b 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -74,4 +74,8 @@ static inline int nw_address_generate(nw_address_t* addr) { + return 0; + } + ++static inline int nw_address_is_multicast(const nw_address_t* addr) { ++ return (addr->ether_addr_octet[0] & NW_ADDRESS_MULTICAST); ++} ++ + #endif /* NETWORKD_ADDRESS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 4c32592..89f3181 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -85,7 +85,12 @@ static int nw_port_setup_address(struct nw_port* port) { + goto ERROR; + } + +- // XXX Do we need to check for multicast here? ++ // Check if this address is usable ++ r = nw_address_is_multicast(&port->address); ++ if (r) { ++ DEBUG("Port %s: Multicast bit is set on Ethernet address\n", port->name); ++ goto ERROR; ++ } + + return 0; + +-- +2.39.2 + diff --git a/network/patches/0201-networkd-Export-ports-over-dbus.patch b/network/patches/0201-networkd-Export-ports-over-dbus.patch new file mode 100644 index 000000000..4381b54bb --- /dev/null +++ b/network/patches/0201-networkd-Export-ports-over-dbus.patch @@ -0,0 +1,347 @@ +From 7297ba7fab067d53560eaeba7e8aa992cef3308a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 12:34:41 +0000 +Subject: [PATCH 201/304] networkd: Export ports over dbus + +Signed-off-by: Michael Tremer +--- + Makefile.am | 6 ++- + src/networkd/daemon-bus.c | 3 +- + src/networkd/daemon.c | 14 ++++++ + src/networkd/daemon.h | 6 +++ + src/networkd/port-bus.c | 89 +++++++++++++++++++++++++++++++++++++++ + src/networkd/port-bus.h | 28 ++++++++++++ + src/networkd/port.c | 14 ++++++ + src/networkd/port.h | 2 + + src/networkd/ports.c | 52 +++++++++++++++++++++++ + src/networkd/ports.h | 6 ++- + 10 files changed, 216 insertions(+), 4 deletions(-) + create mode 100644 src/networkd/port-bus.c + create mode 100644 src/networkd/port-bus.h + +diff --git a/Makefile.am b/Makefile.am +index a27736a..893f1b8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -325,10 +325,12 @@ dist_networkd_SOURCES = \ + src/networkd/links.h \ + src/networkd/logging.h \ + src/networkd/main.c \ +- src/networkd/port.c \ +- src/networkd/port.h \ + src/networkd/ports.c \ + src/networkd/ports.h \ ++ src/networkd/port.c \ ++ src/networkd/port.h \ ++ src/networkd/port-bus.c \ ++ src/networkd/port-bus.h \ + src/networkd/string.h \ + src/networkd/util.c \ + src/networkd/util.h \ +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +index aac9775..ca0754f 100644 +--- a/src/networkd/daemon-bus.c ++++ b/src/networkd/daemon-bus.c +@@ -22,6 +22,7 @@ + + #include "bus.h" + #include "daemon.h" ++#include "port-bus.h" + #include "zone-bus.h" + + static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* error) { +@@ -45,5 +46,5 @@ const struct nw_bus_implementation daemon_bus_impl = { + .path = "/org/ipfire/network1", + .interface = "org.ipfire.network1", + .vtables = BUS_VTABLES(daemon_vtable), +- .children = BUS_IMPLEMENTATIONS(&zone_bus_impl), ++ .children = BUS_IMPLEMENTATIONS(&port_bus_impl, &zone_bus_impl), + }; +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index aee27e3..795a8b7 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -448,6 +448,20 @@ struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifin + return nw_links_get_by_ifindex(daemon->links, ifindex); + } + ++/* ++ Ports ++*/ ++struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon) { ++ return nw_ports_ref(daemon->ports); ++} ++ ++struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name) { ++ if (!daemon->ports) ++ return NULL; ++ ++ return nw_ports_get_by_name(daemon->ports, name); ++} ++ + /* + Zones + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 8e534c5..e08537e 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -49,6 +49,12 @@ struct nw_links* nw_daemon_links(struct nw_daemon* daemon); + void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link); + struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex); + ++/* ++ Ports ++*/ ++struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon); ++struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name); ++ + /* + Zones + */ +diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c +new file mode 100644 +index 0000000..8c327b9 +--- /dev/null ++++ b/src/networkd/port-bus.c +@@ -0,0 +1,89 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "bus.h" ++#include "daemon.h" ++#include "logging.h" ++#include "port.h" ++#include "port-bus.h" ++#include "ports.h" ++ ++static int nw_port_node_enumerator(sd_bus* bus, const char* path, void* data, ++ char*** nodes, sd_bus_error* error) { ++ int r; ++ ++ DEBUG("Enumerating ports...\n"); ++ ++ // Fetch a reference to the daemon ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Fetch ports ++ struct nw_ports* ports = nw_daemon_ports(daemon); ++ ++ // Make bus paths for all ports ++ r = nw_ports_bus_paths(ports, nodes); ++ if (r) ++ goto ERROR; ++ ++ERROR: ++ nw_ports_unref(ports); ++ ++ return r; ++} ++ ++static int nw_port_object_find(sd_bus* bus, const char* path, const char* interface, ++ void* data, void** found, sd_bus_error* error) { ++ char* name = NULL; ++ int r; ++ ++ // Fetch a reference to the daemon ++ struct nw_daemon* daemon = (struct nw_daemon*)data; ++ ++ // Decode the path of the requested object ++ r = sd_bus_path_decode(path, "/org/ipfire/network1/port", &name); ++ if (r <= 0) ++ return 0; ++ ++ // Find the port ++ struct nw_port* port = nw_daemon_get_port_by_name(daemon, name); ++ if (!port) ++ return 0; ++ ++ // Match! ++ *found = port; ++ ++ nw_port_unref(port); ++ ++ return 1; ++} ++ ++static const sd_bus_vtable port_vtable[] = { ++ SD_BUS_VTABLE_START(0), ++ SD_BUS_VTABLE_END ++}; ++ ++const struct nw_bus_implementation port_bus_impl = { ++ "/org/ipfire/network1/port", ++ "org.ipfire.network1.Port", ++ .fallback_vtables = BUS_FALLBACK_VTABLES({port_vtable, nw_port_object_find}), ++ .node_enumerator = nw_port_node_enumerator, ++}; +diff --git a/src/networkd/port-bus.h b/src/networkd/port-bus.h +new file mode 100644 +index 0000000..95e49a8 +--- /dev/null ++++ b/src/networkd/port-bus.h +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_BUS_H ++#define NETWORKD_PORT_BUS_H ++ ++#include "bus.h" ++ ++extern const struct nw_bus_implementation port_bus_impl; ++ ++#endif /* NETWORKD_PORT_BUS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 89f3181..d1e3f7f 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + #include "address.h" + #include "config.h" + #include "logging.h" +@@ -207,3 +209,15 @@ struct nw_port* nw_port_unref(struct nw_port* port) { + const char* nw_port_name(struct nw_port* port) { + return port->name; + } ++ ++char* nw_port_bus_path(struct nw_port* port) { ++ char* p = NULL; ++ int r; ++ ++ // Encode the bus path ++ r = sd_bus_path_encode("/org/ipfire/network1/port", port->name, &p); ++ if (r < 0) ++ return NULL; ++ ++ return p; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index af7fbdd..e3655cf 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -37,4 +37,6 @@ struct nw_port* nw_port_unref(struct nw_port* port); + + const char* nw_port_name(struct nw_port* port); + ++char* nw_port_bus_path(struct nw_port* port); ++ + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 19a3a59..24bd257 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -157,3 +157,55 @@ ERROR: + int nw_ports_enumerate(struct nw_ports* ports) { + return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); + } ++ ++struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name) { ++ struct nw_ports_entry* entry = NULL; ++ ++ STAILQ_FOREACH(entry, &ports->entries, nodes) { ++ const char* __name = nw_port_name(entry->port); ++ ++ // If the name matches, return a reference to the zone ++ if (strcmp(name, __name) == 0) ++ return nw_port_ref(entry->port); ++ } ++ ++ // No match found ++ return NULL; ++} ++ ++int nw_ports_bus_paths(struct nw_ports* ports, char*** paths) { ++ struct nw_ports_entry* entry = NULL; ++ char* path = NULL; ++ ++ // Allocate an array for all paths ++ char** p = calloc(ports->num + 1, sizeof(*p)); ++ if (!p) ++ return 1; ++ ++ unsigned int i = 0; ++ ++ // Walk through all ports ++ STAILQ_FOREACH(entry, &ports->entries, nodes) { ++ // Generate the bus path ++ path = nw_port_bus_path(entry->port); ++ if (!path) ++ goto ERROR; ++ ++ // Append the bus path to the array ++ p[i++] = path; ++ } ++ ++ // Return pointer ++ *paths = p; ++ ++ return 0; ++ ++ERROR: ++ if (p) { ++ for (char** e = p; *e; e++) ++ free(*e); ++ free(p); ++ } ++ ++ return 1; ++} +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +index 76a4a3a..e807e25 100644 +--- a/src/networkd/ports.h ++++ b/src/networkd/ports.h +@@ -32,4 +32,8 @@ struct nw_ports* nw_ports_unref(struct nw_ports* ports); + + int nw_ports_enumerate(struct nw_ports* ports); + +-#endif /* NETWORKD_ZONES_H */ ++struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name); ++ ++int nw_ports_bus_paths(struct nw_ports* ports, char*** paths); ++ ++#endif /* NETWORKD_PORTS_H */ +-- +2.39.2 + diff --git a/network/patches/0202-networkd-address-Fix-buffer-to-Ethernet-address-stri.patch b/network/patches/0202-networkd-address-Fix-buffer-to-Ethernet-address-stri.patch new file mode 100644 index 000000000..b72c77c0f --- /dev/null +++ b/network/patches/0202-networkd-address-Fix-buffer-to-Ethernet-address-stri.patch @@ -0,0 +1,27 @@ +From 8c569e1ca29435a0caa6ecc3b2118ac2dbac4466 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 13:53:52 +0000 +Subject: [PATCH 202/304] networkd: address: Fix buffer to Ethernet address + strings + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index d284a0b..b7556f4 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -43,7 +43,7 @@ static inline int nw_address_from_string(nw_address_t* addr, const char* s) { + } + + static inline char* nw_address_to_string(const nw_address_t* addr) { +- char buffer[ETH_ALEN]; ++ char buffer[18]; + + char* p = ether_ntoa_r(addr, buffer); + if (!p) +-- +2.39.2 + diff --git a/network/patches/0203-networkd-ports-Export-Ethernet-address-over-dbus.patch b/network/patches/0203-networkd-ports-Export-Ethernet-address-over-dbus.patch new file mode 100644 index 000000000..91a0ac533 --- /dev/null +++ b/network/patches/0203-networkd-ports-Export-Ethernet-address-over-dbus.patch @@ -0,0 +1,102 @@ +From 4a383286ff94b4bc6efdde95c26070b68b8942e3 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 13:54:33 +0000 +Subject: [PATCH 203/304] networkd: ports: Export Ethernet address over dbus + +Signed-off-by: Michael Tremer +--- + src/networkd/port-bus.c | 34 ++++++++++++++++++++++++++++++++++ + src/networkd/port.c | 4 ++++ + src/networkd/port.h | 4 ++++ + 3 files changed, 42 insertions(+) + +diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c +index 8c327b9..1a48655 100644 +--- a/src/networkd/port-bus.c ++++ b/src/networkd/port-bus.c +@@ -19,7 +19,9 @@ + #############################################################################*/ + + #include ++#include + ++#include "address.h" + #include "bus.h" + #include "daemon.h" + #include "logging.h" +@@ -76,8 +78,40 @@ static int nw_port_object_find(sd_bus* bus, const char* path, const char* interf + return 1; + } + ++static int nw_port_bus_get_address(sd_bus* bus, const char* path, const char* interface, ++ const char* property, sd_bus_message* reply, void* data, sd_bus_error* error) { ++ struct nw_port* port = (struct nw_port*)data; ++ int r; ++ ++ // Fetch the address ++ const nw_address_t* address = nw_port_get_address(port); ++ ++ // Format the address as a string ++ char* s = nw_address_to_string(address); ++ if (!s) { ++ // XXX How to handle any errors? ++ return 0; ++ } ++ ++ // Append the address to the return value ++ r = sd_bus_message_append(reply, "s", s); ++ if (r) ++ goto ERROR; ++ ++ERROR: ++ if (s) ++ free(s); ++ ++ return r; ++} ++ + static const sd_bus_vtable port_vtable[] = { + SD_BUS_VTABLE_START(0), ++ ++ // Address ++ SD_BUS_PROPERTY("Address", "s", nw_port_bus_get_address, ++ 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), ++ + SD_BUS_VTABLE_END + }; + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index d1e3f7f..e59e760 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -221,3 +221,7 @@ char* nw_port_bus_path(struct nw_port* port) { + + return p; + } ++ ++const nw_address_t* nw_port_get_address(struct nw_port* port) { ++ return &port->address; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index e3655cf..caf1433 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -30,6 +30,8 @@ typedef enum nw_port_type { + + struct nw_port; + ++#include "address.h" ++ + int nw_port_create(struct nw_port** port, const char* name); + + struct nw_port* nw_port_ref(struct nw_port* port); +@@ -39,4 +41,6 @@ const char* nw_port_name(struct nw_port* port); + + char* nw_port_bus_path(struct nw_port* port); + ++const nw_address_t* nw_port_get_address(struct nw_port* port); ++ + #endif /* NETWORKD_PORT_H */ +-- +2.39.2 + diff --git a/network/patches/0204-networkd-Add-method-to-fetch-corresponding-link-to-p.patch b/network/patches/0204-networkd-Add-method-to-fetch-corresponding-link-to-p.patch new file mode 100644 index 000000000..e762f961c --- /dev/null +++ b/network/patches/0204-networkd-Add-method-to-fetch-corresponding-link-to-p.patch @@ -0,0 +1,201 @@ +From 30d4ab67ce9936c6668d93229c8cc808c725338c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 14:10:16 +0000 +Subject: [PATCH 204/304] networkd: Add method to fetch corresponding link to + port + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 7 +++++++ + src/networkd/daemon.h | 1 + + src/networkd/link.h | 5 +++-- + src/networkd/links.c | 15 +++++++++++++++ + src/networkd/links.h | 1 + + src/networkd/port.c | 13 ++++++++++++- + src/networkd/port.h | 3 ++- + src/networkd/ports.c | 2 +- + 8 files changed, 42 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 795a8b7..c4acff5 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -448,6 +448,13 @@ struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifin + return nw_links_get_by_ifindex(daemon->links, ifindex); + } + ++struct nw_link* nw_daemon_get_link_by_name(struct nw_daemon* daemon, const char* name) { ++ if (!daemon->links) ++ return NULL; ++ ++ return nw_links_get_by_name(daemon->links, name); ++} ++ + /* + Ports + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index e08537e..a40dd60 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -48,6 +48,7 @@ sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon); + struct nw_links* nw_daemon_links(struct nw_daemon* daemon); + void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link); + struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex); ++struct nw_link* nw_daemon_get_link_by_name(struct nw_daemon* daemon, const char* name); + + /* + Ports +diff --git a/src/networkd/link.h b/src/networkd/link.h +index e482d71..72ddfa9 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -21,16 +21,17 @@ + #ifndef NETWORKD_LINK_H + #define NETWORKD_LINK_H + +-#include "daemon.h" +- + struct nw_link; + ++#include "daemon.h" ++ + int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex); + + struct nw_link* nw_link_ref(struct nw_link* link); + struct nw_link* nw_link_unref(struct nw_link* link); + + int nw_link_ifindex(struct nw_link* link); ++const char* nw_link_name(struct nw_link* link); + + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + +diff --git a/src/networkd/links.c b/src/networkd/links.c +index 044a27d..7aa83a3 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -20,6 +20,7 @@ + + #include + #include ++#include + #include + + #include "daemon.h" +@@ -192,3 +193,17 @@ struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex) { + + return nw_link_ref(entry->link); + } ++ ++struct nw_link* nw_links_get_by_name(struct nw_links* links, const char* name) { ++ struct nw_links_entry* entry = NULL; ++ ++ STAILQ_FOREACH(entry, &links->entries, nodes) { ++ const char* n = nw_link_name(entry->link); ++ ++ if (strcmp(name, n) == 0) ++ return nw_link_ref(entry->link); ++ } ++ ++ // No match found ++ return NULL; ++} +diff --git a/src/networkd/links.h b/src/networkd/links.h +index 2f2bbea..2b5c787 100644 +--- a/src/networkd/links.h ++++ b/src/networkd/links.h +@@ -37,5 +37,6 @@ void nw_links_drop_link(struct nw_links* links, struct nw_link* link); + int nw_links_enumerate(struct nw_links* links); + + struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex); ++struct nw_link* nw_links_get_by_name(struct nw_links* links, const char* name); + + #endif /* NETWORKD_LINKS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index e59e760..33e75d7 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -27,11 +27,13 @@ + + #include "address.h" + #include "config.h" ++#include "link.h" + #include "logging.h" + #include "string.h" + #include "port.h" + + struct nw_port { ++ struct nw_daemon* daemon; + int nrefs; + + char name[IF_NAMESIZE]; +@@ -66,6 +68,8 @@ static nw_port_type_t nw_port_type_from_string(const char* s) { + static void nw_port_free(struct nw_port* port) { + if (port->config) + nw_config_unref(port->config); ++ if (port->daemon) ++ nw_daemon_unref(port->daemon); + + free(port); + } +@@ -163,7 +167,7 @@ static int nw_port_setup(struct nw_port* port) { + return 0; + } + +-int nw_port_create(struct nw_port** port, const char* name) { ++int nw_port_create(struct nw_port** port, struct nw_daemon* daemon, const char* name) { + int r; + + // Allocate a new object +@@ -171,6 +175,9 @@ int nw_port_create(struct nw_port** port, const char* name) { + if (!p) + return 1; + ++ // Store a reference to the daemon ++ p->daemon = nw_daemon_ref(daemon); ++ + // Initialize reference counter + p->nrefs = 1; + +@@ -222,6 +229,10 @@ char* nw_port_bus_path(struct nw_port* port) { + return p; + } + ++static struct nw_link* nw_port_get_link(struct nw_port* port) { ++ return nw_daemon_get_link_by_name(port->daemon, port->name); ++} ++ + const nw_address_t* nw_port_get_address(struct nw_port* port) { + return &port->address; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index caf1433..92d60b2 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -31,8 +31,9 @@ typedef enum nw_port_type { + struct nw_port; + + #include "address.h" ++#include "daemon.h" + +-int nw_port_create(struct nw_port** port, const char* name); ++int nw_port_create(struct nw_port** port, struct nw_daemon* daemon, const char* name); + + struct nw_port* nw_port_ref(struct nw_port* port); + struct nw_port* nw_port_unref(struct nw_port* port); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 24bd257..9cec111 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -138,7 +138,7 @@ static int __nw_ports_enumerate(const char* path, const struct stat* s, void* da + return 0; + + // Create a new port +- r = nw_port_create(&port, name); ++ r = nw_port_create(&port, ports->daemon, name); + if (r) + goto ERROR; + +-- +2.39.2 + diff --git a/network/patches/0205-networkd-Use-typedef-to-keep-type-names-shorter.patch b/network/patches/0205-networkd-Use-typedef-to-keep-type-names-shorter.patch new file mode 100644 index 000000000..c8f82a9e4 --- /dev/null +++ b/network/patches/0205-networkd-Use-typedef-to-keep-type-names-shorter.patch @@ -0,0 +1,1617 @@ +From 2361667ee3e575e7c1b3044936a7b466283d7996 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 17:44:42 +0000 +Subject: [PATCH 205/304] networkd: Use typedef to keep type names shorter + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 4 +-- + src/networkd/bus.h | 10 +++---- + src/networkd/config.c | 36 +++++++++++------------ + src/networkd/config.h | 26 ++++++++--------- + src/networkd/daemon-bus.c | 4 +-- + src/networkd/daemon-bus.h | 2 +- + src/networkd/daemon.c | 60 +++++++++++++++++++-------------------- + src/networkd/daemon.h | 34 ++++++++++++---------- + src/networkd/link.c | 26 ++++++++--------- + src/networkd/link.h | 12 ++++---- + src/networkd/links.c | 26 ++++++++--------- + src/networkd/links.h | 18 ++++++------ + src/networkd/main.c | 2 +- + src/networkd/port-bus.c | 12 ++++---- + src/networkd/port-bus.h | 2 +- + src/networkd/port.c | 30 ++++++++++---------- + src/networkd/port.h | 14 ++++----- + src/networkd/ports.c | 26 ++++++++--------- + src/networkd/ports.h | 14 ++++----- + src/networkd/zone-bus.c | 14 ++++----- + src/networkd/zone-bus.h | 2 +- + src/networkd/zone.c | 24 ++++++++-------- + src/networkd/zone.h | 16 +++++------ + src/networkd/zones.c | 26 ++++++++--------- + src/networkd/zones.h | 14 ++++----- + 25 files changed, 229 insertions(+), 225 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 258aacd..1daa035 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -29,14 +29,14 @@ + #include "logging.h" + + static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) { +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + DEBUG("Connected to D-Bus\n"); + + return 0; + } + +-int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon) { ++int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon) { + int r; + + // Create a bus object +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 42ab2d3..05b4c63 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -30,27 +30,27 @@ + + #include "daemon.h" + +-int nw_bus_connect(sd_bus* bus, sd_event* loop, struct nw_daemon* daemon); ++int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon); + + struct nw_bus_vtable_pair { + const sd_bus_vtable* vtable; + sd_bus_object_find_t object_find; + }; + +-struct nw_bus_implementation { ++typedef struct nw_bus_implementation { + const char* path; + const char* interface; + const sd_bus_vtable** vtables; + const struct nw_bus_vtable_pair* fallback_vtables; + sd_bus_node_enumerator_t node_enumerator; + const struct nw_bus_implementation** children; +-}; ++} nw_bus_implementation; + + #define BUS_FALLBACK_VTABLES(...) ((const struct nw_bus_vtable_pair[]) { __VA_ARGS__, {} }) +-#define BUS_IMPLEMENTATIONS(...) ((const struct nw_bus_implementation* []) { __VA_ARGS__, NULL }) ++#define BUS_IMPLEMENTATIONS(...) ((const nw_bus_implementation* []) { __VA_ARGS__, NULL }) + #define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL }) + + int nw_bus_register_implementation(sd_bus* bus, +- const struct nw_bus_implementation* impl, void* data); ++ const nw_bus_implementation* impl, void* data); + + #endif /* NETWORKD_BUS_H */ +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 17d6d89..b3d5284 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -50,7 +50,7 @@ static void nw_config_entry_free(struct nw_config_entry* entry) { + } + + static struct nw_config_entry* nw_config_entry_create( +- struct nw_config* config, const char* key) { ++ nw_config* config, const char* key) { + int r; + + // Check input value +@@ -79,17 +79,17 @@ ERROR: + return NULL; + } + +-static void nw_config_free(struct nw_config* config) { ++static void nw_config_free(nw_config* config) { + // Flush all entries + nw_config_flush(config); + + free(config); + } + +-int nw_config_create(struct nw_config** config, const char* path) { ++int nw_config_create(nw_config** config, const char* path) { + int r; + +- struct nw_config* c = calloc(1, sizeof(*c)); ++ nw_config* c = calloc(1, sizeof(*c)); + if (!c) + return 1; + +@@ -121,13 +121,13 @@ ERROR: + return r; + } + +-struct nw_config* nw_config_ref(struct nw_config* config) { ++nw_config* nw_config_ref(nw_config* config) { + config->nrefs++; + + return config; + } + +-struct nw_config* nw_config_unref(struct nw_config* config) { ++nw_config* nw_config_unref(nw_config* config) { + if (--config->nrefs > 0) + return config; + +@@ -135,14 +135,14 @@ struct nw_config* nw_config_unref(struct nw_config* config) { + return NULL; + } + +-const char* nw_config_path(struct nw_config* config) { ++const char* nw_config_path(nw_config* config) { + if (*config->path) + return config->path; + + return NULL; + } + +-int nw_config_flush(struct nw_config* config) { ++int nw_config_flush(nw_config* config) { + struct nw_config_entry* entry = NULL; + + while (!STAILQ_EMPTY(&config->entries)) { +@@ -156,7 +156,7 @@ int nw_config_flush(struct nw_config* config) { + return 0; + } + +-static int nw_config_readf(struct nw_config* config, FILE* f) { ++static int nw_config_readf(nw_config* config, FILE* f) { + char* line = NULL; + size_t length = 0; + int r; +@@ -202,7 +202,7 @@ static int nw_config_readf(struct nw_config* config, FILE* f) { + return r; + } + +-int nw_config_read(struct nw_config* config) { ++int nw_config_read(nw_config* config) { + FILE* f = NULL; + int r; + +@@ -234,7 +234,7 @@ ERROR: + return r; + } + +-static int nw_config_writef(struct nw_config* config, FILE* f) { ++static int nw_config_writef(nw_config* config, FILE* f) { + struct nw_config_entry* entry = NULL; + int r; + +@@ -254,7 +254,7 @@ static int nw_config_writef(struct nw_config* config, FILE* f) { + return 0; + } + +-int nw_config_write(struct nw_config* config) { ++int nw_config_write(nw_config* config) { + int r; + + // We cannot write if path is not set +@@ -280,7 +280,7 @@ ERROR: + return r; + } + +-static struct nw_config_entry* nw_config_find(struct nw_config* config, const char* key) { ++static struct nw_config_entry* nw_config_find(nw_config* config, const char* key) { + struct nw_config_entry* entry = NULL; + + STAILQ_FOREACH(entry, &config->entries, nodes) { +@@ -296,7 +296,7 @@ static struct nw_config_entry* nw_config_find(struct nw_config* config, const ch + return NULL; + } + +-int nw_config_del(struct nw_config* config, const char* key) { ++int nw_config_del(nw_config* config, const char* key) { + struct nw_config_entry* entry = NULL; + + // Find an entry matching the key +@@ -315,7 +315,7 @@ int nw_config_del(struct nw_config* config, const char* key) { + return 0; + } + +-const char* nw_config_get(struct nw_config* config, const char* key) { ++const char* nw_config_get(nw_config* config, const char* key) { + struct nw_config_entry* entry = nw_config_find(config, key); + + // Return the value if found and set +@@ -326,7 +326,7 @@ const char* nw_config_get(struct nw_config* config, const char* key) { + return NULL; + } + +-int nw_config_set(struct nw_config* config, const char* key, const char* value) { ++int nw_config_set(nw_config* config, const char* key, const char* value) { + struct nw_config_entry* entry = NULL; + + // Delete the entry if val is NULL +@@ -347,7 +347,7 @@ int nw_config_set(struct nw_config* config, const char* key, const char* value) + return nw_string_set(entry->value, value); + } + +-int nw_config_get_int(struct nw_config* config, const char* key, const int __default) { ++int nw_config_get_int(nw_config* config, const char* key, const int __default) { + const char* value = nw_config_get(config, key); + + // Return zero if not set +@@ -357,7 +357,7 @@ int nw_config_get_int(struct nw_config* config, const char* key, const int __def + return strtoul(value, NULL, 10); + } + +-int nw_config_set_int(struct nw_config* config, const char* key, const int value) { ++int nw_config_set_int(nw_config* config, const char* key, const int value) { + char __value[1024]; + int r; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index b8d8555..041a10e 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -26,26 +26,26 @@ + #define NETWORK_CONFIG_KEY_MAX_LENGTH 128 + #define NETWORK_CONFIG_VALUE_MAX_LENGTH 2048 + +-struct nw_config; ++typedef struct nw_config nw_config; + +-int nw_config_create(struct nw_config** config, const char* path); ++int nw_config_create(nw_config** config, const char* path); + +-struct nw_config* nw_config_ref(struct nw_config* config); +-struct nw_config* nw_config_unref(struct nw_config* config); ++nw_config* nw_config_ref(nw_config* config); ++nw_config* nw_config_unref(nw_config* config); + +-const char* nw_config_path(struct nw_config* config); ++const char* nw_config_path(nw_config* config); + +-int nw_config_flush(struct nw_config* config); ++int nw_config_flush(nw_config* config); + +-int nw_config_read(struct nw_config* config); +-int nw_config_write(struct nw_config* config); ++int nw_config_read(nw_config* config); ++int nw_config_write(nw_config* config); + +-int nw_config_del(struct nw_config* config, const char* key); ++int nw_config_del(nw_config* config, const char* key); + +-const char* nw_config_get(struct nw_config* config, const char* key); +-int nw_config_set(struct nw_config* config, const char* key, const char* value); ++const char* nw_config_get(nw_config* config, const char* key); ++int nw_config_set(nw_config* config, const char* key, const char* value); + +-int nw_config_get_int(struct nw_config* config, const char* key, const int __default); +-int nw_config_set_int(struct nw_config* config, const char* key, const int value); ++int nw_config_get_int(nw_config* config, const char* key, const int __default); ++int nw_config_set_int(nw_config* config, const char* key, const int value); + + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +index ca0754f..93a0411 100644 +--- a/src/networkd/daemon-bus.c ++++ b/src/networkd/daemon-bus.c +@@ -26,7 +26,7 @@ + #include "zone-bus.h" + + static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* error) { +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Reload the daemon + nw_daemon_reload(daemon); +@@ -42,7 +42,7 @@ static const sd_bus_vtable daemon_vtable[] = { + SD_BUS_VTABLE_END, + }; + +-const struct nw_bus_implementation daemon_bus_impl = { ++const nw_bus_implementation daemon_bus_impl = { + .path = "/org/ipfire/network1", + .interface = "org.ipfire.network1", + .vtables = BUS_VTABLES(daemon_vtable), +diff --git a/src/networkd/daemon-bus.h b/src/networkd/daemon-bus.h +index 787e92a..c314963 100644 +--- a/src/networkd/daemon-bus.h ++++ b/src/networkd/daemon-bus.h +@@ -23,6 +23,6 @@ + + #include "bus.h" + +-extern const struct nw_bus_implementation daemon_bus_impl; ++extern const nw_bus_implementation daemon_bus_impl; + + #endif /* NETWORKD_DAEMON_BUS_H */ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index c4acff5..9b9bf73 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -44,7 +44,7 @@ + struct nw_daemon { + int nrefs; + +- struct nw_config* config; ++ nw_config* config; + + // Event Loop + sd_event* loop; +@@ -59,13 +59,13 @@ struct nw_daemon { + sd_device_monitor* devmon; + + // Links +- struct nw_links* links; ++ nw_links* links; + + // Zones +- struct nw_zones* zones; ++ nw_zones* zones; + + // Ports +- struct nw_ports* ports; ++ nw_ports* ports; + + }; + +@@ -78,7 +78,7 @@ static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_ + + static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_siginfo* si, + void* data) { +- struct nw_daemon* daemon = (struct nw_daemon*)daemon; ++ nw_daemon* daemon = (nw_daemon*)daemon; + + DEBUG("Received signal to reload...\n"); + +@@ -88,7 +88,7 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig + return 0; + } + +-static int nw_daemon_setup_loop(struct nw_daemon* daemon) { ++static int nw_daemon_setup_loop(nw_daemon* daemon) { + int r; + + // Fetch a reference to the default event loop +@@ -132,7 +132,7 @@ static int nw_daemon_setup_loop(struct nw_daemon* daemon) { + return 0; + } + +-static int nw_daemon_load_config(struct nw_daemon* daemon) { ++static int nw_daemon_load_config(nw_daemon* daemon) { + int r; + + // Read configuration file +@@ -148,7 +148,7 @@ static int nw_daemon_load_config(struct nw_daemon* daemon) { + return r; + } + +-static int nw_start_device_monitor(struct nw_daemon* daemon) { ++static int nw_start_device_monitor(nw_daemon* daemon) { + int r; + + const char* subsystems[] = { +@@ -199,7 +199,7 @@ static int nw_start_device_monitor(struct nw_daemon* daemon) { + return 0; + } + +-static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { ++static int nw_daemon_connect_rtnl(nw_daemon* daemon, int fd) { + int r; + + // Connect to Netlink +@@ -242,7 +242,7 @@ static int nw_daemon_connect_rtnl(struct nw_daemon* daemon, int fd) { + return 0; + } + +-static int nw_daemon_enumerate_links(struct nw_daemon* daemon) { ++static int nw_daemon_enumerate_links(nw_daemon* daemon) { + int r; + + // Create a new links container +@@ -253,7 +253,7 @@ static int nw_daemon_enumerate_links(struct nw_daemon* daemon) { + return nw_links_enumerate(daemon->links); + } + +-static int nw_daemon_enumerate_ports(struct nw_daemon* daemon) { ++static int nw_daemon_enumerate_ports(nw_daemon* daemon) { + int r; + + // Create a new ports container +@@ -264,7 +264,7 @@ static int nw_daemon_enumerate_ports(struct nw_daemon* daemon) { + return nw_ports_enumerate(daemon->ports); + } + +-static int nw_daemon_enumerate(struct nw_daemon* daemon) { ++static int nw_daemon_enumerate(nw_daemon* daemon) { + int r; + + // Links +@@ -280,7 +280,7 @@ static int nw_daemon_enumerate(struct nw_daemon* daemon) { + return 0; + } + +-static int nw_daemon_setup(struct nw_daemon* daemon) { ++static int nw_daemon_setup(nw_daemon* daemon) { + int r; + + // Read the configuration +@@ -316,10 +316,10 @@ static int nw_daemon_setup(struct nw_daemon* daemon) { + return 0; + } + +-int nw_daemon_create(struct nw_daemon** daemon) { ++int nw_daemon_create(nw_daemon** daemon) { + int r; + +- struct nw_daemon* d = calloc(1, sizeof(*d)); ++ nw_daemon* d = calloc(1, sizeof(*d)); + if (!d) + return 1; + +@@ -342,7 +342,7 @@ ERROR: + return r; + } + +-static void nw_daemon_cleanup(struct nw_daemon* daemon) { ++static void nw_daemon_cleanup(nw_daemon* daemon) { + if (daemon->ports) + nw_ports_unref(daemon->ports); + if (daemon->zones) +@@ -353,7 +353,7 @@ static void nw_daemon_cleanup(struct nw_daemon* daemon) { + nw_config_unref(daemon->config); + } + +-static void nw_daemon_free(struct nw_daemon* daemon) { ++static void nw_daemon_free(nw_daemon* daemon) { + // Cleanup common objects + nw_daemon_cleanup(daemon); + +@@ -365,13 +365,13 @@ static void nw_daemon_free(struct nw_daemon* daemon) { + free(daemon); + } + +-struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon) { ++nw_daemon* nw_daemon_ref(nw_daemon* daemon) { + daemon->nrefs++; + + return daemon; + } + +-struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon) { ++nw_daemon* nw_daemon_unref(nw_daemon* daemon) { + if (--daemon->nrefs > 0) + return daemon; + +@@ -382,7 +382,7 @@ struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon) { + /* + This function contains the main loop of the daemon... + */ +-int nw_daemon_run(struct nw_daemon* daemon) { ++int nw_daemon_run(nw_daemon* daemon) { + int r; + + // We are now ready to process any requests +@@ -412,7 +412,7 @@ ERROR: + return 1; + } + +-int nw_daemon_reload(struct nw_daemon* daemon) { ++int nw_daemon_reload(nw_daemon* daemon) { + DEBUG("Reloading daemon...\n"); + + // XXX TODO +@@ -423,32 +423,32 @@ int nw_daemon_reload(struct nw_daemon* daemon) { + /* + Netlink + */ +-sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon) { ++sd_netlink* nw_daemon_get_rtnl(nw_daemon* daemon) { + return daemon->rtnl; + } + + /* + Links + */ +-struct nw_links* nw_daemon_links(struct nw_daemon* daemon) { ++nw_links* nw_daemon_links(nw_daemon* daemon) { + return nw_links_ref(daemon->links); + } + +-void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link) { ++void nw_daemon_drop_link(nw_daemon* daemon, nw_link* link) { + if (!daemon->links) + return; + + nw_links_drop_link(daemon->links, link); + } + +-struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex) { ++nw_link* nw_daemon_get_link_by_ifindex(nw_daemon* daemon, int ifindex) { + if (!daemon->links) + return NULL; + + return nw_links_get_by_ifindex(daemon->links, ifindex); + } + +-struct nw_link* nw_daemon_get_link_by_name(struct nw_daemon* daemon, const char* name) { ++nw_link* nw_daemon_get_link_by_name(nw_daemon* daemon, const char* name) { + if (!daemon->links) + return NULL; + +@@ -458,11 +458,11 @@ struct nw_link* nw_daemon_get_link_by_name(struct nw_daemon* daemon, const char* + /* + Ports + */ +-struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon) { ++nw_ports* nw_daemon_ports(nw_daemon* daemon) { + return nw_ports_ref(daemon->ports); + } + +-struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name) { ++nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name) { + if (!daemon->ports) + return NULL; + +@@ -473,11 +473,11 @@ struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* + Zones + */ + +-struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon) { ++nw_zones* nw_daemon_zones(nw_daemon* daemon) { + return nw_zones_ref(daemon->zones); + } + +-struct nw_zone* nw_daemon_get_zone_by_name(struct nw_daemon* daemon, const char* name) { ++nw_zone* nw_daemon_get_zone_by_name(nw_daemon* daemon, const char* name) { + if (!daemon->zones) + return NULL; + +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index a40dd60..1694599 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -23,43 +23,47 @@ + + #include + +-struct nw_daemon; ++typedef struct nw_daemon nw_daemon; + + #include "link.h" ++#include "links.h" ++#include "port.h" ++#include "ports.h" + #include "zone.h" ++#include "zones.h" + +-int nw_daemon_create(struct nw_daemon** daemon); ++int nw_daemon_create(nw_daemon** daemon); + +-struct nw_daemon* nw_daemon_ref(struct nw_daemon* daemon); +-struct nw_daemon* nw_daemon_unref(struct nw_daemon* daemon); ++nw_daemon* nw_daemon_ref(nw_daemon* daemon); ++nw_daemon* nw_daemon_unref(nw_daemon* daemon); + +-int nw_daemon_run(struct nw_daemon* daemon); ++int nw_daemon_run(nw_daemon* daemon); + +-int nw_daemon_reload(struct nw_daemon* daemon); ++int nw_daemon_reload(nw_daemon* daemon); + + /* + Netlink + */ +-sd_netlink* nw_daemon_get_rtnl(struct nw_daemon* daemon); ++sd_netlink* nw_daemon_get_rtnl(nw_daemon* daemon); + + /* + Links + */ +-struct nw_links* nw_daemon_links(struct nw_daemon* daemon); +-void nw_daemon_drop_link(struct nw_daemon* daemon, struct nw_link* link); +-struct nw_link* nw_daemon_get_link_by_ifindex(struct nw_daemon* daemon, int ifindex); +-struct nw_link* nw_daemon_get_link_by_name(struct nw_daemon* daemon, const char* name); ++nw_links* nw_daemon_links(nw_daemon* daemon); ++void nw_daemon_drop_link(nw_daemon* daemon, nw_link* link); ++nw_link* nw_daemon_get_link_by_ifindex(nw_daemon* daemon, int ifindex); ++nw_link* nw_daemon_get_link_by_name(nw_daemon* daemon, const char* name); + + /* + Ports + */ +-struct nw_ports* nw_daemon_ports(struct nw_daemon* daemon); +-struct nw_port* nw_daemon_get_port_by_name(struct nw_daemon* daemon, const char* name); ++nw_ports* nw_daemon_ports(nw_daemon* daemon); ++nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name); + + /* + Zones + */ +-struct nw_zones* nw_daemon_zones(struct nw_daemon* daemon); +-struct nw_zone* nw_daemon_get_zone_by_name(struct nw_daemon* daemon, const char* name); ++nw_zones* nw_daemon_zones(nw_daemon* daemon); ++nw_zone* nw_daemon_get_zone_by_name(nw_daemon* daemon, const char* name); + + #endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 62be893..2f95dc3 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -32,7 +32,7 @@ + #include "string.h" + + struct nw_link { +- struct nw_daemon* daemon; ++ nw_daemon* daemon; + int nrefs; + + // Interface Index +@@ -47,9 +47,9 @@ struct nw_link { + uint32_t max_mtu; + }; + +-int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) { ++int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex) { + // Allocate a new object +- struct nw_link* l = calloc(1, sizeof(*l)); ++ nw_link* l = calloc(1, sizeof(*l)); + if (!l) + return 1; + +@@ -69,20 +69,20 @@ int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex) + return 0; + } + +-static void nw_link_free(struct nw_link* link) { ++static void nw_link_free(nw_link* link) { + DEBUG("Freeing link (ifindex = %d)\n", link->ifindex); + + if (link->daemon) + nw_daemon_unref(link->daemon); + } + +-struct nw_link* nw_link_ref(struct nw_link* link) { ++nw_link* nw_link_ref(nw_link* link) { + link->nrefs++; + + return link; + } + +-struct nw_link* nw_link_unref(struct nw_link* link) { ++nw_link* nw_link_unref(nw_link* link) { + if (--link->nrefs > 0) + return link; + +@@ -90,11 +90,11 @@ struct nw_link* nw_link_unref(struct nw_link* link) { + return NULL; + } + +-int nw_link_ifindex(struct nw_link* link) { ++int nw_link_ifindex(nw_link* link) { + return link->ifindex; + } + +-static int nw_link_update_ifname(struct nw_link* link, sd_netlink_message* message) { ++static int nw_link_update_ifname(nw_link* link, sd_netlink_message* message) { + const char* ifname = NULL; + int r; + +@@ -120,7 +120,7 @@ static int nw_link_update_ifname(struct nw_link* link, sd_netlink_message* messa + return 0; + } + +-static int nw_link_update_mtu(struct nw_link* link, sd_netlink_message* message) { ++static int nw_link_update_mtu(nw_link* link, sd_netlink_message* message) { + uint32_t mtu = 0; + uint32_t min_mtu = 0; + uint32_t max_mtu = 0; +@@ -172,7 +172,7 @@ static int nw_link_update_mtu(struct nw_link* link, sd_netlink_message* message) + This function is called whenever anything changes, so that we can + update our internal link object. + */ +-static int nw_link_update(struct nw_link* link, sd_netlink_message* message) { ++static int nw_link_update(nw_link* link, sd_netlink_message* message) { + int r; + + // Update the interface name +@@ -189,14 +189,14 @@ static int nw_link_update(struct nw_link* link, sd_netlink_message* message) { + } + + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { +- struct nw_links* links = NULL; +- struct nw_link* link = NULL; ++ nw_links* links = NULL; ++ nw_link* link = NULL; + const char* ifname = NULL; + int ifindex; + uint16_t type; + int r; + +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Fetch links + links = nw_daemon_links(daemon); +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 72ddfa9..acb5e7b 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -21,17 +21,17 @@ + #ifndef NETWORKD_LINK_H + #define NETWORKD_LINK_H + +-struct nw_link; ++typedef struct nw_link nw_link; + + #include "daemon.h" + +-int nw_link_create(struct nw_link** link, struct nw_daemon* daemon, int ifindex); ++int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex); + +-struct nw_link* nw_link_ref(struct nw_link* link); +-struct nw_link* nw_link_unref(struct nw_link* link); ++nw_link* nw_link_ref(nw_link* link); ++nw_link* nw_link_unref(nw_link* link); + +-int nw_link_ifindex(struct nw_link* link); +-const char* nw_link_name(struct nw_link* link); ++int nw_link_ifindex(nw_link* link); ++const char* nw_link_name(nw_link* link); + + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + +diff --git a/src/networkd/links.c b/src/networkd/links.c +index 7aa83a3..9f41034 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -29,14 +29,14 @@ + #include "links.h" + + struct nw_links_entry { +- struct nw_link* link; ++ nw_link* link; + + // Link to the other entries + STAILQ_ENTRY(nw_links_entry) nodes; + }; + + struct nw_links { +- struct nw_daemon* daemon; ++ nw_daemon* daemon; + int nrefs; + + // Link Entries +@@ -46,8 +46,8 @@ struct nw_links { + unsigned int num; + }; + +-int nw_links_create(struct nw_links** links, struct nw_daemon* daemon) { +- struct nw_links* l = calloc(1, sizeof(*l)); ++int nw_links_create(nw_links** links, nw_daemon* daemon) { ++ nw_links* l = calloc(1, sizeof(*l)); + if (!l) + return 1; + +@@ -66,7 +66,7 @@ int nw_links_create(struct nw_links** links, struct nw_daemon* daemon) { + return 0; + } + +-static void nw_links_free(struct nw_links* links) { ++static void nw_links_free(nw_links* links) { + struct nw_links_entry* entry = NULL; + + while (!STAILQ_EMPTY(&links->entries)) { +@@ -86,13 +86,13 @@ static void nw_links_free(struct nw_links* links) { + nw_daemon_unref(links->daemon); + } + +-struct nw_links* nw_links_ref(struct nw_links* links) { ++nw_links* nw_links_ref(nw_links* links) { + links->nrefs++; + + return links; + } + +-struct nw_links* nw_links_unref(struct nw_links* links) { ++nw_links* nw_links_unref(nw_links* links) { + if (--links->nrefs > 0) + return links; + +@@ -100,7 +100,7 @@ struct nw_links* nw_links_unref(struct nw_links* links) { + return NULL; + } + +-static struct nw_links_entry* nw_links_find_link(struct nw_links* links, const int ifindex) { ++static struct nw_links_entry* nw_links_find_link(nw_links* links, const int ifindex) { + struct nw_links_entry* entry = NULL; + + STAILQ_FOREACH(entry, &links->entries, nodes) { +@@ -112,7 +112,7 @@ static struct nw_links_entry* nw_links_find_link(struct nw_links* links, const i + return NULL; + } + +-int nw_links_add_link(struct nw_links* links, struct nw_link* link) { ++int nw_links_add_link(nw_links* links, struct nw_link* link) { + // Allocate a new entry + struct nw_links_entry* entry = calloc(1, sizeof(*entry)); + if (!entry) +@@ -130,7 +130,7 @@ int nw_links_add_link(struct nw_links* links, struct nw_link* link) { + return 0; + } + +-void nw_links_drop_link(struct nw_links* links, struct nw_link* link) { ++void nw_links_drop_link(nw_links* links, struct nw_link* link) { + struct nw_links_entry* entry = NULL; + + entry = nw_links_find_link(links, nw_link_ifindex(link)); +@@ -143,7 +143,7 @@ void nw_links_drop_link(struct nw_links* links, struct nw_link* link) { + links->num--; + } + +-int nw_links_enumerate(struct nw_links* links) { ++int nw_links_enumerate(nw_links* links) { + sd_netlink_message* req = NULL; + sd_netlink_message* res = NULL; + int r; +@@ -184,7 +184,7 @@ ERROR: + return r; + } + +-struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex) { ++nw_link* nw_links_get_by_ifindex(nw_links* links, int ifindex) { + struct nw_links_entry* entry = NULL; + + entry = nw_links_find_link(links, ifindex); +@@ -194,7 +194,7 @@ struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex) { + return nw_link_ref(entry->link); + } + +-struct nw_link* nw_links_get_by_name(struct nw_links* links, const char* name) { ++nw_link* nw_links_get_by_name(nw_links* links, const char* name) { + struct nw_links_entry* entry = NULL; + + STAILQ_FOREACH(entry, &links->entries, nodes) { +diff --git a/src/networkd/links.h b/src/networkd/links.h +index 2b5c787..21e6cfb 100644 +--- a/src/networkd/links.h ++++ b/src/networkd/links.h +@@ -24,19 +24,19 @@ + #include "daemon.h" + #include "link.h" + +-struct nw_links; ++typedef struct nw_links nw_links; + +-int nw_links_create(struct nw_links** links, struct nw_daemon* daemon); ++int nw_links_create(nw_links** links, nw_daemon* daemon); + +-struct nw_links* nw_links_ref(struct nw_links* links); +-struct nw_links* nw_links_unref(struct nw_links* links); ++nw_links* nw_links_ref(nw_links* links); ++nw_links* nw_links_unref(nw_links* links); + +-int nw_links_add_link(struct nw_links* links, struct nw_link* link); +-void nw_links_drop_link(struct nw_links* links, struct nw_link* link); ++int nw_links_add_link(nw_links* links, nw_link* link); ++void nw_links_drop_link(nw_links* links, nw_link* link); + +-int nw_links_enumerate(struct nw_links* links); ++int nw_links_enumerate(nw_links* links); + +-struct nw_link* nw_links_get_by_ifindex(struct nw_links* links, int ifindex); +-struct nw_link* nw_links_get_by_name(struct nw_links* links, const char* name); ++nw_link* nw_links_get_by_ifindex(nw_links* links, int ifindex); ++nw_link* nw_links_get_by_name(nw_links* links, const char* name); + + #endif /* NETWORKD_LINKS_H */ +diff --git a/src/networkd/main.c b/src/networkd/main.c +index 9a0fd74..d3afc2a 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -212,7 +212,7 @@ static int drop_privileges(const char* user) { + } + + int main(int argc, char** argv) { +- struct nw_daemon* daemon = NULL; ++ nw_daemon* daemon = NULL; + int r; + + // Drop privileges +diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c +index 1a48655..996be92 100644 +--- a/src/networkd/port-bus.c ++++ b/src/networkd/port-bus.c +@@ -36,10 +36,10 @@ static int nw_port_node_enumerator(sd_bus* bus, const char* path, void* data, + DEBUG("Enumerating ports...\n"); + + // Fetch a reference to the daemon +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Fetch ports +- struct nw_ports* ports = nw_daemon_ports(daemon); ++ nw_ports* ports = nw_daemon_ports(daemon); + + // Make bus paths for all ports + r = nw_ports_bus_paths(ports, nodes); +@@ -58,7 +58,7 @@ static int nw_port_object_find(sd_bus* bus, const char* path, const char* interf + int r; + + // Fetch a reference to the daemon +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Decode the path of the requested object + r = sd_bus_path_decode(path, "/org/ipfire/network1/port", &name); +@@ -66,7 +66,7 @@ static int nw_port_object_find(sd_bus* bus, const char* path, const char* interf + return 0; + + // Find the port +- struct nw_port* port = nw_daemon_get_port_by_name(daemon, name); ++ nw_port* port = nw_daemon_get_port_by_name(daemon, name); + if (!port) + return 0; + +@@ -80,7 +80,7 @@ static int nw_port_object_find(sd_bus* bus, const char* path, const char* interf + + static int nw_port_bus_get_address(sd_bus* bus, const char* path, const char* interface, + const char* property, sd_bus_message* reply, void* data, sd_bus_error* error) { +- struct nw_port* port = (struct nw_port*)data; ++ nw_port* port = (nw_port*)data; + int r; + + // Fetch the address +@@ -115,7 +115,7 @@ static const sd_bus_vtable port_vtable[] = { + SD_BUS_VTABLE_END + }; + +-const struct nw_bus_implementation port_bus_impl = { ++const nw_bus_implementation port_bus_impl = { + "/org/ipfire/network1/port", + "org.ipfire.network1.Port", + .fallback_vtables = BUS_FALLBACK_VTABLES({port_vtable, nw_port_object_find}), +diff --git a/src/networkd/port-bus.h b/src/networkd/port-bus.h +index 95e49a8..373c281 100644 +--- a/src/networkd/port-bus.h ++++ b/src/networkd/port-bus.h +@@ -23,6 +23,6 @@ + + #include "bus.h" + +-extern const struct nw_bus_implementation port_bus_impl; ++extern const nw_bus_implementation port_bus_impl; + + #endif /* NETWORKD_PORT_BUS_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 33e75d7..41b8b24 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -33,14 +33,14 @@ + #include "port.h" + + struct nw_port { +- struct nw_daemon* daemon; ++ nw_daemon* daemon; + int nrefs; + + char name[IF_NAMESIZE]; + nw_port_type_t type; + + // Configuration +- struct nw_config *config; ++ nw_config *config; + + // Common attributes + nw_address_t address; +@@ -65,7 +65,7 @@ static nw_port_type_t nw_port_type_from_string(const char* s) { + return NW_PORT_UNKNOWN; + } + +-static void nw_port_free(struct nw_port* port) { ++static void nw_port_free(nw_port* port) { + if (port->config) + nw_config_unref(port->config); + if (port->daemon) +@@ -74,7 +74,7 @@ static void nw_port_free(struct nw_port* port) { + free(port); + } + +-static int nw_port_setup_address(struct nw_port* port) { ++static int nw_port_setup_address(nw_port* port) { + int r; + + // Read ADDRESS from configuration +@@ -111,7 +111,7 @@ ERROR: + return 0; + } + +-static int nw_port_setup_common(struct nw_port* port) { ++static int nw_port_setup_common(nw_port* port) { + int r; + + // Address +@@ -122,7 +122,7 @@ static int nw_port_setup_common(struct nw_port* port) { + return 0; + } + +-static nw_port_type_t nw_port_setup_type(struct nw_port* port) { ++static nw_port_type_t nw_port_setup_type(nw_port* port) { + const char* type = nw_config_get(port->config, "TYPE"); + if (!type) + return NW_PORT_UNKNOWN; +@@ -130,7 +130,7 @@ static nw_port_type_t nw_port_setup_type(struct nw_port* port) { + return nw_port_type_from_string(type); + } + +-static int nw_port_setup(struct nw_port* port) { ++static int nw_port_setup(nw_port* port) { + char path[PATH_MAX]; + int r; + +@@ -167,11 +167,11 @@ static int nw_port_setup(struct nw_port* port) { + return 0; + } + +-int nw_port_create(struct nw_port** port, struct nw_daemon* daemon, const char* name) { ++int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name) { + int r; + + // Allocate a new object +- struct nw_port* p = calloc(1, sizeof(*p)); ++ nw_port* p = calloc(1, sizeof(*p)); + if (!p) + return 1; + +@@ -199,13 +199,13 @@ ERROR: + return r; + } + +-struct nw_port* nw_port_ref(struct nw_port* port) { ++nw_port* nw_port_ref(nw_port* port) { + port->nrefs++; + + return port; + } + +-struct nw_port* nw_port_unref(struct nw_port* port) { ++nw_port* nw_port_unref(nw_port* port) { + if (--port->nrefs > 0) + return port; + +@@ -213,11 +213,11 @@ struct nw_port* nw_port_unref(struct nw_port* port) { + return NULL; + } + +-const char* nw_port_name(struct nw_port* port) { ++const char* nw_port_name(nw_port* port) { + return port->name; + } + +-char* nw_port_bus_path(struct nw_port* port) { ++char* nw_port_bus_path(nw_port* port) { + char* p = NULL; + int r; + +@@ -229,10 +229,10 @@ char* nw_port_bus_path(struct nw_port* port) { + return p; + } + +-static struct nw_link* nw_port_get_link(struct nw_port* port) { ++static nw_link* nw_port_get_link(nw_port* port) { + return nw_daemon_get_link_by_name(port->daemon, port->name); + } + +-const nw_address_t* nw_port_get_address(struct nw_port* port) { ++const nw_address_t* nw_port_get_address(nw_port* port) { + return &port->address; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 92d60b2..9881846 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -28,20 +28,20 @@ typedef enum nw_port_type { + NW_PORT_DUMMY, + } nw_port_type_t; + +-struct nw_port; ++typedef struct nw_port nw_port; + + #include "address.h" + #include "daemon.h" + +-int nw_port_create(struct nw_port** port, struct nw_daemon* daemon, const char* name); ++int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name); + +-struct nw_port* nw_port_ref(struct nw_port* port); +-struct nw_port* nw_port_unref(struct nw_port* port); ++nw_port* nw_port_ref(nw_port* port); ++nw_port* nw_port_unref(nw_port* port); + +-const char* nw_port_name(struct nw_port* port); ++const char* nw_port_name(nw_port* port); + +-char* nw_port_bus_path(struct nw_port* port); ++char* nw_port_bus_path(nw_port* port); + +-const nw_address_t* nw_port_get_address(struct nw_port* port); ++const nw_address_t* nw_port_get_address(nw_port* port); + + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 9cec111..35ed048 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -30,14 +30,14 @@ + #include "util.h" + + struct nw_ports_entry { +- struct nw_port* port; ++ nw_port* port; + + // Link to the other entries + STAILQ_ENTRY(nw_ports_entry) nodes; + }; + + struct nw_ports { +- struct nw_daemon* daemon; ++ nw_daemon* daemon; + int nrefs; + + // Port Entries +@@ -47,8 +47,8 @@ struct nw_ports { + unsigned int num; + }; + +-int nw_ports_create(struct nw_ports** ports, struct nw_daemon* daemon) { +- struct nw_ports* p = calloc(1, sizeof(*p)); ++int nw_ports_create(nw_ports** ports, nw_daemon* daemon) { ++ nw_ports* p = calloc(1, sizeof(*p)); + if (!p) + return 1; + +@@ -67,7 +67,7 @@ int nw_ports_create(struct nw_ports** ports, struct nw_daemon* daemon) { + return 0; + } + +-static void nw_ports_free(struct nw_ports* ports) { ++static void nw_ports_free(nw_ports* ports) { + struct nw_ports_entry* entry = NULL; + + while (!STAILQ_EMPTY(&ports->entries)) { +@@ -84,13 +84,13 @@ static void nw_ports_free(struct nw_ports* ports) { + } + } + +-struct nw_ports* nw_ports_ref(struct nw_ports* ports) { ++nw_ports* nw_ports_ref(nw_ports* ports) { + ports->nrefs++; + + return ports; + } + +-struct nw_ports* nw_ports_unref(struct nw_ports* ports) { ++nw_ports* nw_ports_unref(nw_ports* ports) { + if (--ports->nrefs > 0) + return ports; + +@@ -98,7 +98,7 @@ struct nw_ports* nw_ports_unref(struct nw_ports* ports) { + return NULL; + } + +-static int nw_ports_add_port(struct nw_ports* ports, struct nw_port* port) { ++static int nw_ports_add_port(nw_ports* ports, nw_port* port) { + // Allocate a new entry + struct nw_ports_entry* entry = calloc(1, sizeof(*entry)); + if (!entry) +@@ -117,10 +117,10 @@ static int nw_ports_add_port(struct nw_ports* ports, struct nw_port* port) { + } + + static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { +- struct nw_port* port = NULL; ++ nw_port* port = NULL; + int r; + +- struct nw_ports* ports = (struct nw_ports*)data; ++ nw_ports* ports = (nw_ports*)data; + + // Skip anything that isn't a regular file + if (!S_ISREG(s->st_mode)) +@@ -154,11 +154,11 @@ ERROR: + return r; + } + +-int nw_ports_enumerate(struct nw_ports* ports) { ++int nw_ports_enumerate(nw_ports* ports) { + return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); + } + +-struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name) { ++nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name) { + struct nw_ports_entry* entry = NULL; + + STAILQ_FOREACH(entry, &ports->entries, nodes) { +@@ -173,7 +173,7 @@ struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name) { + return NULL; + } + +-int nw_ports_bus_paths(struct nw_ports* ports, char*** paths) { ++int nw_ports_bus_paths(nw_ports* ports, char*** paths) { + struct nw_ports_entry* entry = NULL; + char* path = NULL; + +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +index e807e25..f58c3a4 100644 +--- a/src/networkd/ports.h ++++ b/src/networkd/ports.h +@@ -21,19 +21,19 @@ + #ifndef NETWORKD_PORTS_H + #define NETWORKD_PORTS_H + +-struct nw_ports; ++typedef struct nw_ports nw_ports; + + #include "daemon.h" + +-int nw_ports_create(struct nw_ports** ports, struct nw_daemon* daemon); ++int nw_ports_create(nw_ports** ports, nw_daemon* daemon); + +-struct nw_ports* nw_ports_ref(struct nw_ports* ports); +-struct nw_ports* nw_ports_unref(struct nw_ports* ports); ++nw_ports* nw_ports_ref(nw_ports* ports); ++nw_ports* nw_ports_unref(nw_ports* ports); + +-int nw_ports_enumerate(struct nw_ports* ports); ++int nw_ports_enumerate(nw_ports* ports); + +-struct nw_port* nw_ports_get_by_name(struct nw_ports* ports, const char* name); ++struct nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name); + +-int nw_ports_bus_paths(struct nw_ports* ports, char*** paths); ++int nw_ports_bus_paths(nw_ports* ports, char*** paths); + + #endif /* NETWORKD_PORTS_H */ +diff --git a/src/networkd/zone-bus.c b/src/networkd/zone-bus.c +index e9c2ecc..a06deb5 100644 +--- a/src/networkd/zone-bus.c ++++ b/src/networkd/zone-bus.c +@@ -34,10 +34,10 @@ static int nw_zone_node_enumerator(sd_bus* bus, const char* path, void* data, + DEBUG("Enumerating zones...\n"); + + // Fetch a reference to the daemon +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Fetch zones +- struct nw_zones* zones = nw_daemon_zones(daemon); ++ nw_zones* zones = nw_daemon_zones(daemon); + + // Make bus paths for all zones + r = nw_zones_bus_paths(zones, nodes); +@@ -56,7 +56,7 @@ static int nw_zone_object_find(sd_bus* bus, const char* path, const char* interf + int r; + + // Fetch a reference to the daemon +- struct nw_daemon* daemon = (struct nw_daemon*)data; ++ nw_daemon* daemon = (nw_daemon*)data; + + // Decode the path of the requested object + r = sd_bus_path_decode(path, "/org/ipfire/network1/zone", &name); +@@ -64,7 +64,7 @@ static int nw_zone_object_find(sd_bus* bus, const char* path, const char* interf + return 0; + + // Find the zone +- struct nw_zone* zone = nw_daemon_get_zone_by_name(daemon, name); ++ nw_zone* zone = nw_daemon_get_zone_by_name(daemon, name); + if (!zone) + return 0; + +@@ -81,7 +81,7 @@ static int nw_zone_object_find(sd_bus* bus, const char* path, const char* interf + */ + static int nw_zone_bus_get_mtu(sd_bus* bus, const char *path, const char *interface, + const char* property, sd_bus_message* reply, void* data, sd_bus_error *error) { +- struct nw_zone* zone = (struct nw_zone*)data; ++ nw_zone* zone = (nw_zone*)data; + + return sd_bus_message_append(reply, "u", nw_zone_mtu(zone)); + } +@@ -91,7 +91,7 @@ static int nw_zone_bus_set_mtu(sd_bus* bus, const char* path, const char* interf + unsigned int mtu = 0; + int r; + +- struct nw_zone* zone = (struct nw_zone*)data; ++ nw_zone* zone = (nw_zone*)data; + + // Parse the value + r = sd_bus_message_read(value, "u", &mtu); +@@ -114,7 +114,7 @@ static const sd_bus_vtable zone_vtable[] = { + SD_BUS_VTABLE_END + }; + +-const struct nw_bus_implementation zone_bus_impl = { ++const nw_bus_implementation zone_bus_impl = { + "/org/ipfire/network1/zone", + "org.ipfire.network1.Zone", + .fallback_vtables = BUS_FALLBACK_VTABLES({zone_vtable, nw_zone_object_find}), +diff --git a/src/networkd/zone-bus.h b/src/networkd/zone-bus.h +index 0d5583e..db257f7 100644 +--- a/src/networkd/zone-bus.h ++++ b/src/networkd/zone-bus.h +@@ -23,6 +23,6 @@ + + #include "bus.h" + +-extern const struct nw_bus_implementation zone_bus_impl; ++extern const nw_bus_implementation zone_bus_impl; + + #endif /* NETWORKD_ZONE_BUS_H */ +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index c64706f..b6fa65d 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -34,13 +34,13 @@ struct nw_zone { + char name[NETWORK_ZONE_NAME_MAX_LENGTH]; + + // Configuration +- struct nw_config *config; ++ nw_config *config; + }; + + #define nw_zone_path(zone, path, format, ...) \ + __nw_zone_path(zone, path, sizeof(path), format, __VA_ARGS__) + +-static int __nw_zone_path(struct nw_zone* zone, char* p, const size_t length, ++static int __nw_zone_path(nw_zone* zone, char* p, const size_t length, + const char* format, ...) { + char prefix[NAME_MAX]; + char suffix[NAME_MAX]; +@@ -63,14 +63,14 @@ static int __nw_zone_path(struct nw_zone* zone, char* p, const size_t length, + return __nw_path_join(p, length, prefix, suffix); + } + +-static void nw_zone_free(struct nw_zone* zone) { ++static void nw_zone_free(nw_zone* zone) { + if (zone->config) + nw_config_unref(zone->config); + + free(zone); + } + +-static int nw_zone_setup(struct nw_zone* zone) { ++static int nw_zone_setup(nw_zone* zone) { + char path[PATH_MAX]; + int r; + +@@ -87,11 +87,11 @@ static int nw_zone_setup(struct nw_zone* zone) { + return 0; + } + +-int nw_zone_create(struct nw_zone** zone, const char* name) { ++int nw_zone_create(nw_zone** zone, const char* name) { + int r; + + // Allocate a new object +- struct nw_zone* z = calloc(1, sizeof(*z)); ++ nw_zone* z = calloc(1, sizeof(*z)); + if (!z) + return 1; + +@@ -116,13 +116,13 @@ ERROR: + return r; + } + +-struct nw_zone* nw_zone_ref(struct nw_zone* zone) { ++nw_zone* nw_zone_ref(nw_zone* zone) { + zone->nrefs++; + + return zone; + } + +-struct nw_zone* nw_zone_unref(struct nw_zone* zone) { ++nw_zone* nw_zone_unref(nw_zone* zone) { + if (--zone->nrefs > 0) + return zone; + +@@ -130,11 +130,11 @@ struct nw_zone* nw_zone_unref(struct nw_zone* zone) { + return NULL; + } + +-const char* nw_zone_name(struct nw_zone* zone) { ++const char* nw_zone_name(nw_zone* zone) { + return zone->name; + } + +-char* nw_zone_bus_path(struct nw_zone* zone) { ++char* nw_zone_bus_path(nw_zone* zone) { + char* p = NULL; + int r; + +@@ -149,11 +149,11 @@ char* nw_zone_bus_path(struct nw_zone* zone) { + /* + MTU + */ +-unsigned int nw_zone_mtu(struct nw_zone* zone) { ++unsigned int nw_zone_mtu(nw_zone* zone) { + return nw_config_get_int(zone->config, "MTU", NETWORK_ZONE_DEFAULT_MTU); + } + +-int nw_zone_set_mtu(struct nw_zone* zone, unsigned int mtu) { ++int nw_zone_set_mtu(nw_zone* zone, unsigned int mtu) { + DEBUG("Change MTU of %s to %u\n", zone->name, mtu); + + return nw_config_set_int(zone->config, "MTU", mtu); +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 4a00412..1c8e6b6 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -24,21 +24,21 @@ + #define NETWORK_ZONE_NAME_MAX_LENGTH 16 + #define NETWORK_ZONE_DEFAULT_MTU 1500 + +-struct nw_zone; ++typedef struct nw_zone nw_zone; + +-int nw_zone_create(struct nw_zone** zone, const char* name); ++int nw_zone_create(nw_zone** zone, const char* name); + +-struct nw_zone* nw_zone_ref(struct nw_zone* zone); +-struct nw_zone* nw_zone_unref(struct nw_zone* zone); ++nw_zone* nw_zone_ref(nw_zone* zone); ++nw_zone* nw_zone_unref(nw_zone* zone); + +-const char* nw_zone_name(struct nw_zone* zone); ++const char* nw_zone_name(nw_zone* zone); + +-char* nw_zone_bus_path(struct nw_zone* zone); ++char* nw_zone_bus_path(nw_zone* zone); + + /* + MTU + */ +-unsigned int nw_zone_mtu(struct nw_zone* zone); +-int nw_zone_set_mtu(struct nw_zone* zone, unsigned int mtu); ++unsigned int nw_zone_mtu(nw_zone* zone); ++int nw_zone_set_mtu(nw_zone* zone, unsigned int mtu); + + #endif /* NETWORKD_ZONE_H */ +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 4f739f5..779bbe1 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -28,7 +28,7 @@ + #include "zones.h" + + struct nw_zones_entry { +- struct nw_zone* zone; ++ nw_zone* zone; + + // Link to the other entries + STAILQ_ENTRY(nw_zones_entry) nodes; +@@ -44,8 +44,8 @@ struct nw_zones { + unsigned int num; + }; + +-static int nw_zones_create(struct nw_zones** zones) { +- struct nw_zones* z = calloc(1, sizeof(*z)); ++static int nw_zones_create(nw_zones** zones) { ++ nw_zones* z = calloc(1, sizeof(*z)); + if (!z) + return 1; + +@@ -61,7 +61,7 @@ static int nw_zones_create(struct nw_zones** zones) { + return 0; + } + +-static void nw_zones_free(struct nw_zones* zones) { ++static void nw_zones_free(nw_zones* zones) { + struct nw_zones_entry* entry = NULL; + + while (!STAILQ_EMPTY(&zones->entries)) { +@@ -78,13 +78,13 @@ static void nw_zones_free(struct nw_zones* zones) { + } + } + +-struct nw_zones* nw_zones_ref(struct nw_zones* zones) { ++nw_zones* nw_zones_ref(nw_zones* zones) { + zones->nrefs++; + + return zones; + } + +-struct nw_zones* nw_zones_unref(struct nw_zones* zones) { ++nw_zones* nw_zones_unref(nw_zones* zones) { + if (--zones->nrefs > 0) + return zones; + +@@ -92,7 +92,7 @@ struct nw_zones* nw_zones_unref(struct nw_zones* zones) { + return NULL; + } + +-static int nw_zones_add_zone(struct nw_zones* zones, struct nw_zone* zone) { ++static int nw_zones_add_zone(nw_zones* zones, nw_zone* zone) { + // Allocate a new entry + struct nw_zones_entry* entry = calloc(1, sizeof(*entry)); + if (!entry) +@@ -124,12 +124,12 @@ static int nw_zones_load_filter(const struct dirent* path) { + return 1; + } + +-static int __nw_zones_load(struct nw_zones* zones) { ++static int __nw_zones_load(nw_zones* zones) { + struct dirent** paths = NULL; + int n; + int r = 0; + +- struct nw_zone* zone = NULL; ++ nw_zone* zone = NULL; + + // Scan the zones directory + n = scandir(CONFIG_DIR "/zones", &paths, nw_zones_load_filter, alphasort); +@@ -173,7 +173,7 @@ ERROR: + return r; + } + +-int nw_zones_load(struct nw_zones** zones) { ++int nw_zones_load(nw_zones** zones) { + int r; + + // Create a new zones object +@@ -193,7 +193,7 @@ ERROR: + return r; + } + +-size_t nw_zones_num(struct nw_zones* zones) { ++size_t nw_zones_num(nw_zones* zones) { + struct nw_zones_entry* entry = NULL; + size_t length = 0; + +@@ -204,7 +204,7 @@ size_t nw_zones_num(struct nw_zones* zones) { + return length; + } + +-struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) { ++nw_zone* nw_zones_get_by_name(nw_zones* zones, const char* name) { + struct nw_zones_entry* entry = NULL; + + STAILQ_FOREACH(entry, &zones->entries, nodes) { +@@ -219,7 +219,7 @@ struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name) { + return NULL; + } + +-int nw_zones_bus_paths(struct nw_zones* zones, char*** paths) { ++int nw_zones_bus_paths(nw_zones* zones, char*** paths) { + struct nw_zones_entry* entry = NULL; + char* path = NULL; + +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index 6e2686d..e41c74f 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -21,17 +21,17 @@ + #ifndef NETWORKD_ZONES_H + #define NETWORKD_ZONES_H + +-struct nw_zones; ++typedef struct nw_zones nw_zones; + +-struct nw_zones* nw_zones_ref(struct nw_zones* zones); +-struct nw_zones* nw_zones_unref(struct nw_zones* zones); ++nw_zones* nw_zones_ref(nw_zones* zones); ++nw_zones* nw_zones_unref(nw_zones* zones); + +-int nw_zones_load(struct nw_zones** zones); ++int nw_zones_load(nw_zones** zones); + +-size_t nw_zones_num(struct nw_zones* zones); ++size_t nw_zones_num(nw_zones* zones); + +-struct nw_zone* nw_zones_get_by_name(struct nw_zones* zones, const char* name); ++nw_zone* nw_zones_get_by_name(nw_zones* zones, const char* name); + +-int nw_zones_bus_paths(struct nw_zones* zones, char*** paths); ++int nw_zones_bus_paths(nw_zones* zones, char*** paths); + + #endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0206-networkd-Store-a-reference-to-the-daemon-in-zone.patch b/network/patches/0206-networkd-Store-a-reference-to-the-daemon-in-zone.patch new file mode 100644 index 000000000..44827567e --- /dev/null +++ b/network/patches/0206-networkd-Store-a-reference-to-the-daemon-in-zone.patch @@ -0,0 +1,180 @@ +From dd84704eadbf2f55f650b5879095bafad7ffec30 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 17:51:28 +0000 +Subject: [PATCH 206/304] networkd: Store a reference to the daemon in zone + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 2 +- + src/networkd/zone.c | 9 ++++++++- + src/networkd/zone.h | 4 +++- + src/networkd/zones.c | 18 ++++++++++++++---- + src/networkd/zones.h | 4 +++- + 5 files changed, 29 insertions(+), 8 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 9b9bf73..8122f58 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -141,7 +141,7 @@ static int nw_daemon_load_config(nw_daemon* daemon) { + return r; + + // Load zones +- r = nw_zones_load(&daemon->zones); ++ r = nw_zones_load(&daemon->zones, daemon); + if (r) + return r; + +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index b6fa65d..30f22d6 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -24,11 +24,13 @@ + #include + + #include "config.h" ++#include "daemon.h" + #include "logging.h" + #include "string.h" + #include "zone.h" + + struct nw_zone { ++ nw_daemon* daemon; + int nrefs; + + char name[NETWORK_ZONE_NAME_MAX_LENGTH]; +@@ -66,6 +68,8 @@ static int __nw_zone_path(nw_zone* zone, char* p, const size_t length, + static void nw_zone_free(nw_zone* zone) { + if (zone->config) + nw_config_unref(zone->config); ++ if (zone->daemon) ++ nw_daemon_unref(zone->daemon); + + free(zone); + } +@@ -87,7 +91,7 @@ static int nw_zone_setup(nw_zone* zone) { + return 0; + } + +-int nw_zone_create(nw_zone** zone, const char* name) { ++int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) { + int r; + + // Allocate a new object +@@ -95,6 +99,9 @@ int nw_zone_create(nw_zone** zone, const char* name) { + if (!z) + return 1; + ++ // Store a reference to the daemon ++ z->daemon = nw_daemon_ref(daemon); ++ + // Initialize reference counter + z->nrefs = 1; + +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 1c8e6b6..9df30ec 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -26,7 +26,9 @@ + + typedef struct nw_zone nw_zone; + +-int nw_zone_create(nw_zone** zone, const char* name); ++#include "daemon.h" ++ ++int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name); + + nw_zone* nw_zone_ref(nw_zone* zone); + nw_zone* nw_zone_unref(nw_zone* zone); +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 779bbe1..fd43f1c 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -23,6 +23,7 @@ + #include + #include + ++#include "daemon.h" + #include "logging.h" + #include "zone.h" + #include "zones.h" +@@ -35,6 +36,7 @@ struct nw_zones_entry { + }; + + struct nw_zones { ++ nw_daemon* daemon; + int nrefs; + + // Zone Entries +@@ -44,11 +46,14 @@ struct nw_zones { + unsigned int num; + }; + +-static int nw_zones_create(nw_zones** zones) { ++static int nw_zones_create(nw_zones** zones, nw_daemon* daemon) { + nw_zones* z = calloc(1, sizeof(*z)); + if (!z) + return 1; + ++ // Store a reference to the daemon ++ z->daemon = nw_daemon_ref(daemon); ++ + // Initialize the reference counter + z->nrefs = 1; + +@@ -76,6 +81,11 @@ static void nw_zones_free(nw_zones* zones) { + // Free the entry + free(entry); + } ++ ++ if (zones->daemon) ++ nw_daemon_unref(zones->daemon); ++ ++ free(zones); + } + + nw_zones* nw_zones_ref(nw_zones* zones) { +@@ -147,7 +157,7 @@ static int __nw_zones_load(nw_zones* zones) { + DEBUG("Loading zone '%s'...\n", name); + + // Create a new zone object +- r = nw_zone_create(&zone, name); ++ r = nw_zone_create(&zone, zones->daemon, name); + if (r) + goto ERROR; + +@@ -173,11 +183,11 @@ ERROR: + return r; + } + +-int nw_zones_load(nw_zones** zones) { ++int nw_zones_load(nw_zones** zones, nw_daemon* daemon) { + int r; + + // Create a new zones object +- r = nw_zones_create(zones); ++ r = nw_zones_create(zones, daemon); + if (r) + return r; + +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index e41c74f..330e524 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -23,10 +23,12 @@ + + typedef struct nw_zones nw_zones; + ++#include "daemon.h" ++ + nw_zones* nw_zones_ref(nw_zones* zones); + nw_zones* nw_zones_unref(nw_zones* zones); + +-int nw_zones_load(nw_zones** zones); ++int nw_zones_load(nw_zones** zones, nw_daemon* daemon); + + size_t nw_zones_num(nw_zones* zones); + +-- +2.39.2 + diff --git a/network/patches/0207-networkd-Refactor-enumerating-zones.patch b/network/patches/0207-networkd-Refactor-enumerating-zones.patch new file mode 100644 index 000000000..e1dec5603 --- /dev/null +++ b/network/patches/0207-networkd-Refactor-enumerating-zones.patch @@ -0,0 +1,231 @@ +From 7af642e14376b599183cd19091d4cab28ddc11e7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 18:00:26 +0000 +Subject: [PATCH 207/304] networkd: Refactor enumerating zones + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 21 +++++++--- + src/networkd/zone.h | 2 + + src/networkd/zones.c | 97 +++++++++++++------------------------------ + src/networkd/zones.h | 4 +- + 4 files changed, 50 insertions(+), 74 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 8122f58..6a6def3 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -140,11 +140,6 @@ static int nw_daemon_load_config(nw_daemon* daemon) { + if (r) + return r; + +- // Load zones +- r = nw_zones_load(&daemon->zones, daemon); +- if (r) +- return r; +- + return r; + } + +@@ -264,6 +259,17 @@ static int nw_daemon_enumerate_ports(nw_daemon* daemon) { + return nw_ports_enumerate(daemon->ports); + } + ++static int nw_daemon_enumerate_zones(nw_daemon* daemon) { ++ int r; ++ ++ // Create a new zones container ++ r = nw_zones_create(&daemon->zones, daemon); ++ if (r) ++ return r; ++ ++ return nw_zones_enumerate(daemon->zones); ++} ++ + static int nw_daemon_enumerate(nw_daemon* daemon) { + int r; + +@@ -277,6 +283,11 @@ static int nw_daemon_enumerate(nw_daemon* daemon) { + if (r) + return r; + ++ // Zones ++ r = nw_daemon_enumerate_zones(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 9df30ec..2748e6d 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_ZONE_H + #define NETWORKD_ZONE_H + ++#define ZONE_CONFIG_DIR CONFIG_DIR "/zones" ++ + #define NETWORK_ZONE_NAME_MAX_LENGTH 16 + #define NETWORK_ZONE_DEFAULT_MTU 1500 + +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index fd43f1c..1b0ffdc 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -25,6 +25,8 @@ + + #include "daemon.h" + #include "logging.h" ++#include "string.h" ++#include "util.h" + #include "zone.h" + #include "zones.h" + +@@ -46,7 +48,7 @@ struct nw_zones { + unsigned int num; + }; + +-static int nw_zones_create(nw_zones** zones, nw_daemon* daemon) { ++int nw_zones_create(nw_zones** zones, nw_daemon* daemon) { + nw_zones* z = calloc(1, sizeof(*z)); + if (!z) + return 1; +@@ -120,89 +122,48 @@ static int nw_zones_add_zone(nw_zones* zones, nw_zone* zone) { + return 0; + } + +-static int nw_zones_load_filter(const struct dirent* path) { +- const char* fn = path->d_name; +- +- // Ignore everything starting with '.' +- if (*fn == '.') +- return 0; +- +- // Ignore anything that isn't a directory +- if (path->d_type != DT_DIR) +- return 0; +- +- return 1; +-} +- +-static int __nw_zones_load(nw_zones* zones) { +- struct dirent** paths = NULL; +- int n; +- int r = 0; +- ++static int __nw_zones_enumerate(const char* path, const struct stat* s, void* data) { + nw_zone* zone = NULL; ++ int r; + +- // Scan the zones directory +- n = scandir(CONFIG_DIR "/zones", &paths, nw_zones_load_filter, alphasort); +- if (n < 0) { +- ERROR("Could not load zones: %m\n"); +- return 1; +- } +- +- DEBUG("Found %d zone(s)\n", n); +- +- // Load all zones +- for (int i = 0; i < n; i++) { +- const char* name = paths[i]->d_name; +- +- DEBUG("Loading zone '%s'...\n", name); +- +- // Create a new zone object +- r = nw_zone_create(&zone, zones->daemon, name); +- if (r) +- goto ERROR; +- +- // Store the zone +- r = nw_zones_add_zone(zones, zone); +- if (r) { +- nw_zone_unref(zone); +- goto ERROR; +- } ++ nw_zones* zones = (nw_zones*)data; + +- nw_zone_unref(zone); +- } ++ // Skip anything that isn't a directory ++ if (!S_ISDIR(s->st_mode)) ++ return 0; + +-ERROR: +- // Free paths +- if (paths) { +- for (int i = 0; i < n; i++) { +- free(paths[i]); +- } +- free(paths); +- } ++ // Find the basename of the file ++ const char* name = nw_path_basename(path); + +- return r; +-} ++ // Break on invalid paths ++ if (!name) ++ return 0; + +-int nw_zones_load(nw_zones** zones, nw_daemon* daemon) { +- int r; ++ // Skip any hidden files ++ if (*name == '.') ++ return 0; + +- // Create a new zones object +- r = nw_zones_create(zones, daemon); ++ // Create a new zone ++ r = nw_zone_create(&zone, zones->daemon, name); + if (r) +- return r; ++ goto ERROR; + +- // Load all zones +- r = __nw_zones_load(*zones); ++ // Add the zone to the list ++ r = nw_zones_add_zone(zones, zone); + if (r) + goto ERROR; + +- return 0; +- + ERROR: +- nw_zones_unref(*zones); ++ if (zone) ++ nw_zone_unref(zone); ++ + return r; + } + ++int nw_zones_enumerate(nw_zones* zones) { ++ return nw_ftw(ZONE_CONFIG_DIR, ZONE_CONFIG_DIR "/*", __nw_zones_enumerate, zones); ++} ++ + size_t nw_zones_num(nw_zones* zones) { + struct nw_zones_entry* entry = NULL; + size_t length = 0; +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index 330e524..dbf7ccd 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -25,10 +25,12 @@ typedef struct nw_zones nw_zones; + + #include "daemon.h" + ++int nw_zones_create(nw_zones** zones, nw_daemon* daemon); ++ + nw_zones* nw_zones_ref(nw_zones* zones); + nw_zones* nw_zones_unref(nw_zones* zones); + +-int nw_zones_load(nw_zones** zones, nw_daemon* daemon); ++int nw_zones_enumerate(nw_zones* zones); + + size_t nw_zones_num(nw_zones* zones); + +-- +2.39.2 + diff --git a/network/patches/0208-networkd-Save-configuration-when-the-daemon-exits.patch b/network/patches/0208-networkd-Save-configuration-when-the-daemon-exits.patch new file mode 100644 index 000000000..75c62ada2 --- /dev/null +++ b/network/patches/0208-networkd-Save-configuration-when-the-daemon-exits.patch @@ -0,0 +1,239 @@ +From 605e975f53ed433718df5d101496474870d6439c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 11 Feb 2023 18:29:32 +0000 +Subject: [PATCH 208/304] networkd: Save configuration when the daemon exits + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 31 +++++++++++++++++++++++++++++++ + src/networkd/daemon.h | 2 ++ + src/networkd/main.c | 1 + + src/networkd/port.c | 10 ++++++++++ + src/networkd/port.h | 2 ++ + src/networkd/ports.c | 13 +++++++++++++ + src/networkd/ports.h | 2 ++ + src/networkd/zone.c | 10 ++++++++++ + src/networkd/zone.h | 2 ++ + src/networkd/zones.c | 13 +++++++++++++ + src/networkd/zones.h | 2 ++ + 11 files changed, 88 insertions(+) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 6a6def3..c67c759 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -409,6 +409,11 @@ int nw_daemon_run(nw_daemon* daemon) { + // Let systemd know that we are shutting down + sd_notify(0, "STOPPING=1\n" "STATUS=Shutting down..."); + ++ // Save the configuration ++ r = nw_daemon_save(daemon); ++ if (r) ++ goto ERROR; ++ + // Cleanup everything + nw_daemon_cleanup(daemon); + +@@ -431,6 +436,32 @@ int nw_daemon_reload(nw_daemon* daemon) { + return 0; + } + ++/* ++ Saves the configuration to disk ++*/ ++int nw_daemon_save(nw_daemon* daemon) { ++ int r; ++ ++ DEBUG("Saving configuration...\n"); ++ ++ // Save settings ++ r = nw_config_write(daemon->config); ++ if (r) ++ return r; ++ ++ // Save ports ++ r = nw_ports_save(daemon->ports); ++ if (r) ++ return r; ++ ++ // Save zones ++ r = nw_zones_save(daemon->zones); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + /* + Netlink + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 1694599..6f4c217 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -41,6 +41,8 @@ int nw_daemon_run(nw_daemon* daemon); + + int nw_daemon_reload(nw_daemon* daemon); + ++int nw_daemon_save(nw_daemon* daemon); ++ + /* + Netlink + */ +diff --git a/src/networkd/main.c b/src/networkd/main.c +index d3afc2a..c8b9a79 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -29,6 +29,7 @@ + + #include "daemon.h" + #include "logging.h" ++#include "port.h" + + static int cap_acquire_setpcap(void) { + cap_flag_value_t value; +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 41b8b24..30bd98f 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -213,6 +213,16 @@ nw_port* nw_port_unref(nw_port* port) { + return NULL; + } + ++int nw_port_save(nw_port* port) { ++ int r; ++ ++ r = nw_config_write(port->config); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + const char* nw_port_name(nw_port* port) { + return port->name; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 9881846..8861046 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -38,6 +38,8 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name); + nw_port* nw_port_ref(nw_port* port); + nw_port* nw_port_unref(nw_port* port); + ++int nw_port_save(nw_port* port); ++ + const char* nw_port_name(nw_port* port); + + char* nw_port_bus_path(nw_port* port); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 35ed048..a87ca03 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -98,6 +98,19 @@ nw_ports* nw_ports_unref(nw_ports* ports) { + return NULL; + } + ++int nw_ports_save(nw_ports* ports) { ++ struct nw_ports_entry* entry = NULL; ++ int r; ++ ++ STAILQ_FOREACH(entry, &ports->entries, nodes) { ++ r = nw_port_save(entry->port); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ + static int nw_ports_add_port(nw_ports* ports, nw_port* port) { + // Allocate a new entry + struct nw_ports_entry* entry = calloc(1, sizeof(*entry)); +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +index f58c3a4..40c9ae1 100644 +--- a/src/networkd/ports.h ++++ b/src/networkd/ports.h +@@ -30,6 +30,8 @@ int nw_ports_create(nw_ports** ports, nw_daemon* daemon); + nw_ports* nw_ports_ref(nw_ports* ports); + nw_ports* nw_ports_unref(nw_ports* ports); + ++int nw_ports_save(nw_ports* ports); ++ + int nw_ports_enumerate(nw_ports* ports); + + struct nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name); +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 30f22d6..1e4abc3 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -137,6 +137,16 @@ nw_zone* nw_zone_unref(nw_zone* zone) { + return NULL; + } + ++int nw_zone_save(nw_zone* zone) { ++ int r; ++ ++ r = nw_config_write(zone->config); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + const char* nw_zone_name(nw_zone* zone) { + return zone->name; + } +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 2748e6d..088bb2f 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -35,6 +35,8 @@ int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name); + nw_zone* nw_zone_ref(nw_zone* zone); + nw_zone* nw_zone_unref(nw_zone* zone); + ++int nw_zone_save(nw_zone* zone); ++ + const char* nw_zone_name(nw_zone* zone); + + char* nw_zone_bus_path(nw_zone* zone); +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 1b0ffdc..ea0d8de 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -104,6 +104,19 @@ nw_zones* nw_zones_unref(nw_zones* zones) { + return NULL; + } + ++int nw_zones_save(nw_zones* zones) { ++ struct nw_zones_entry* entry = NULL; ++ int r; ++ ++ STAILQ_FOREACH(entry, &zones->entries, nodes) { ++ r = nw_zone_save(entry->zone); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ + static int nw_zones_add_zone(nw_zones* zones, nw_zone* zone) { + // Allocate a new entry + struct nw_zones_entry* entry = calloc(1, sizeof(*entry)); +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index dbf7ccd..c887bd0 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -30,6 +30,8 @@ int nw_zones_create(nw_zones** zones, nw_daemon* daemon); + nw_zones* nw_zones_ref(nw_zones* zones); + nw_zones* nw_zones_unref(nw_zones* zones); + ++int nw_zones_save(nw_zones* zones); ++ + int nw_zones_enumerate(nw_zones* zones); + + size_t nw_zones_num(nw_zones* zones); +-- +2.39.2 + diff --git a/network/patches/0209-networkd-Store-any-flags.patch b/network/patches/0209-networkd-Store-any-flags.patch new file mode 100644 index 000000000..33427641c --- /dev/null +++ b/network/patches/0209-networkd-Store-any-flags.patch @@ -0,0 +1,69 @@ +From c65300b47197145ac899bd2e80597b4c6b44ca6d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 13 Feb 2023 15:05:41 +0000 +Subject: [PATCH 209/304] networkd: Store any flags + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 2f95dc3..78ae106 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -45,6 +45,9 @@ struct nw_link { + uint32_t mtu; + uint32_t min_mtu; + uint32_t max_mtu; ++ ++ // Flags ++ unsigned int flags; + }; + + int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex) { +@@ -168,6 +171,29 @@ static int nw_link_update_mtu(nw_link* link, sd_netlink_message* message) { + return 0; + } + ++static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { ++ unsigned int flags = 0; ++ int r; ++ ++ // Fetch flags ++ r = sd_rtnl_message_link_get_flags(message, &flags); ++ if (r < 0) { ++ return DEBUG("Could not read link flags: %m\n"); ++ return 1; ++ } ++ ++ // End here if there have been no changes ++ if (link->flags == flags) ++ return 0; ++ ++ // XXX We should log any changes here ++ ++ // Store the new flags ++ link->flags = flags; ++ ++ return 0; ++} ++ + /* + This function is called whenever anything changes, so that we can + update our internal link object. +@@ -185,6 +211,11 @@ static int nw_link_update(nw_link* link, sd_netlink_message* message) { + if (r) + return r; + ++ // Update flags ++ r = nw_link_update_flags(link, message); ++ if (r) ++ return r; ++ + return 0; + } + +-- +2.39.2 + diff --git a/network/patches/0210-networkd-Store-operstate-too.patch b/network/patches/0210-networkd-Store-operstate-too.patch new file mode 100644 index 000000000..2c0b950d2 --- /dev/null +++ b/network/patches/0210-networkd-Store-operstate-too.patch @@ -0,0 +1,59 @@ +From 69ef50c7403a5e09fcdf6ee4b53f94665920277a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 13 Feb 2023 15:10:01 +0000 +Subject: [PATCH 210/304] networkd: Store operstate, too + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 78ae106..6392a90 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -48,6 +48,7 @@ struct nw_link { + + // Flags + unsigned int flags; ++ uint8_t operstate; + }; + + int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex) { +@@ -173,6 +174,7 @@ static int nw_link_update_mtu(nw_link* link, sd_netlink_message* message) { + + static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { + unsigned int flags = 0; ++ uint8_t operstate = 0; + int r; + + // Fetch flags +@@ -182,14 +184,23 @@ static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { + return 1; + } + ++ // Fetch operstate ++ r = sd_netlink_message_read_u8(message, IFLA_OPERSTATE, &operstate); ++ if (r < 1) { ++ ERROR("Could not read operstate: %m\n"); ++ return 1; ++ } ++ + // End here if there have been no changes +- if (link->flags == flags) ++ if (link->flags == flags && link->operstate == operstate) + return 0; + + // XXX We should log any changes here + +- // Store the new flags ++ // Store the new flags & operstate + link->flags = flags; ++ link->operstate = operstate; ++ + + return 0; + } +-- +2.39.2 + diff --git a/network/patches/0211-networkd-Add-function-to-check-whether-a-link-has-a-.patch b/network/patches/0211-networkd-Add-function-to-check-whether-a-link-has-a-.patch new file mode 100644 index 000000000..b5ec88638 --- /dev/null +++ b/network/patches/0211-networkd-Add-function-to-check-whether-a-link-has-a-.patch @@ -0,0 +1,96 @@ +From dfd49c2cc85fcee2303a96bc2186de0e21d8da4f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 13 Feb 2023 15:14:01 +0000 +Subject: [PATCH 211/304] networkd: Add function to check whether a link has a + carrier + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 32 ++++++++++++++++++++++++++++++-- + src/networkd/link.h | 2 ++ + 2 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 6392a90..80478f4 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -18,7 +18,7 @@ + # # + #############################################################################*/ + +-#include ++#include + #include + #include + #include +@@ -39,7 +39,7 @@ struct nw_link { + int ifindex; + + // Interface Name +- char ifname[IF_NAMESIZE]; ++ char ifname[IFNAMSIZ]; + + // MTU + uint32_t mtu; +@@ -98,6 +98,20 @@ int nw_link_ifindex(nw_link* link) { + return link->ifindex; + } + ++// Carrier ++ ++int nw_link_has_carrier(nw_link* link) { ++ return link->operstate == IF_OPER_UP; ++} ++ ++static int nw_link_carrier_gained(nw_link* link) { ++ return 0; // XXX TODO ++} ++ ++static int nw_link_carrier_lost(nw_link* link) { ++ return 0; // XXX TODO ++} ++ + static int nw_link_update_ifname(nw_link* link, sd_netlink_message* message) { + const char* ifname = NULL; + int r; +@@ -197,10 +211,24 @@ static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { + + // XXX We should log any changes here + ++ // Fetch current carrier state ++ const int had_carrier = nw_link_has_carrier(link); ++ + // Store the new flags & operstate + link->flags = flags; + link->operstate = operstate; + ++ // Notify if carrier was gained or lost ++ if (!had_carrier && nw_link_has_carrier(link)) { ++ r = nw_link_carrier_gained(link); ++ if (r < 0) ++ return r; ++ ++ } else if (had_carrier && !nw_link_has_carrier(link)) { ++ r = nw_link_carrier_lost(link); ++ if (r < 0) ++ return r; ++ } + + return 0; + } +diff --git a/src/networkd/link.h b/src/networkd/link.h +index acb5e7b..3d8d397 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -33,6 +33,8 @@ nw_link* nw_link_unref(nw_link* link); + int nw_link_ifindex(nw_link* link); + const char* nw_link_name(nw_link* link); + ++int nw_link_has_carrier(nw_link* link); ++ + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + + #endif /* NETWORKD_LINK_H */ +-- +2.39.2 + diff --git a/network/patches/0212-networkd-Add-methods-to-check-zones-ports-for-carrie.patch b/network/patches/0212-networkd-Add-methods-to-check-zones-ports-for-carrie.patch new file mode 100644 index 000000000..e0058a804 --- /dev/null +++ b/network/patches/0212-networkd-Add-methods-to-check-zones-ports-for-carrie.patch @@ -0,0 +1,92 @@ +From 20375a083cbb965971b3b471b161e6475cef3c4b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 13 Feb 2023 15:34:40 +0000 +Subject: [PATCH 212/304] networkd: Add methods to check zones/ports for + carrier + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 13 +++++++++++++ + src/networkd/port.h | 2 ++ + src/networkd/zone.c | 19 +++++++++++++++++++ + src/networkd/zone.h | 2 ++ + 4 files changed, 36 insertions(+) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 30bd98f..c6c8781 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -246,3 +246,16 @@ static nw_link* nw_port_get_link(nw_port* port) { + const nw_address_t* nw_port_get_address(nw_port* port) { + return &port->address; + } ++ ++int nw_port_has_carrier(nw_port* port) { ++ int has_carrier = 0; ++ ++ // Fetch link ++ nw_link* link = nw_port_get_link(port); ++ if (link) { ++ has_carrier = nw_link_has_carrier(link); ++ nw_link_unref(link); ++ } ++ ++ return has_carrier; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 8861046..33241ed 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -46,4 +46,6 @@ char* nw_port_bus_path(nw_port* port); + + const nw_address_t* nw_port_get_address(nw_port* port); + ++int nw_port_has_carrier(nw_port* port); ++ + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 1e4abc3..8fe07c5 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -163,6 +163,25 @@ char* nw_zone_bus_path(nw_zone* zone) { + return p; + } + ++static nw_link* nw_zone_get_link(nw_zone* zone) { ++ return nw_daemon_get_link_by_name(zone->daemon, zone->name); ++} ++ ++// Carrier ++ ++int nw_zone_has_carrier(nw_zone* zone) { ++ int has_carrier = 0; ++ ++ // Fetch link ++ nw_link* link = nw_zone_get_link(zone); ++ if (link) { ++ has_carrier = nw_link_has_carrier(link); ++ nw_link_unref(link); ++ } ++ ++ return has_carrier; ++} ++ + /* + MTU + */ +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 088bb2f..f5a2355 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -41,6 +41,8 @@ const char* nw_zone_name(nw_zone* zone); + + char* nw_zone_bus_path(nw_zone* zone); + ++int nw_zone_has_carrier(nw_zone* zone); ++ + /* + MTU + */ +-- +2.39.2 + diff --git a/network/patches/0213-networkd-Log-to-journald.patch b/network/patches/0213-networkd-Log-to-journald.patch new file mode 100644 index 000000000..6f3257eac --- /dev/null +++ b/network/patches/0213-networkd-Log-to-journald.patch @@ -0,0 +1,137 @@ +From 1a70a6864ca83ed91c9acfd6be5a64185ac34917 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 13 Feb 2023 16:00:43 +0000 +Subject: [PATCH 213/304] networkd: Log to journald + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + src/networkd/link.c | 2 +- + src/networkd/logging.c | 65 ++++++++++++++++++++++++++++++++++++++++++ + src/networkd/logging.h | 10 +++++-- + 4 files changed, 74 insertions(+), 4 deletions(-) + create mode 100644 src/networkd/logging.c + +diff --git a/Makefile.am b/Makefile.am +index 893f1b8..eded292 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -323,6 +323,7 @@ dist_networkd_SOURCES = \ + src/networkd/link.h \ + src/networkd/links.c \ + src/networkd/links.h \ ++ src/networkd/logging.c \ + src/networkd/logging.h \ + src/networkd/main.c \ + src/networkd/ports.c \ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 80478f4..7f49606 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -194,7 +194,7 @@ static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { + // Fetch flags + r = sd_rtnl_message_link_get_flags(message, &flags); + if (r < 0) { +- return DEBUG("Could not read link flags: %m\n"); ++ DEBUG("Could not read link flags: %m\n"); + return 1; + } + +diff --git a/src/networkd/logging.c b/src/networkd/logging.c +new file mode 100644 +index 0000000..c4809e8 +--- /dev/null ++++ b/src/networkd/logging.c +@@ -0,0 +1,65 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "logging.h" ++ ++void nw_log(int priority, const char* file, ++ int line, const char* fn, const char* format, ...) { ++ char* buffer = NULL; ++ va_list args; ++ int r; ++ ++ // Format log message ++ va_start(args, format); ++ r = vasprintf(&buffer, format, args); ++ va_end(args); ++ if (r < 0) ++ return; ++ ++ // Send message to journald ++ r = sd_journal_send( ++ "MESSAGE=%s", buffer, ++ "PRIORITY=%d", priority, ++ ++ // Syslog compat ++ "SYSLOG_IDENTIFIER=networkd", ++ ++ // Debugging stuff ++ "ERRNO=%d", errno, ++ "CODE_FILE=%s", file, ++ "CODE_LINE=%d", line, ++ "CODE_FUNC=%s", fn, ++ ++ NULL ++ ); ++ ++ // Fall back to standard output ++ if (r) ++ sd_journal_perror(buffer); ++ ++ // Cleanup ++ free(buffer); ++} +diff --git a/src/networkd/logging.h b/src/networkd/logging.h +index 9d51f21..ea75ba0 100644 +--- a/src/networkd/logging.h ++++ b/src/networkd/logging.h +@@ -21,12 +21,16 @@ + #ifndef NETWORKD_LOGGING_H + #define NETWORKD_LOGGING_H + +-#include ++#include ++ ++void nw_log(int priority, const char *file, int line, const char* fn, ++ const char *format, ...) __attribute__((format(printf, 5, 6))); + + /* + This is just something simple which will work for now... + */ +-#define ERROR(...) fprintf(stderr, __VA_ARGS__) +-#define DEBUG(...) printf(__VA_ARGS__) ++#define INFO(args...) nw_log(LOG_INFO, __FILE__, __LINE__, __FUNCTION__, ## args) ++#define ERROR(args...) nw_log(LOG_ERR, __FILE__, __LINE__, __FUNCTION__, ## args) ++#define DEBUG(args...) nw_log(LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, ## args) + + #endif /* NETWORKD_LOGGING_H */ +-- +2.39.2 + diff --git a/network/patches/0214-networkd-Install-in-usr-lib-network.patch b/network/patches/0214-networkd-Install-in-usr-lib-network.patch new file mode 100644 index 000000000..3b524d04d --- /dev/null +++ b/network/patches/0214-networkd-Install-in-usr-lib-network.patch @@ -0,0 +1,49 @@ +From ac0188ee9bffceedc94417e586bcbe21daa96c74 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Mar 2023 15:34:32 +0000 +Subject: [PATCH 214/304] networkd: Install in /usr/lib/network + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 ++-- + src/networkd/networkd.service.in | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index eded292..707eabe 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -61,7 +61,7 @@ INSTALL_DIRS = + INSTALL_EXEC_HOOKS = + UNINSTALL_EXEC_HOOKS = + noinst_DATA = +-sbin_PROGRAMS = ++network_PROGRAMS = + dist_dbuspolicy_DATA = + dist_dbussystembus_DATA = + dist_polkitpolicy_DATA = +@@ -304,7 +304,7 @@ EXTRA_DIST += \ + + # ------------------------------------------------------------------------------ + +-sbin_PROGRAMS += \ ++network_PROGRAMS += \ + networkd + + dist_networkd_SOURCES = \ +diff --git a/src/networkd/networkd.service.in b/src/networkd/networkd.service.in +index 4361023..7ee8fad 100644 +--- a/src/networkd/networkd.service.in ++++ b/src/networkd/networkd.service.in +@@ -15,7 +15,7 @@ AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET + BusName=org.ipfire.network1 + CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW + DeviceAllow=char-* rw +-ExecStart=@sbindir@/networkd ++ExecStart=@networkdir@/networkd + FileDescriptorStoreMax=512 + LockPersonality=yes + MemoryDenyWriteExecute=yes +-- +2.39.2 + diff --git a/network/patches/0215-networkctl-Create-some-scaffolding.patch b/network/patches/0215-networkctl-Create-some-scaffolding.patch new file mode 100644 index 000000000..c054332c4 --- /dev/null +++ b/network/patches/0215-networkctl-Create-some-scaffolding.patch @@ -0,0 +1,94 @@ +From 840738f6baf2d3024df6ae0e9a887c5b1bef3a50 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Mar 2023 15:41:17 +0000 +Subject: [PATCH 215/304] networkctl: Create some scaffolding + +Signed-off-by: Michael Tremer +--- + .gitignore | 1 + + Makefile.am | 19 +++++++++++++++++++ + src/networkctl/main.c | 23 +++++++++++++++++++++++ + 3 files changed, 43 insertions(+) + create mode 100644 src/networkctl/main.c + +diff --git a/.gitignore b/.gitignore +index 9194c93..c45db75 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -3,6 +3,7 @@ + /config.* + /libtool + /missing ++/networkctl + /networkd + /src/functions/functions + /src/inetcalc +diff --git a/Makefile.am b/Makefile.am +index 707eabe..1640060 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -379,6 +379,24 @@ CLEANFILES += \ + + # ------------------------------------------------------------------------------ + ++bin_PROGRAMS += \ ++ networkctl ++ ++dist_networkctl_SOURCES = \ ++ src/networkctl/main.c ++ ++networkctl_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ $(SYSTEMD_CFLAGS) ++ ++networkctl_LDFLAGS = \ ++ $(AM_LDFLAGS) ++ ++networkctl_LDADD = \ ++ $(SYSTEMD_LIBS) ++ ++# ------------------------------------------------------------------------------ ++ + util_PROGRAMS = \ + src/utils/network-phy-list-channels \ + src/utils/network-phy-list-ciphers \ +@@ -622,6 +640,7 @@ substitutions = \ + '|builddir=$(abs_builddir)|' \ + '|prefix=$(prefix)|' \ + '|exec_prefix=$(exec_prefix)|' \ ++ '|bindir=$(bindir)|' \ + '|sbindir=$(sbindir)|' \ + '|networkdir=$(networkdir)|' \ + '|helpersdir=$(helpersdir)|' \ +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +new file mode 100644 +index 0000000..14aafdd +--- /dev/null ++++ b/src/networkctl/main.c +@@ -0,0 +1,23 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++int main(int argc, char** argv) { ++ return 0; ++} +-- +2.39.2 + diff --git a/network/patches/0216-networkctl-Connect-to-the-system-bus.patch b/network/patches/0216-networkctl-Connect-to-the-system-bus.patch new file mode 100644 index 000000000..2ba84a6d8 --- /dev/null +++ b/network/patches/0216-networkctl-Connect-to-the-system-bus.patch @@ -0,0 +1,45 @@ +From d9b54f58d6abedf04cfa893cae479b05533f470f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Mar 2023 15:52:20 +0000 +Subject: [PATCH 216/304] networkctl: Connect to the system bus + +Signed-off-by: Michael Tremer +--- + src/networkctl/main.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 14aafdd..6ecaeb6 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -18,6 +18,26 @@ + # # + #############################################################################*/ + ++#include ++ ++#include ++ + int main(int argc, char** argv) { +- return 0; ++ sd_bus* bus = NULL; ++ int r; ++ ++ // Connect to system bus ++ r = sd_bus_open_system(&bus); ++ if (r < 0) { ++ fprintf(stderr, "Could not connect to system bus: %m\n"); ++ goto ERROR; ++ } ++ ++ // XXX TODO Do all the work ++ ++ERROR: ++ if (bus) ++ sd_bus_flush_close_unref(bus); ++ ++ return r; + } +-- +2.39.2 + diff --git a/network/patches/0217-networkctl-Add-some-help-and-version-arguments.patch b/network/patches/0217-networkctl-Add-some-help-and-version-arguments.patch new file mode 100644 index 000000000..9f9eaecf0 --- /dev/null +++ b/network/patches/0217-networkctl-Add-some-help-and-version-arguments.patch @@ -0,0 +1,94 @@ +From bc44ba7128b38d16455899acaa145daa2eb6aade Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Mar 2023 16:13:11 +0000 +Subject: [PATCH 217/304] networkctl: Add some help and version arguments + +Signed-off-by: Michael Tremer +--- + src/networkctl/main.c | 63 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 62 insertions(+), 1 deletion(-) + +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 6ecaeb6..494fd7d 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -18,14 +18,75 @@ + # # + #############################################################################*/ + ++#include ++#include + #include ++#include + + #include + +-int main(int argc, char** argv) { ++static int version(void) { ++ printf("networkctl %s\n", PACKAGE_VERSION); ++ ++ return 0; ++} ++ ++static int help(void) { ++ printf( ++ "%s [OPTIONS...] COMMAND\n\n" ++ "Options:\n" ++ " -h --help Show help\n" ++ " --version Show version\n", ++ program_invocation_short_name ++ ); ++ ++ return 0; ++} ++ ++static int parse_argv(int argc, char* argv[]) { ++ enum { ++ ARG_VERSION, ++ }; ++ ++ static const struct option options[] = { ++ { "help", no_argument, NULL, 'h' }, ++ { "version", no_argument, NULL, ARG_VERSION }, ++ { NULL }, ++ }; ++ int c; ++ ++ for (;;) { ++ c = getopt_long(argc, argv, "h", options, NULL); ++ if (c < 0) ++ break; ++ ++ switch (c) { ++ case 'h': ++ return help(); ++ ++ case ARG_VERSION: ++ return version(); ++ ++ case '?': ++ return -EINVAL; ++ ++ default: ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++int main(int argc, char* argv[]) { + sd_bus* bus = NULL; + int r; + ++ // Parse command line arguments ++ r = parse_argv(argc, argv); ++ if (r) ++ goto ERROR; ++ + // Connect to system bus + r = sd_bus_open_system(&bus); + if (r < 0) { +-- +2.39.2 + diff --git a/network/patches/0218-networkctl-Implement-a-basic-command-dispatcher.patch b/network/patches/0218-networkctl-Implement-a-basic-command-dispatcher.patch new file mode 100644 index 000000000..74e8eae38 --- /dev/null +++ b/network/patches/0218-networkctl-Implement-a-basic-command-dispatcher.patch @@ -0,0 +1,172 @@ +From f3bb976c4be0fe41959d7623f4ae3269c0e95e1d Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 1 Mar 2023 16:55:45 +0000 +Subject: [PATCH 218/304] networkctl: Implement a basic command dispatcher + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkctl/command.c | 58 ++++++++++++++++++++++++++++++++++++++++ + src/networkctl/command.h | 34 +++++++++++++++++++++++ + src/networkctl/main.c | 19 ++++++++++++- + 4 files changed, 112 insertions(+), 1 deletion(-) + create mode 100644 src/networkctl/command.c + create mode 100644 src/networkctl/command.h + +diff --git a/Makefile.am b/Makefile.am +index 1640060..186af94 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -383,6 +383,8 @@ bin_PROGRAMS += \ + networkctl + + dist_networkctl_SOURCES = \ ++ src/networkctl/command.c \ ++ src/networkctl/command.h \ + src/networkctl/main.c + + networkctl_CFLAGS = \ +diff --git a/src/networkctl/command.c b/src/networkctl/command.c +new file mode 100644 +index 0000000..7114efe +--- /dev/null ++++ b/src/networkctl/command.c +@@ -0,0 +1,58 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++#include ++ ++#include "command.h" ++ ++static const struct command* command_find(const struct command* commands, const char* verb) { ++ for (const struct command* command = commands; command->verb; command++) { ++ if (strcmp(command->verb, verb) == 0) ++ return command; ++ } ++ ++ return NULL; ++} ++ ++int command_dispatch(sd_bus* bus, const struct command* commands, int argc, char* argv[]) { ++ const struct command* command = NULL; ++ ++ argc -= optind; ++ argv += optind; ++ optind = 1; ++ ++ if (!argc) { ++ fprintf(stderr, "Command required\n"); ++ return -EINVAL; ++ } ++ ++ const char* verb = argv[0]; ++ ++ // Find a matching command ++ command = command_find(commands, verb); ++ if (!command) { ++ fprintf(stderr, "Unknown command '%s'\n", verb); ++ return -EINVAL; ++ } ++ ++ return command->callback(bus, argc, argv); ++} +diff --git a/src/networkctl/command.h b/src/networkctl/command.h +new file mode 100644 +index 0000000..f8f295e +--- /dev/null ++++ b/src/networkctl/command.h +@@ -0,0 +1,34 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKCTL_COMMAND_H ++#define NETWORKCTL_COMMAND_H ++ ++#include ++ ++struct command { ++ const char* verb; ++ int flags; ++ int (*callback)(sd_bus* bus, int argc, char* argv[]); ++}; ++ ++int command_dispatch(sd_bus* bus, const struct command* commands, int argc, char* argv[]); ++ ++#endif /* NETWORKCTL_COMMAND_H */ +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 494fd7d..0cbc3e6 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -25,6 +25,22 @@ + + #include + ++#include "command.h" ++ ++static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { ++ printf("%s called\n", __FUNCTION__); ++ return 0; ++} ++ ++static int networkctl_main(sd_bus* bus, int argc, char* argv[]) { ++ static const struct command commands[] = { ++ { "status", 0, networkctl_status }, ++ { NULL }, ++ }; ++ ++ return command_dispatch(bus, commands, argc, argv); ++} ++ + static int version(void) { + printf("networkctl %s\n", PACKAGE_VERSION); + +@@ -94,7 +110,8 @@ int main(int argc, char* argv[]) { + goto ERROR; + } + +- // XXX TODO Do all the work ++ // Run a command ++ r = networkctl_main(bus, argc, argv); + + ERROR: + if (bus) +-- +2.39.2 + diff --git a/network/patches/0219-networkd-Implement-ListZones-bus-command.patch b/network/patches/0219-networkd-Implement-ListZones-bus-command.patch new file mode 100644 index 000000000..e6558d155 --- /dev/null +++ b/network/patches/0219-networkd-Implement-ListZones-bus-command.patch @@ -0,0 +1,169 @@ +From b4faae0abf9bd02b4aa02660a85d58497ad8b07b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 11:25:56 +0000 +Subject: [PATCH 219/304] networkd: Implement ListZones bus command + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon-bus.c | 55 +++++++++++++++++++++++++++++++++++++++ + src/networkd/daemon.c | 7 +++++ + src/networkd/daemon.h | 1 + + src/networkd/zones.c | 13 +++++++++ + src/networkd/zones.h | 4 +++ + 5 files changed, 80 insertions(+) + +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +index 93a0411..7620eed 100644 +--- a/src/networkd/daemon-bus.c ++++ b/src/networkd/daemon-bus.c +@@ -18,12 +18,16 @@ + # # + #############################################################################*/ + ++#include ++ + #include + + #include "bus.h" + #include "daemon.h" ++#include "logging.h" + #include "port-bus.h" + #include "zone-bus.h" ++#include "zones.h" + + static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* error) { + nw_daemon* daemon = (nw_daemon*)data; +@@ -35,8 +39,59 @@ static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* err + return sd_bus_reply_method_return(m, NULL); + } + ++static int __nw_daemon_bus_list_zones(nw_daemon* daemon, nw_zone* zone, void* data) { ++ sd_bus_message* reply = (sd_bus_message*)data; ++ int r; ++ ++ // Fetch zone name ++ const char* name = nw_zone_name(zone); ++ ++ // Fetch bus path ++ char* path = nw_zone_bus_path(zone); ++ ++ r = sd_bus_message_append(reply, "(so)", name, path); ++ ++ free(path); ++ ++ return r; ++} ++ ++static int nw_daemon_bus_list_zones(sd_bus_message* m, void* data, sd_bus_error* error) { ++ nw_daemon* daemon = (nw_daemon*)data; ++ sd_bus_message* reply = NULL; ++ int r; ++ ++ // Form a reply message ++ r = sd_bus_message_new_method_return(m, &reply); ++ if (r < 0) ++ goto ERROR; ++ ++ r = sd_bus_message_open_container(reply, 'a', "(so)"); ++ if (r < 0) ++ goto ERROR; ++ ++ r = nw_daemon_zones_walk(daemon, __nw_daemon_bus_list_zones, reply); ++ if (r < 0) ++ goto ERROR; ++ ++ r = sd_bus_message_close_container(reply); ++ if (r < 0) ++ goto ERROR; ++ ++ // Send the reply ++ r = sd_bus_send(NULL, reply, NULL); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ ++ return r; ++} ++ + static const sd_bus_vtable daemon_vtable[] = { + SD_BUS_VTABLE_START(0), ++ SD_BUS_METHOD_WITH_ARGS("ListZones", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links), ++ nw_daemon_bus_list_zones, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, + nw_daemon_bus_reload, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END, +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index c67c759..925b207 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -519,6 +519,13 @@ nw_zones* nw_daemon_zones(nw_daemon* daemon) { + return nw_zones_ref(daemon->zones); + } + ++int nw_daemon_zones_walk(nw_daemon* daemon, nw_zones_walk_callback callback, void* data) { ++ if (!daemon->zones) ++ return 0; ++ ++ return nw_zones_walk(daemon->zones, callback, data); ++} ++ + nw_zone* nw_daemon_get_zone_by_name(nw_daemon* daemon, const char* name) { + if (!daemon->zones) + return NULL; +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 6f4c217..ce9a660 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -66,6 +66,7 @@ nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name); + Zones + */ + nw_zones* nw_daemon_zones(nw_daemon* daemon); ++int nw_daemon_zones_walk(nw_daemon* daemon, nw_zones_walk_callback callback, void* data); + nw_zone* nw_daemon_get_zone_by_name(nw_daemon* daemon, const char* name); + + #endif /* NETWORKD_DAEMON_H */ +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index ea0d8de..521da51 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -239,3 +239,16 @@ ERROR: + + return 1; + } ++ ++int nw_zones_walk(nw_zones* zones, nw_zones_walk_callback callback, void* data) { ++ struct nw_zones_entry* entry = NULL; ++ int r; ++ ++ STAILQ_FOREACH(entry, &zones->entries, nodes) { ++ r = callback(zones->daemon, entry->zone, data); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index c887bd0..019955e 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -23,6 +23,8 @@ + + typedef struct nw_zones nw_zones; + ++typedef int (*nw_zones_walk_callback)(nw_daemon* daemon, nw_zone* zone, void* data); ++ + #include "daemon.h" + + int nw_zones_create(nw_zones** zones, nw_daemon* daemon); +@@ -40,4 +42,6 @@ nw_zone* nw_zones_get_by_name(nw_zones* zones, const char* name); + + int nw_zones_bus_paths(nw_zones* zones, char*** paths); + ++int nw_zones_walk(nw_zones* zones, nw_zones_walk_callback callback, void* data); ++ + #endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0220-networkctl-Implement-zone-list-command.patch b/network/patches/0220-networkctl-Implement-zone-list-command.patch new file mode 100644 index 000000000..05492bc75 --- /dev/null +++ b/network/patches/0220-networkctl-Implement-zone-list-command.patch @@ -0,0 +1,188 @@ +From 537fae0bc0758b2b93a80dff94918752ff01b813 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 11:26:43 +0000 +Subject: [PATCH 220/304] networkctl: Implement "zone list" command + +Signed-off-by: Michael Tremer +--- + Makefile.am | 4 +- + src/networkctl/main.c | 2 + + src/networkctl/zone.c | 97 +++++++++++++++++++++++++++++++++++++++++++ + src/networkctl/zone.h | 26 ++++++++++++ + 4 files changed, 128 insertions(+), 1 deletion(-) + create mode 100644 src/networkctl/zone.c + create mode 100644 src/networkctl/zone.h + +diff --git a/Makefile.am b/Makefile.am +index 186af94..80a7236 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -385,7 +385,9 @@ bin_PROGRAMS += \ + dist_networkctl_SOURCES = \ + src/networkctl/command.c \ + src/networkctl/command.h \ +- src/networkctl/main.c ++ src/networkctl/main.c \ ++ src/networkctl/zone.c \ ++ src/networkctl/zone.h + + networkctl_CFLAGS = \ + $(AM_CFLAGS) \ +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 0cbc3e6..a08256c 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -26,6 +26,7 @@ + #include + + #include "command.h" ++#include "zone.h" + + static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { + printf("%s called\n", __FUNCTION__); +@@ -35,6 +36,7 @@ static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { + static int networkctl_main(sd_bus* bus, int argc, char* argv[]) { + static const struct command commands[] = { + { "status", 0, networkctl_status }, ++ { "zone", 0, networkctl_zone }, + { NULL }, + }; + +diff --git a/src/networkctl/zone.c b/src/networkctl/zone.c +new file mode 100644 +index 0000000..ee1d0a2 +--- /dev/null ++++ b/src/networkctl/zone.c +@@ -0,0 +1,97 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "command.h" ++#include "zone.h" ++ ++typedef int (*networkctl_zone_walk_callback) ++ (sd_bus* bus, const char* path, const char* name, void* data); ++ ++static int networkctl_zone_walk(sd_bus* bus, ++ networkctl_zone_walk_callback callback, void* data) { ++ sd_bus_message* reply = NULL; ++ sd_bus_error error = SD_BUS_ERROR_NULL; ++ int r; ++ ++ // Call ListZones ++ r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1", ++ "org.ipfire.network1", "ListZones", &error, &reply, ""); ++ if (r < 0) { ++ fprintf(stderr, "ListZones call failed: %m\n"); ++ goto ERROR; ++ } ++ ++ const char* name = NULL; ++ const char* path = NULL; ++ ++ // Open the container ++ r = sd_bus_message_enter_container(reply, 'a', "(so)"); ++ if (r < 0) { ++ fprintf(stderr, "Could not open container: %m\n"); ++ goto ERROR; ++ } ++ ++ // Iterate over all zones ++ for (;;) { ++ r = sd_bus_message_read(reply, "(so)", &name, &path); ++ if (r < 0) ++ goto ERROR; ++ ++ // Break if we reached the end of the container ++ if (r == 0) ++ break; ++ ++ // Call the callback ++ r = callback(bus, path, name, data); ++ if (r) ++ goto ERROR; ++ } ++ ++ // Close the container ++ sd_bus_message_exit_container(reply); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ sd_bus_error_free(&error); ++ ++ return r; ++} ++ ++static int __networkctl_zone_list(sd_bus* bus, const char* path, const char* name, void* data) { ++ printf("%s\n", name); ++ ++ return 0; ++} ++ ++static int networkctl_zone_list(sd_bus* bus, int argc, char* argv[]) { ++ return networkctl_zone_walk(bus, __networkctl_zone_list, NULL); ++} ++ ++int networkctl_zone(sd_bus* bus, int argc, char* argv[]) { ++ static const struct command commands[] = { ++ { "list", 0, networkctl_zone_list }, ++ { NULL }, ++ }; ++ ++ return command_dispatch(bus, commands, argc, argv); ++} +diff --git a/src/networkctl/zone.h b/src/networkctl/zone.h +new file mode 100644 +index 0000000..5eddd98 +--- /dev/null ++++ b/src/networkctl/zone.h +@@ -0,0 +1,26 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKCTL_ZONE_H ++#define NETWORKCTL_ZONE_H ++ ++int networkctl_zone(sd_bus* bus, int argc, char* argv[]); ++ ++#endif /* NETWORKCTL_ZONE_H */ +-- +2.39.2 + diff --git a/network/patches/0221-networkd-Fix-finding-links-by-name.patch b/network/patches/0221-networkd-Fix-finding-links-by-name.patch new file mode 100644 index 000000000..bac9705bc --- /dev/null +++ b/network/patches/0221-networkd-Fix-finding-links-by-name.patch @@ -0,0 +1,56 @@ +From 207abe4eabad65c2d1e120f7c0fc711d17ed017a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 11:57:19 +0000 +Subject: [PATCH 221/304] networkd: Fix finding links by name + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 4 ++++ + src/networkd/link.h | 2 +- + src/networkd/links.c | 2 +- + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 7f49606..0fb388b 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -98,6 +98,10 @@ int nw_link_ifindex(nw_link* link) { + return link->ifindex; + } + ++const char* nw_link_ifname(nw_link* link) { ++ return link->ifname; ++} ++ + // Carrier + + int nw_link_has_carrier(nw_link* link) { +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 3d8d397..779621b 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -31,7 +31,7 @@ nw_link* nw_link_ref(nw_link* link); + nw_link* nw_link_unref(nw_link* link); + + int nw_link_ifindex(nw_link* link); +-const char* nw_link_name(nw_link* link); ++const char* nw_link_ifname(nw_link* link); + + int nw_link_has_carrier(nw_link* link); + +diff --git a/src/networkd/links.c b/src/networkd/links.c +index 9f41034..3dd06d0 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -198,7 +198,7 @@ nw_link* nw_links_get_by_name(nw_links* links, const char* name) { + struct nw_links_entry* entry = NULL; + + STAILQ_FOREACH(entry, &links->entries, nodes) { +- const char* n = nw_link_name(entry->link); ++ const char* n = nw_link_ifname(entry->link); + + if (strcmp(name, n) == 0) + return nw_link_ref(entry->link); +-- +2.39.2 + diff --git a/network/patches/0222-networkd-ports-Keep-a-permanent-reference-to-links.patch b/network/patches/0222-networkd-ports-Keep-a-permanent-reference-to-links.patch new file mode 100644 index 000000000..cb4989442 --- /dev/null +++ b/network/patches/0222-networkd-ports-Keep-a-permanent-reference-to-links.patch @@ -0,0 +1,81 @@ +From 02801f0d507924a4efb8c462f6fc775ab5793ebc Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 11:57:48 +0000 +Subject: [PATCH 222/304] networkd: ports: Keep a permanent reference to links + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index c6c8781..3c4f0b3 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -36,6 +36,9 @@ struct nw_port { + nw_daemon* daemon; + int nrefs; + ++ // Link ++ nw_link* link; ++ + char name[IF_NAMESIZE]; + nw_port_type_t type; + +@@ -66,6 +69,8 @@ static nw_port_type_t nw_port_type_from_string(const char* s) { + } + + static void nw_port_free(nw_port* port) { ++ if (port->link) ++ nw_link_unref(port->link); + if (port->config) + nw_config_unref(port->config); + if (port->daemon) +@@ -134,6 +139,14 @@ static int nw_port_setup(nw_port* port) { + char path[PATH_MAX]; + int r; + ++ // Find the link ++ port->link = nw_daemon_get_link_by_name(port->daemon, port->name); ++ if (port->link) { ++ DEBUG("%s: Found matching link %d\n", port->name, nw_link_ifindex(port->link)); ++ } else { ++ DEBUG("%s: Could not find matching link\n", port->name); ++ } ++ + // Compose the path to the main configuration file + r = nw_path_join(path, PORT_CONFIG_DIR, port->name); + if (r) +@@ -240,7 +253,10 @@ char* nw_port_bus_path(nw_port* port) { + } + + static nw_link* nw_port_get_link(nw_port* port) { +- return nw_daemon_get_link_by_name(port->daemon, port->name); ++ if (!port->link) ++ return NULL; ++ ++ return nw_link_ref(port->link); + } + + const nw_address_t* nw_port_get_address(nw_port* port) { +@@ -248,14 +264,8 @@ const nw_address_t* nw_port_get_address(nw_port* port) { + } + + int nw_port_has_carrier(nw_port* port) { +- int has_carrier = 0; +- +- // Fetch link +- nw_link* link = nw_port_get_link(port); +- if (link) { +- has_carrier = nw_link_has_carrier(link); +- nw_link_unref(link); +- } ++ if (!port->link) ++ return 0; + +- return has_carrier; ++ return nw_link_has_carrier(port->link); + } +-- +2.39.2 + diff --git a/network/patches/0223-networkd-zones-Keep-a-permanent-reference-to-links.patch b/network/patches/0223-networkd-zones-Keep-a-permanent-reference-to-links.patch new file mode 100644 index 000000000..bafe16a5b --- /dev/null +++ b/network/patches/0223-networkd-zones-Keep-a-permanent-reference-to-links.patch @@ -0,0 +1,89 @@ +From 4e989bd539cc0aea61345156a6401e7282357d0c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 12:02:40 +0000 +Subject: [PATCH 223/304] networkd: zones: Keep a permanent reference to links + +Signed-off-by: Michael Tremer +--- + src/networkd/zone.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 8fe07c5..4fda1e5 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -25,6 +25,7 @@ + + #include "config.h" + #include "daemon.h" ++#include "link.h" + #include "logging.h" + #include "string.h" + #include "zone.h" +@@ -33,6 +34,9 @@ struct nw_zone { + nw_daemon* daemon; + int nrefs; + ++ // Link ++ nw_link* link; ++ + char name[NETWORK_ZONE_NAME_MAX_LENGTH]; + + // Configuration +@@ -66,6 +70,8 @@ static int __nw_zone_path(nw_zone* zone, char* p, const size_t length, + } + + static void nw_zone_free(nw_zone* zone) { ++ if (zone->link) ++ nw_link_unref(zone->link); + if (zone->config) + nw_config_unref(zone->config); + if (zone->daemon) +@@ -78,6 +84,14 @@ static int nw_zone_setup(nw_zone* zone) { + char path[PATH_MAX]; + int r; + ++ // Find the link ++ zone->link = nw_daemon_get_link_by_name(zone->daemon, zone->name); ++ if (zone->link) { ++ DEBUG("%s: Found matching link %d\n", zone->name, nw_link_ifindex(zone->link)); ++ } else { ++ DEBUG("%s: Could not find matching link\n", zone->name); ++ } ++ + // Compose the path to the main configuration file + r = nw_zone_path(zone, path, "%s", "settings"); + if (r) +@@ -164,22 +178,19 @@ char* nw_zone_bus_path(nw_zone* zone) { + } + + static nw_link* nw_zone_get_link(nw_zone* zone) { +- return nw_daemon_get_link_by_name(zone->daemon, zone->name); ++ if (!zone->link) ++ return NULL; ++ ++ return nw_link_ref(zone->link); + } + + // Carrier + + int nw_zone_has_carrier(nw_zone* zone) { +- int has_carrier = 0; +- +- // Fetch link +- nw_link* link = nw_zone_get_link(zone); +- if (link) { +- has_carrier = nw_link_has_carrier(link); +- nw_link_unref(link); +- } ++ if (!zone->link) ++ return 0; + +- return has_carrier; ++ return nw_link_has_carrier(zone->link); + } + + /* +-- +2.39.2 + diff --git a/network/patches/0224-networkd-config-Add-functions-to-handle-boolean-valu.patch b/network/patches/0224-networkd-config-Add-functions-to-handle-boolean-valu.patch new file mode 100644 index 000000000..4b2ad1b9b --- /dev/null +++ b/network/patches/0224-networkd-config-Add-functions-to-handle-boolean-valu.patch @@ -0,0 +1,63 @@ +From 8b0b5c6d9e99c09341fe90b1278763fd3f70b53a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 13:04:17 +0000 +Subject: [PATCH 224/304] networkd: config: Add functions to handle boolean + values + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 28 ++++++++++++++++++++++++++++ + src/networkd/config.h | 3 +++ + 2 files changed, 31 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index b3d5284..d879ace 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -368,3 +368,31 @@ int nw_config_set_int(nw_config* config, const char* key, const int value) { + + return nw_config_set(config, key, __value); + } ++ ++static const char* nw_config_true[] = { ++ "true", ++ "yes", ++ "1", ++ NULL, ++}; ++ ++int nw_config_get_bool(nw_config* config, const char* key) { ++ const char* value = nw_config_get(config, key); ++ ++ // No value indicates false ++ if (!value) ++ return 0; ++ ++ // Check if we match any known true words ++ for (const char** s = nw_config_true; *s; s++) { ++ if (strcmp(value, *s) == 0) ++ return 1; ++ } ++ ++ // No match means false ++ return 0; ++} ++ ++int nw_config_set_bool(nw_config* config, const char* key, const int value) { ++ return nw_config_set(config, key, value ? "true" : "false"); ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 041a10e..0b25f75 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -48,4 +48,7 @@ int nw_config_set(nw_config* config, const char* key, const char* value); + int nw_config_get_int(nw_config* config, const char* key, const int __default); + int nw_config_set_int(nw_config* config, const char* key, const int value); + ++int nw_config_get_bool(nw_config* config, const char* key); ++int nw_config_set_bool(nw_config* config, const char* key, const int value); ++ + #endif /* NETWORKD_CONFIG_H */ +-- +2.39.2 + diff --git a/network/patches/0225-networkd-Try-to-reconfigure-all-ports-and-zones-on-s.patch b/network/patches/0225-networkd-Try-to-reconfigure-all-ports-and-zones-on-s.patch new file mode 100644 index 000000000..8ea8c778b --- /dev/null +++ b/network/patches/0225-networkd-Try-to-reconfigure-all-ports-and-zones-on-s.patch @@ -0,0 +1,210 @@ +From b9769b09ea2943e4b212806c11f31f14f627b08f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 13:06:25 +0000 +Subject: [PATCH 225/304] networkd: Try to reconfigure all ports and zones on + startup + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 36 ++++++++++++++++++++++++++++++++++++ + src/networkd/port.c | 4 ++++ + src/networkd/port.h | 2 ++ + src/networkd/ports.c | 21 +++++++++++++++++++++ + src/networkd/ports.h | 6 ++++++ + src/networkd/zone.c | 4 ++++ + src/networkd/zone.h | 2 ++ + src/networkd/zones.c | 8 ++++++++ + src/networkd/zones.h | 2 ++ + 9 files changed, 85 insertions(+) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 925b207..c6dad91 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -291,6 +291,37 @@ static int nw_daemon_enumerate(nw_daemon* daemon) { + return 0; + } + ++static int __nw_daemon_reconfigure(sd_event_source* s, void* data) { ++ nw_daemon* daemon = (nw_daemon*)data; ++ int r; ++ ++ DEBUG("Reconfiguring...\n"); ++ ++ // Reconfigure all zones ++ r = nw_zones_reconfigure(daemon->zones); ++ if (r) ++ return r; ++ ++ // Reconfigure all ports ++ r = nw_ports_reconfigure(daemon->ports); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ ++static int nw_daemon_reconfigure(nw_daemon* daemon) { ++ int r; ++ ++ r = sd_event_add_defer(daemon->loop, NULL, __nw_daemon_reconfigure, daemon); ++ if (r) { ++ ERROR("Could not schedule re-configuration task: %m\n"); ++ return r; ++ } ++ ++ return 0; ++} ++ + static int nw_daemon_setup(nw_daemon* daemon) { + int r; + +@@ -324,6 +355,11 @@ static int nw_daemon_setup(nw_daemon* daemon) { + if (r) + return r; + ++ // (Re-)configure everything ++ r = nw_daemon_reconfigure(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 3c4f0b3..ec40830 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -263,6 +263,10 @@ const nw_address_t* nw_port_get_address(nw_port* port) { + return &port->address; + } + ++int nw_port_reconfigure(nw_port* port) { ++ return 0; // XXX TODO ++} ++ + int nw_port_has_carrier(nw_port* port) { + if (!port->link) + return 0; +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 33241ed..17c8c3c 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -46,6 +46,8 @@ char* nw_port_bus_path(nw_port* port); + + const nw_address_t* nw_port_get_address(nw_port* port); + ++int nw_port_reconfigure(nw_port* port); ++ + int nw_port_has_carrier(nw_port* port); + + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index a87ca03..87135d8 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -222,3 +222,24 @@ ERROR: + + return 1; + } ++ ++int nw_ports_walk(nw_ports* ports, nw_ports_walk_callback callback, void* data) { ++ struct nw_ports_entry* entry = NULL; ++ int r; ++ ++ STAILQ_FOREACH(entry, &ports->entries, nodes) { ++ r = callback(ports->daemon, entry->port, data); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ ++static int __nw_ports_reconfigure(nw_daemon* daemon, nw_port* port, void* data) { ++ return nw_port_reconfigure(port); ++} ++ ++int nw_ports_reconfigure(nw_ports* ports) { ++ return nw_ports_walk(ports, __nw_ports_reconfigure, NULL); ++} +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +index 40c9ae1..68ae532 100644 +--- a/src/networkd/ports.h ++++ b/src/networkd/ports.h +@@ -23,6 +23,8 @@ + + typedef struct nw_ports nw_ports; + ++typedef int (*nw_ports_walk_callback)(nw_daemon* daemon, nw_port* port, void* data); ++ + #include "daemon.h" + + int nw_ports_create(nw_ports** ports, nw_daemon* daemon); +@@ -38,4 +40,8 @@ struct nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name); + + int nw_ports_bus_paths(nw_ports* ports, char*** paths); + ++int nw_ports_walk(nw_ports* ports, nw_ports_walk_callback callback, void* data); ++ ++int nw_ports_reconfigure(nw_ports* ports); ++ + #endif /* NETWORKD_PORTS_H */ +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 4fda1e5..9daa0d3 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -184,6 +184,10 @@ static nw_link* nw_zone_get_link(nw_zone* zone) { + return nw_link_ref(zone->link); + } + ++int nw_zone_reconfigure(nw_zone* zone) { ++ return 0; // XXX TODO ++} ++ + // Carrier + + int nw_zone_has_carrier(nw_zone* zone) { +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index f5a2355..591e467 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -41,6 +41,8 @@ const char* nw_zone_name(nw_zone* zone); + + char* nw_zone_bus_path(nw_zone* zone); + ++int nw_zone_reconfigure(nw_zone* zone); ++ + int nw_zone_has_carrier(nw_zone* zone); + + /* +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 521da51..84a6673 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -252,3 +252,11 @@ int nw_zones_walk(nw_zones* zones, nw_zones_walk_callback callback, void* data) + + return 0; + } ++ ++static int __nw_zones_reconfigure(nw_daemon* daemon, nw_zone* zone, void* data) { ++ return nw_zone_reconfigure(zone); ++} ++ ++int nw_zones_reconfigure(nw_zones* zones) { ++ return nw_zones_walk(zones, __nw_zones_reconfigure, NULL); ++} +diff --git a/src/networkd/zones.h b/src/networkd/zones.h +index 019955e..ad39fd2 100644 +--- a/src/networkd/zones.h ++++ b/src/networkd/zones.h +@@ -44,4 +44,6 @@ int nw_zones_bus_paths(nw_zones* zones, char*** paths); + + int nw_zones_walk(nw_zones* zones, nw_zones_walk_callback callback, void* data); + ++int nw_zones_reconfigure(nw_zones* zones); ++ + #endif /* NETWORKD_ZONES_H */ +-- +2.39.2 + diff --git a/network/patches/0226-networkd-Implement-deleting-links.patch b/network/patches/0226-networkd-Implement-deleting-links.patch new file mode 100644 index 000000000..ba7e4160e --- /dev/null +++ b/network/patches/0226-networkd-Implement-deleting-links.patch @@ -0,0 +1,147 @@ +From 371b836adc35d69cdd7a4a71144ec5e0f7ef42e1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 13:33:13 +0000 +Subject: [PATCH 226/304] networkd: Implement deleting links + +This is a little bit rough but generally does work. + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ + src/networkd/link.h | 2 ++ + src/networkd/port.c | 19 ++++++++++++- + 3 files changed, 86 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 0fb388b..949d0d8 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -41,6 +41,11 @@ struct nw_link { + // Interface Name + char ifname[IFNAMSIZ]; + ++ enum nw_link_state { ++ NW_LINK_UNKNOWN = 0, ++ NW_LINK_DESTROYED, ++ } state; ++ + // MTU + uint32_t mtu; + uint32_t min_mtu; +@@ -94,6 +99,16 @@ nw_link* nw_link_unref(nw_link* link) { + return NULL; + } + ++/* ++ This is a helper function for when we pass a reference to the event loop ++ it will have to dereference the link instance later. ++*/ ++static void __nw_link_unref(void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ nw_link_unref(link); ++} ++ + int nw_link_ifindex(nw_link* link) { + return link->ifindex; + } +@@ -370,3 +385,54 @@ ERROR: + + return r; + } ++ ++static int __nw_link_destroy(sd_netlink* rtnl, sd_netlink_message* m, void* data) { ++ nw_link* link = (nw_link*)data; ++ int r; ++ ++ // Check if the operation was successful ++ r = sd_netlink_message_get_errno(m); ++ if (r < 0) { ++ ERROR("Could not remove link %d: %m\n", link->ifindex); ++ // XXX We should extract the error message ++ ++ return 0; ++ } ++ ++ // Mark this link as destroyed ++ link->state = NW_LINK_DESTROYED; ++ ++ return 0; ++} ++ ++int nw_link_destroy(nw_link* link) { ++ sd_netlink_message* m = NULL; ++ int r; ++ ++ sd_netlink* rtnl = nw_daemon_get_rtnl(link->daemon); ++ if (!rtnl) ++ return 1; ++ ++ DEBUG("Destroying link %d\n", link->ifindex); ++ ++ // Create a new message ++ r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, link->ifindex); ++ if (r < 0) { ++ ERROR("Could not allocate RTM_DELLINK message: %m\n"); ++ goto ERROR; ++ } ++ ++ // Send the message ++ r = sd_netlink_call_async(rtnl, NULL, m, __nw_link_destroy, ++ __nw_link_unref, nw_link_ref(link), -1, NULL); ++ if (r < 0) { ++ ERROR("Could not send rtnetlink message: %m\n"); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (m) ++ sd_netlink_message_unref(m); ++ ++ return r; ++} +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 779621b..58a825a 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -37,4 +37,6 @@ int nw_link_has_carrier(nw_link* link); + + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + ++int nw_link_destroy(nw_link* link); ++ + #endif /* NETWORKD_LINK_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index ec40830..7d02305 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -263,8 +263,25 @@ const nw_address_t* nw_port_get_address(nw_port* port) { + return &port->address; + } + ++static int nw_port_is_disabled(nw_port* port) { ++ return nw_config_get_bool(port->config, "DISABLED"); ++} ++ + int nw_port_reconfigure(nw_port* port) { +- return 0; // XXX TODO ++ int r; ++ ++ // If the port is disabled, we will try to destroy it ++ if (nw_port_is_disabled(port)) { ++ if (port->link) { ++ r = nw_link_destroy(port->link); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++ } ++ ++ // XXX TODO + } + + int nw_port_has_carrier(nw_port* port) { +-- +2.39.2 + diff --git a/network/patches/0227-networkd-Automatically-reference-dereference-links-t.patch b/network/patches/0227-networkd-Automatically-reference-dereference-links-t.patch new file mode 100644 index 000000000..465c14c07 --- /dev/null +++ b/network/patches/0227-networkd-Automatically-reference-dereference-links-t.patch @@ -0,0 +1,368 @@ +From 611d4aca5d48567a7a7ddb0dd3446a97e91aad54 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 14:15:01 +0000 +Subject: [PATCH 227/304] networkd: Automatically reference/dereference links + to zones/ports + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 7 ++++ + src/networkd/daemon.h | 1 + + src/networkd/link.c | 10 ++++++ + src/networkd/links.c | 6 ++++ + src/networkd/port.c | 82 +++++++++++++++++++++++++++++++++++-------- + src/networkd/port.h | 3 ++ + src/networkd/zone.c | 78 +++++++++++++++++++++++++++++++++------- + src/networkd/zone.h | 3 ++ + 8 files changed, 164 insertions(+), 26 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index c6dad91..02ca8e2 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -540,6 +540,13 @@ nw_ports* nw_daemon_ports(nw_daemon* daemon) { + return nw_ports_ref(daemon->ports); + } + ++int nw_daemon_ports_walk(nw_daemon* daemon, nw_ports_walk_callback callback, void* data) { ++ if (!daemon->ports) ++ return 0; ++ ++ return nw_ports_walk(daemon->ports, callback, data); ++} ++ + nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name) { + if (!daemon->ports) + return NULL; +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index ce9a660..a14d33b 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -60,6 +60,7 @@ nw_link* nw_daemon_get_link_by_name(nw_daemon* daemon, const char* name); + Ports + */ + nw_ports* nw_daemon_ports(nw_daemon* daemon); ++int nw_daemon_ports_walk(nw_daemon* daemon, nw_ports_walk_callback callback, void* data); + nw_port* nw_daemon_get_port_by_name(nw_daemon* daemon, const char* name); + + /* +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 949d0d8..09b9a62 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -114,6 +114,10 @@ int nw_link_ifindex(nw_link* link) { + } + + const char* nw_link_ifname(nw_link* link) { ++ // Return NULL if name isn't set ++ if (!*link->ifname) ++ return NULL; ++ + return link->ifname; + } + +@@ -154,6 +158,12 @@ static int nw_link_update_ifname(nw_link* link, sd_netlink_message* message) { + + DEBUG("Link %d has been renamed to '%s'\n", link->ifindex, link->ifname); + ++ // Assign link to ports ++ nw_daemon_ports_walk(link->daemon, __nw_port_set_link, link); ++ ++ // Assign link to zones ++ nw_daemon_zones_walk(link->daemon, __nw_zone_set_link, link); ++ + return 0; + } + +diff --git a/src/networkd/links.c b/src/networkd/links.c +index 3dd06d0..40926f3 100644 +--- a/src/networkd/links.c ++++ b/src/networkd/links.c +@@ -141,6 +141,12 @@ void nw_links_drop_link(nw_links* links, struct nw_link* link) { + + STAILQ_REMOVE(&links->entries, entry, nw_links_entry, nodes); + links->num--; ++ ++ // Drop link from all ports ++ nw_daemon_ports_walk(links->daemon, __nw_port_drop_link, link); ++ ++ // Drop link from all zones ++ nw_daemon_zones_walk(links->daemon, __nw_zone_drop_link, link); + } + + int nw_links_enumerate(nw_links* links) { +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 7d02305..37ab3a7 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -135,39 +135,65 @@ static nw_port_type_t nw_port_setup_type(nw_port* port) { + return nw_port_type_from_string(type); + } + ++static int nw_port_set_link(nw_port* port, nw_link* link) { ++ // Do nothing if the same link is being re-assigned ++ if (port->link == link) ++ return 0; ++ ++ // Dereference the former link if set ++ if (port->link) ++ nw_link_unref(port->link); ++ ++ // Store the new link ++ if (link) { ++ port->link = nw_link_ref(link); ++ ++ DEBUG("Port %s: Assigned link %d\n", port->name, nw_link_ifindex(port->link)); ++ ++ // Or clear the pointer if no link has been provided ++ } else { ++ port->link = NULL; ++ ++ DEBUG("Port %s: Removed link\n", port->name); ++ } ++ ++ return 0; ++} ++ + static int nw_port_setup(nw_port* port) { ++ nw_link* link = NULL; + char path[PATH_MAX]; + int r; + + // Find the link +- port->link = nw_daemon_get_link_by_name(port->daemon, port->name); +- if (port->link) { +- DEBUG("%s: Found matching link %d\n", port->name, nw_link_ifindex(port->link)); +- } else { +- DEBUG("%s: Could not find matching link\n", port->name); ++ link = nw_daemon_get_link_by_name(port->daemon, port->name); ++ if (link) { ++ r = nw_port_set_link(port, link); ++ if (r) ++ goto ERROR; + } + + // Compose the path to the main configuration file + r = nw_path_join(path, PORT_CONFIG_DIR, port->name); + if (r) +- return r; ++ goto ERROR; + + // Initialize the configuration + r = nw_config_create(&port->config, path); + if (r) +- return r; ++ goto ERROR; + + // Determine type + port->type = nw_port_setup_type(port); + if (!port->type) { + ERROR("Could not determine type of port %s\n", port->name); +- return 0; ++ goto ERROR; + } + + // Perform some common initialization + r = nw_port_setup_common(port); + if (r) +- return r; ++ goto ERROR; + + // Call any custom initialization + switch (port->type) { +@@ -177,7 +203,11 @@ static int nw_port_setup(nw_port* port) { + break; + } + +- return 0; ++ERROR: ++ if (link) ++ nw_link_unref(link); ++ ++ return r; + } + + int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name) { +@@ -252,11 +282,35 @@ char* nw_port_bus_path(nw_port* port) { + return p; + } + +-static nw_link* nw_port_get_link(nw_port* port) { +- if (!port->link) +- return NULL; ++int __nw_port_set_link(nw_daemon* daemon, nw_port* port, void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ // Fetch the link name ++ const char* ifname = nw_link_ifname(link); ++ if (!ifname) { ++ ERROR("Link does not have a name set\n"); ++ return 1; ++ } ++ ++ // Set link if the name matches ++ if (strcmp(port->name, ifname) == 0) ++ return nw_port_set_link(port, link); ++ ++ // If we have the link set but the name did not match, we will remove it ++ else if (port->link == link) ++ return nw_port_set_link(port, NULL); ++ ++ return 0; ++} ++ ++int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data) { ++ nw_link* link = (nw_link*)data; + +- return nw_link_ref(port->link); ++ // Drop the link if it matches ++ if (port->link == link) ++ return nw_port_set_link(port, NULL); ++ ++ return 0; + } + + const nw_address_t* nw_port_get_address(nw_port* port) { +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 17c8c3c..3981c82 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -44,6 +44,9 @@ const char* nw_port_name(nw_port* port); + + char* nw_port_bus_path(nw_port* port); + ++int __nw_port_set_link(nw_daemon* daemon, nw_port* port, void* data); ++int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data); ++ + const nw_address_t* nw_port_get_address(nw_port* port); + + int nw_port_reconfigure(nw_port* port); +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 9daa0d3..00ab017 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -80,29 +80,59 @@ static void nw_zone_free(nw_zone* zone) { + free(zone); + } + ++static int nw_zone_set_link(nw_zone* zone, nw_link* link) { ++ // Do nothing if the same link is being re-assigned ++ if (zone->link == link) ++ return 0; ++ ++ // Dereference the former link if set ++ if (zone->link) ++ nw_link_unref(zone->link); ++ ++ // Store the new link ++ if (link) { ++ zone->link = nw_link_ref(link); ++ ++ DEBUG("Zone %s: Assigned link %d\n", zone->name, nw_link_ifindex(zone->link)); ++ ++ // Or clear the pointer if no link has been provided ++ } else { ++ zone->link = NULL; ++ ++ DEBUG("Zone %s: Removed link\n", zone->name); ++ } ++ ++ return 0; ++} ++ + static int nw_zone_setup(nw_zone* zone) { ++ nw_link* link = NULL; + char path[PATH_MAX]; + int r; + + // Find the link +- zone->link = nw_daemon_get_link_by_name(zone->daemon, zone->name); +- if (zone->link) { +- DEBUG("%s: Found matching link %d\n", zone->name, nw_link_ifindex(zone->link)); +- } else { +- DEBUG("%s: Could not find matching link\n", zone->name); ++ link = nw_daemon_get_link_by_name(zone->daemon, zone->name); ++ if (link) { ++ r = nw_zone_set_link(zone, link); ++ if (r) ++ goto ERROR; + } + + // Compose the path to the main configuration file + r = nw_zone_path(zone, path, "%s", "settings"); + if (r) +- return r; ++ goto ERROR; + + // Initialize the configuration + r = nw_config_create(&zone->config, path); + if (r) +- return r; ++ goto ERROR; + +- return 0; ++ERROR: ++ if (link) ++ nw_link_unref(link); ++ ++ return r; + } + + int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) { +@@ -177,11 +207,35 @@ char* nw_zone_bus_path(nw_zone* zone) { + return p; + } + +-static nw_link* nw_zone_get_link(nw_zone* zone) { +- if (!zone->link) +- return NULL; ++int __nw_zone_set_link(nw_daemon* daemon, nw_zone* zone, void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ // Fetch the link name ++ const char* ifname = nw_link_ifname(link); ++ if (!ifname) { ++ ERROR("Link does not have a name set\n"); ++ return 1; ++ } ++ ++ // Set link if the name matches ++ if (strcmp(zone->name, ifname) == 0) ++ return nw_zone_set_link(zone, link); ++ ++ // If we have the link set but the name did not match, we will remove it ++ else if (zone->link == link) ++ return nw_zone_set_link(zone, NULL); + +- return nw_link_ref(zone->link); ++ return 0; ++} ++ ++int __nw_zone_drop_link(nw_daemon* daemon, nw_zone* zone, void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ // Drop the link if it matches ++ if (zone->link == link) ++ return nw_zone_set_link(zone, NULL); ++ ++ return 0; + } + + int nw_zone_reconfigure(nw_zone* zone) { +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 591e467..ad348d7 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -41,6 +41,9 @@ const char* nw_zone_name(nw_zone* zone); + + char* nw_zone_bus_path(nw_zone* zone); + ++int __nw_zone_set_link(nw_daemon* daemon, nw_zone* zone, void* data); ++int __nw_zone_drop_link(nw_daemon* daemon, nw_zone* zone, void* data); ++ + int nw_zone_reconfigure(nw_zone* zone); + + int nw_zone_has_carrier(nw_zone* zone); +-- +2.39.2 + diff --git a/network/patches/0228-networkd-ports-Create-dummy-function-to-create-links.patch b/network/patches/0228-networkd-ports-Create-dummy-function-to-create-links.patch new file mode 100644 index 000000000..3e5f06ff3 --- /dev/null +++ b/network/patches/0228-networkd-ports-Create-dummy-function-to-create-links.patch @@ -0,0 +1,46 @@ +From 96b1b84d857124d5b145859e25e3bfe7572eeb73 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 14:29:22 +0000 +Subject: [PATCH 228/304] networkd: ports: Create dummy function to create + links + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 37ab3a7..5694024 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -321,6 +321,10 @@ static int nw_port_is_disabled(nw_port* port) { + return nw_config_get_bool(port->config, "DISABLED"); + } + ++static int nw_port_create_link(nw_port* port) { ++ return 0; // XXX TODO ++} ++ + int nw_port_reconfigure(nw_port* port) { + int r; + +@@ -335,7 +339,16 @@ int nw_port_reconfigure(nw_port* port) { + return 0; + } + ++ // If there is no link, we will try to create it ++ if (!port->link) { ++ r = nw_port_create_link(port); ++ if (r) ++ return r; ++ } ++ + // XXX TODO ++ ++ return 0; + } + + int nw_port_has_carrier(nw_port* port) { +-- +2.39.2 + diff --git a/network/patches/0229-networkd-daemon-Correctly-store-reference-to-bus.patch b/network/patches/0229-networkd-daemon-Correctly-store-reference-to-bus.patch new file mode 100644 index 000000000..fbf54fce6 --- /dev/null +++ b/network/patches/0229-networkd-daemon-Correctly-store-reference-to-bus.patch @@ -0,0 +1,157 @@ +From 442b2fc2a34e8f6b7343d616d07c1aecb667a652 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 17:35:48 +0000 +Subject: [PATCH 229/304] networkd: daemon: Correctly store reference to bus + +Signed-off-by: Michael Tremer +--- + src/networkd/bus.c | 30 +++++++++++++++++------------- + src/networkd/bus.h | 2 +- + src/networkd/daemon.c | 2 +- + 3 files changed, 19 insertions(+), 15 deletions(-) + +diff --git a/src/networkd/bus.c b/src/networkd/bus.c +index 1daa035..8158c84 100644 +--- a/src/networkd/bus.c ++++ b/src/networkd/bus.c +@@ -36,18 +36,19 @@ static int nw_bus_on_connect(sd_bus_message* m, void* data, sd_bus_error* error) + return 0; + } + +-int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon) { ++int nw_bus_connect(sd_bus** bus, sd_event* loop, nw_daemon* daemon) { ++ sd_bus* b = NULL; + int r; + + // Create a bus object +- r = sd_bus_new(&bus); ++ r = sd_bus_new(&b); + if (r < 0) { + ERROR("Could not allocate a bus object: %s\n", strerror(-r)); + return 1; + } + + // Set description +- r = sd_bus_set_description(bus, NETWORKD_BUS_DESCRIPTION); ++ r = sd_bus_set_description(b, NETWORKD_BUS_DESCRIPTION); + if (r < 0) { + ERROR("Could not set bus description: %s\n", strerror(-r)); + return 1; +@@ -58,21 +59,21 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon) { + address = DEFAULT_SYSTEM_BUS_ADDRESS; + + // Set bus address +- r = sd_bus_set_address(bus, address); ++ r = sd_bus_set_address(b, address); + if (r < 0) { + ERROR("Could not set bus address: %s\n", strerror(-r)); + return 1; + } + + // Set bus client +- r = sd_bus_set_bus_client(bus, 1); ++ r = sd_bus_set_bus_client(b, 1); + if (r < 0) { + ERROR("Could not set bus client: %s\n", strerror(-r)); + return 1; + } + + // Request some credentials for all messages +- r = sd_bus_negotiate_creds(bus, 1, ++ r = sd_bus_negotiate_creds(b, 1, + SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); + if (r < 0) { + ERROR("Could not negotiate creds: %s\n", strerror(-r)); +@@ -80,53 +81,56 @@ int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon) { + } + + // Automatically bind when the socket is available +- r = sd_bus_set_watch_bind(bus, 1); ++ r = sd_bus_set_watch_bind(b, 1); + if (r < 0) { + ERROR("Could not watch socket: %s\n", strerror(-r)); + return 1; + } + + // Emit a connected signal when we are connected +- r = sd_bus_set_connected_signal(bus, 1); ++ r = sd_bus_set_connected_signal(b, 1); + if (r < 0) { + ERROR("Could not enable sending a connect signal: %s\n", strerror(-r)); + return 1; + } + + // Connect to the bus +- r = sd_bus_start(bus); ++ r = sd_bus_start(b); + if (r < 0) { + ERROR("Could not connect to bus: %s\n", strerror(-r)); + return 1; + } + + // Register the implementation +- r = nw_bus_register_implementation(bus, &daemon_bus_impl, daemon); ++ r = nw_bus_register_implementation(b, &daemon_bus_impl, daemon); + if (r) + return r; + + // Request interface name +- r = sd_bus_request_name_async(bus, NULL, "org.ipfire.network1", 0, NULL, NULL); ++ r = sd_bus_request_name_async(b, NULL, "org.ipfire.network1", 0, NULL, NULL); + if (r < 0) { + ERROR("Could not request bus name: %s\n", strerror(-r)); + return 1; + } + + // Attach the event loop +- r = sd_bus_attach_event(bus, loop, 0); ++ r = sd_bus_attach_event(b, loop, 0); + if (r < 0) { + ERROR("Could not attach bus to event loop: %s\n", strerror(-r)); + return 1; + } + + // Request receiving a connect signal +- r = sd_bus_match_signal_async(bus, NULL, "org.freedesktop.DBus.Local", ++ r = sd_bus_match_signal_async(b, NULL, "org.freedesktop.DBus.Local", + NULL, "org.freedesktop.DBus.Local", "Connected", nw_bus_on_connect, NULL, NULL); + if (r < 0) { + ERROR("Could not request match on Connected signal: %s\n", strerror(-r)); + return 1; + } + ++ // Return reference ++ *bus = b; ++ + return 0; + } + +diff --git a/src/networkd/bus.h b/src/networkd/bus.h +index 05b4c63..29b1b4a 100644 +--- a/src/networkd/bus.h ++++ b/src/networkd/bus.h +@@ -30,7 +30,7 @@ + + #include "daemon.h" + +-int nw_bus_connect(sd_bus* bus, sd_event* loop, nw_daemon* daemon); ++int nw_bus_connect(sd_bus** bus, sd_event* loop, nw_daemon* daemon); + + struct nw_bus_vtable_pair { + const sd_bus_vtable* vtable; +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 02ca8e2..c8e65f4 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -341,7 +341,7 @@ static int nw_daemon_setup(nw_daemon* daemon) { + return r; + + // Connect to the system bus +- r = nw_bus_connect(daemon->bus, daemon->loop, daemon); ++ r = nw_bus_connect(&daemon->bus, daemon->loop, daemon); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0230-networkd-Collect-stats-regulary-and-emit-them-on-dbu.patch b/network/patches/0230-networkd-Collect-stats-regulary-and-emit-them-on-dbu.patch new file mode 100644 index 000000000..34057f31b --- /dev/null +++ b/network/patches/0230-networkd-Collect-stats-regulary-and-emit-them-on-dbu.patch @@ -0,0 +1,667 @@ +From 15240e0819685c30a4955ae161374b5a3fc9d313 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 14 Apr 2023 17:43:12 +0000 +Subject: [PATCH 230/304] networkd: Collect stats regulary and emit them on + dbus + +This is useful for us monitoring interface throughput (e.g. in +collecty). + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/daemon.c | 44 ++++++++ + src/networkd/daemon.h | 6 + + src/networkd/link.c | 81 ++++++++++++++ + src/networkd/link.h | 6 + + src/networkd/port.c | 31 +++++- + src/networkd/port.h | 5 + + src/networkd/stats-collector.c | 197 +++++++++++++++++++++++++++++++++ + src/networkd/stats-collector.h | 37 +++++++ + src/networkd/zone.c | 30 +++++ + src/networkd/zone.h | 6 + + 11 files changed, 444 insertions(+), 1 deletion(-) + create mode 100644 src/networkd/stats-collector.c + create mode 100644 src/networkd/stats-collector.h + +diff --git a/Makefile.am b/Makefile.am +index 80a7236..22d90d4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -332,6 +332,8 @@ dist_networkd_SOURCES = \ + src/networkd/port.h \ + src/networkd/port-bus.c \ + src/networkd/port-bus.h \ ++ src/networkd/stats-collector.c \ ++ src/networkd/stats-collector.h \ + src/networkd/string.h \ + src/networkd/util.c \ + src/networkd/util.h \ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index c8e65f4..749a70b 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -35,6 +35,7 @@ + #include "links.h" + #include "logging.h" + #include "ports.h" ++#include "stats-collector.h" + #include "zone.h" + #include "zones.h" + +@@ -67,6 +68,8 @@ struct nw_daemon { + // Ports + nw_ports* ports; + ++ // Stats Collector ++ sd_event_source* stats_collector_event; + }; + + static int __nw_daemon_terminate(sd_event_source* source, const struct signalfd_siginfo* si, +@@ -322,6 +325,33 @@ static int nw_daemon_reconfigure(nw_daemon* daemon) { + return 0; + } + ++static int nw_daemon_starts_stats_collector(nw_daemon* daemon) { ++ sd_event_source* s = NULL; ++ int r; ++ ++ // Register the stats collector main function ++ r = sd_event_add_time_relative(daemon->loop, &s, CLOCK_MONOTONIC, 0, 0, ++ nw_stats_collector, daemon); ++ if (r < 0) { ++ ERROR("Could not start the stats collector: %m\n"); ++ goto ERROR; ++ } ++ ++ // Keep calling the stats collector for forever ++ r = sd_event_source_set_enabled(s, SD_EVENT_ON); ++ if (r < 0) ++ goto ERROR; ++ ++ // Keep a reference to the event source ++ daemon->stats_collector_event = sd_event_source_ref(s); ++ ++ERROR: ++ if (s) ++ sd_event_source_unref(s); ++ ++ return r; ++} ++ + static int nw_daemon_setup(nw_daemon* daemon) { + int r; + +@@ -360,6 +390,11 @@ static int nw_daemon_setup(nw_daemon* daemon) { + if (r) + return r; + ++ // Start the stats collector ++ r = nw_daemon_starts_stats_collector(daemon); ++ if (r) ++ return r; ++ + return 0; + } + +@@ -404,6 +439,8 @@ static void nw_daemon_free(nw_daemon* daemon) { + // Cleanup common objects + nw_daemon_cleanup(daemon); + ++ if (daemon->stats_collector_event) ++ sd_event_source_unref(daemon->stats_collector_event); + if (daemon->bus) + sd_bus_unref(daemon->bus); + if (daemon->loop) +@@ -498,6 +535,13 @@ int nw_daemon_save(nw_daemon* daemon) { + return 0; + } + ++/* ++ Bus ++*/ ++sd_bus* nw_daemon_get_bus(nw_daemon* daemon) { ++ return daemon->bus; ++} ++ + /* + Netlink + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index a14d33b..74e19e6 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -21,6 +21,7 @@ + #ifndef NETWORKD_DAEMON_H + #define NETWORKD_DAEMON_H + ++#include + #include + + typedef struct nw_daemon nw_daemon; +@@ -43,6 +44,11 @@ int nw_daemon_reload(nw_daemon* daemon); + + int nw_daemon_save(nw_daemon* daemon); + ++/* ++ Bus ++*/ ++sd_bus* nw_daemon_get_bus(nw_daemon* daemon); ++ + /* + Netlink + */ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 09b9a62..1edf20d 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -19,6 +19,7 @@ + #############################################################################*/ + + #include ++#include + #include + #include + #include +@@ -46,6 +47,9 @@ struct nw_link { + NW_LINK_DESTROYED, + } state; + ++ // Stats ++ struct rtnl_link_stats64 stats64; ++ + // MTU + uint32_t mtu; + uint32_t min_mtu; +@@ -121,6 +125,83 @@ const char* nw_link_ifname(nw_link* link) { + return link->ifname; + } + ++// Stats ++ ++const struct rtnl_link_stats64* nw_link_get_stats64(nw_link* link) { ++ return &link->stats64; ++} ++ ++static int nw_link_call_getlink(nw_link* link, ++ int (*callback)(sd_netlink* rtnl, sd_netlink_message* m, void* data)) { ++ sd_netlink_message* m = NULL; ++ int r; ++ ++ sd_netlink* rtnl = nw_daemon_get_rtnl(link->daemon); ++ if (!rtnl) ++ return 1; ++ ++ // Create a new message ++ r = sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, link->ifindex); ++ if (r < 0) { ++ ERROR("Could not allocate RTM_GETLINK message: %m\n"); ++ goto ERROR; ++ } ++ ++ // Send the message ++ r = sd_netlink_call_async(rtnl, NULL, m, callback, ++ __nw_link_unref, nw_link_ref(link), -1, NULL); ++ if (r < 0) { ++ ERROR("Could not send rtnetlink message: %m\n"); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (m) ++ sd_netlink_message_unref(m); ++ ++ return r; ++} ++ ++static int __nw_link_update_stats(sd_netlink* rtnl, sd_netlink_message* m, void* data) { ++ nw_link* link = (nw_link*)data; ++ int r; ++ ++ // Fetch the stats ++ r = sd_netlink_message_read(m, IFLA_STATS64, sizeof(link->stats64), &link->stats64); ++ if (r < 0) ++ return r; ++ ++ DEBUG("Link %d: Stats updated\n", link->ifindex); ++ ++ // Log stats ++ DEBUG(" Packets : RX: %12llu, TX: %12llu\n", ++ link->stats64.rx_packets, link->stats64.tx_packets); ++ DEBUG(" Bytes : RX: %12llu, TX: %12llu\n", ++ link->stats64.rx_bytes, link->stats64.tx_bytes); ++ DEBUG(" Errors : RX: %12llu, TX: %12llu\n", ++ link->stats64.rx_errors, link->stats64.tx_errors); ++ DEBUG(" Dropped : RX: %12llu, TX: %12llu\n", ++ link->stats64.rx_dropped, link->stats64.rx_dropped); ++ DEBUG(" Multicast : %llu\n", link->stats64.multicast); ++ DEBUG(" Collisions : %llu\n", link->stats64.collisions); ++ ++ // Notify ports that stats have been updated ++ r = nw_daemon_ports_walk(link->daemon, __nw_port_update_stats, link); ++ if (r) ++ return r; ++ ++ // Notify zones that stats have been updated ++ r = nw_daemon_zones_walk(link->daemon, __nw_zone_update_stats, link); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ ++int nw_link_update_stats(nw_link* link) { ++ return nw_link_call_getlink(link, __nw_link_update_stats); ++} ++ + // Carrier + + int nw_link_has_carrier(nw_link* link) { +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 58a825a..2bab47c 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_LINK_H + #define NETWORKD_LINK_H + ++#include ++ + typedef struct nw_link nw_link; + + #include "daemon.h" +@@ -33,6 +35,10 @@ nw_link* nw_link_unref(nw_link* link); + int nw_link_ifindex(nw_link* link); + const char* nw_link_ifname(nw_link* link); + ++// Stats ++const struct rtnl_link_stats64* nw_link_get_stats64(nw_link* link); ++int nw_link_update_stats(nw_link* link); ++ + int nw_link_has_carrier(nw_link* link); + + int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 5694024..7638c7b 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -29,8 +29,9 @@ + #include "config.h" + #include "link.h" + #include "logging.h" +-#include "string.h" + #include "port.h" ++#include "stats-collector.h" ++#include "string.h" + + struct nw_port { + nw_daemon* daemon; +@@ -357,3 +358,31 @@ int nw_port_has_carrier(nw_port* port) { + + return nw_link_has_carrier(port->link); + } ++ ++/* ++ Stats ++*/ ++ ++const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port) { ++ if (!port->link) ++ return NULL; ++ ++ return nw_link_get_stats64(port->link); ++} ++ ++int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ // Emit stats if link matches ++ if (port->link == link) ++ return nw_stats_collector_emit_port_stats(daemon, port); ++ ++ return 0; ++} ++ ++int nw_port_update_stats(nw_port* port) { ++ if (port->link) ++ return nw_link_update_stats(port->link); ++ ++ return 0; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 3981c82..9dcd6c2 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -53,4 +53,9 @@ int nw_port_reconfigure(nw_port* port); + + int nw_port_has_carrier(nw_port* port); + ++// Stats ++const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); ++int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); ++int nw_port_update_stats(nw_port* port); ++ + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/stats-collector.c b/src/networkd/stats-collector.c +new file mode 100644 +index 0000000..c10602e +--- /dev/null ++++ b/src/networkd/stats-collector.c +@@ -0,0 +1,197 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include ++#include ++ ++#include "logging.h" ++#include "port.h" ++#include "stats-collector.h" ++#include "zone.h" ++ ++static int __nw_stats_collector_port(nw_daemon* daemon, nw_port* port, void* data) { ++ return nw_port_update_stats(port); ++} ++ ++static int __nw_stats_collector_zone(nw_daemon* daemon, nw_zone* zone, void* data) { ++ return nw_zone_update_stats(zone); ++} ++ ++int nw_stats_collector(sd_event_source* s, long unsigned int usec, void* data) { ++ nw_daemon* daemon = (nw_daemon*)data; ++ int r; ++ ++ DEBUG("Stats collector has been called\n"); ++ ++ // Schedule the next call ++ r = sd_event_source_set_time(s, usec + NW_STATS_COLLECTOR_INTERVAL); ++ if (r < 0) ++ return r; ++ ++ // Ports ++ r = nw_daemon_ports_walk(daemon, __nw_stats_collector_port, NULL); ++ if (r) ++ return r; ++ ++ // Zones ++ r = nw_daemon_zones_walk(daemon, __nw_stats_collector_zone, NULL); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ ++static int nw_stats_collector_emit_stats(nw_daemon* daemon, const char* path, ++ const char* interface, const char* member, const struct rtnl_link_stats64* stats64) { ++ sd_bus_message* m = NULL; ++ int r; ++ ++ sd_bus* bus = nw_daemon_get_bus(daemon); ++ ++ // Allocate a new message ++ r = sd_bus_message_new_signal(bus, &m, path, interface, member); ++ if (r < 0) { ++ errno = -r; ++ ERROR("Could not allocate bus message: %m\n"); ++ goto ERROR; ++ } ++ ++ // Open the container ++ r = sd_bus_message_open_container(m, 'a', "{st}"); ++ if (r < 0) { ++ ERROR("Could not open container: %m\n"); ++ goto ERROR; ++ } ++ ++ const struct stats64_entry { ++ const char* key; ++ uint64_t value; ++ } entries[] = { ++ { "rx-packets", stats64->rx_packets }, ++ { "tx-packets", stats64->tx_packets }, ++ { "rx-bytes", stats64->rx_bytes }, ++ { "tx-bytes", stats64->tx_bytes }, ++ { "rx-errors", stats64->rx_errors }, ++ { "tx-errors", stats64->tx_errors }, ++ { "rx-dropped", stats64->rx_dropped }, ++ { "tx-dropped", stats64->tx_dropped }, ++ { "multicast", stats64->multicast }, ++ { "collisions", stats64->collisions }, ++ ++ // Detailed RX errors ++ { "rx-length-errors", stats64->rx_length_errors }, ++ { "rx-over-errors", stats64->rx_over_errors }, ++ { "rx-crc-errors", stats64->rx_crc_errors }, ++ { "rx-frame-errors", stats64->rx_frame_errors }, ++ { "rx-fifo-errors", stats64->rx_fifo_errors }, ++ { "rx-missed-errors", stats64->rx_missed_errors }, ++ ++ // Detailed TX errors ++ { "tx-aborted-errors", stats64->tx_aborted_errors }, ++ { "tx-carrier-errors", stats64->tx_carrier_errors }, ++ { "tx-fifo-errors", stats64->tx_fifo_errors }, ++ { "tx-heartbeat-errors", stats64->tx_heartbeat_errors }, ++ { "tx-window-errors", stats64->tx_window_errors }, ++ ++ { NULL }, ++ }; ++ ++ for (const struct stats64_entry* e = entries; e->key; e++) { ++ r = sd_bus_message_append(m, "{st}", e->key, e->value); ++ if (r < 0) { ++ ERROR("Could not set stat value: %m\n"); ++ goto ERROR; ++ } ++ } ++ ++ // Close the container ++ r = sd_bus_message_close_container(m); ++ if (r < 0) { ++ ERROR("Could not close container: %m\n"); ++ goto ERROR; ++ } ++ ++ // Emit the signal ++ r = sd_bus_send(bus, m, NULL); ++ if (r < 0) { ++ ERROR("Could not emit the stats signal for %s: %m\n", path); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (m) ++ sd_bus_message_unref(m); ++ ++ return r; ++} ++ ++int nw_stats_collector_emit_port_stats(nw_daemon* daemon, nw_port* port) { ++ const struct rtnl_link_stats64* stats64 = NULL; ++ char* path = NULL; ++ int r; ++ ++ // Fetch the bus path ++ path = nw_port_bus_path(port); ++ ++ // Fetch the stats ++ stats64 = nw_port_get_stats64(port); ++ ++ // Emit the stats ++ r = nw_stats_collector_emit_stats(daemon, path, ++ "org.ipfire.network1.Port", "Stats", stats64); ++ if (r < 0) { ++ ERROR("Could not emit stats for port %s: %m\n", nw_port_name(port)); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (path) ++ free(path); ++ ++ return r; ++} ++ ++int nw_stats_collector_emit_zone_stats(nw_daemon* daemon, nw_zone* zone) { ++ const struct rtnl_link_stats64* stats64 = NULL; ++ char* path = NULL; ++ int r; ++ ++ // Fetch the bus path ++ path = nw_zone_bus_path(zone); ++ ++ // Fetch the stats ++ stats64 = nw_zone_get_stats64(zone); ++ ++ // Emit the stats ++ r = nw_stats_collector_emit_stats(daemon, path, ++ "org.ipfire.network1.Zone", "Stats", stats64); ++ if (r < 0) { ++ ERROR("Could not emit stats for zone %s: %m\n", nw_zone_name(zone)); ++ goto ERROR; ++ } ++ ++ERROR: ++ if (path) ++ free(path); ++ ++ return r; ++} +diff --git a/src/networkd/stats-collector.h b/src/networkd/stats-collector.h +new file mode 100644 +index 0000000..ea11c11 +--- /dev/null ++++ b/src/networkd/stats-collector.h +@@ -0,0 +1,37 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_STATS_COLLECTOR_H ++#define NETWORKD_STATS_COLLECTOR_H ++ ++#include ++ ++#include "daemon.h" ++#include "port.h" ++#include "zone.h" ++ ++#define NW_STATS_COLLECTOR_INTERVAL 15 * 1000000ULL // 15 sec in µsec ++ ++int nw_stats_collector(sd_event_source* s, long unsigned int usec, void* data); ++ ++int nw_stats_collector_emit_port_stats(nw_daemon* daemon, nw_port* port); ++int nw_stats_collector_emit_zone_stats(nw_daemon* daemon, nw_zone* zone); ++ ++#endif /* NETWORKD_STATS_COLLECTOR_H */ +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 00ab017..3f47a26 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -19,6 +19,7 @@ + #############################################################################*/ + + #include ++#include + #include + + #include +@@ -27,6 +28,7 @@ + #include "daemon.h" + #include "link.h" + #include "logging.h" ++#include "stats-collector.h" + #include "string.h" + #include "zone.h" + +@@ -263,3 +265,31 @@ int nw_zone_set_mtu(nw_zone* zone, unsigned int mtu) { + + return nw_config_set_int(zone->config, "MTU", mtu); + } ++ ++/* ++ Stats ++*/ ++ ++const struct rtnl_link_stats64* nw_zone_get_stats64(nw_zone* zone) { ++ if (!zone->link) ++ return NULL; ++ ++ return nw_link_get_stats64(zone->link); ++} ++ ++int __nw_zone_update_stats(nw_daemon* daemon, nw_zone* zone, void* data) { ++ nw_link* link = (nw_link*)data; ++ ++ // Emit stats if link matches ++ if (zone->link == link) ++ return nw_stats_collector_emit_zone_stats(daemon, zone); ++ ++ return 0; ++} ++ ++int nw_zone_update_stats(nw_zone* zone) { ++ if (zone->link) ++ return nw_link_update_stats(zone->link); ++ ++ return 0; ++} +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index ad348d7..9737b45 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -28,6 +28,8 @@ + + typedef struct nw_zone nw_zone; + ++#include ++ + #include "daemon.h" + + int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name); +@@ -54,4 +56,8 @@ int nw_zone_has_carrier(nw_zone* zone); + unsigned int nw_zone_mtu(nw_zone* zone); + int nw_zone_set_mtu(nw_zone* zone, unsigned int mtu); + ++const struct rtnl_link_stats64* nw_zone_get_stats64(nw_zone* zone); ++int __nw_zone_update_stats(nw_daemon* daemon, nw_zone* zone, void* data); ++int nw_zone_update_stats(nw_zone* zone); ++ + #endif /* NETWORKD_ZONE_H */ +-- +2.39.2 + diff --git a/network/patches/0231-address-Fix-output-buffer-size-when-formatting-MAC-a.patch b/network/patches/0231-address-Fix-output-buffer-size-when-formatting-MAC-a.patch new file mode 100644 index 000000000..716fc51b3 --- /dev/null +++ b/network/patches/0231-address-Fix-output-buffer-size-when-formatting-MAC-a.patch @@ -0,0 +1,27 @@ +From 35bf96bb311d13924cd96668736b474c1576f553 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 10:45:53 +0000 +Subject: [PATCH 231/304] address: Fix output buffer size when formatting MAC + addresses + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index b7556f4..7937d62 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -43,7 +43,7 @@ static inline int nw_address_from_string(nw_address_t* addr, const char* s) { + } + + static inline char* nw_address_to_string(const nw_address_t* addr) { +- char buffer[18]; ++ char buffer[20]; + + char* p = ether_ntoa_r(addr, buffer); + if (!p) +-- +2.39.2 + diff --git a/network/patches/0232-config-Fail-if-there-is-garbage-after-intergers.patch b/network/patches/0232-config-Fail-if-there-is-garbage-after-intergers.patch new file mode 100644 index 000000000..d5b55cc45 --- /dev/null +++ b/network/patches/0232-config-Fail-if-there-is-garbage-after-intergers.patch @@ -0,0 +1,42 @@ +From 92c8a4fe8806d0a84f4c546be75c0f08dc6d7200 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 10:46:32 +0000 +Subject: [PATCH 232/304] config: Fail if there is garbage after intergers + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index d879ace..42e0172 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -348,13 +348,23 @@ int nw_config_set(nw_config* config, const char* key, const char* value) { + } + + int nw_config_get_int(nw_config* config, const char* key, const int __default) { ++ char* p = NULL; ++ int r; ++ + const char* value = nw_config_get(config, key); + + // Return zero if not set + if (!value) + return __default; + +- return strtoul(value, NULL, 10); ++ // Parse the input ++ r = strtoul(value, &p, 10); ++ ++ // If we have characters following the input, we throw it away ++ if (p) ++ return __default; ++ ++ return r; + } + + int nw_config_set_int(nw_config* config, const char* key, const int value) { +-- +2.39.2 + diff --git a/network/patches/0233-config-Avoid-adding-empty-line-after-integers.patch b/network/patches/0233-config-Avoid-adding-empty-line-after-integers.patch new file mode 100644 index 000000000..6494350da --- /dev/null +++ b/network/patches/0233-config-Avoid-adding-empty-line-after-integers.patch @@ -0,0 +1,26 @@ +From 2d00051763072b26fa5c1ba421afe2f0928d57ce Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 11:13:22 +0000 +Subject: [PATCH 233/304] config: Avoid adding empty line after integers + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 42e0172..27cfad8 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -372,7 +372,7 @@ int nw_config_set_int(nw_config* config, const char* key, const int value) { + int r; + + // Format the value as string +- r = nw_string_format(__value, "%d\n", value); ++ r = nw_string_format(__value, "%d", value); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0234-ports-Require-type-to-be-set-at-all-times.patch b/network/patches/0234-ports-Require-type-to-be-set-at-all-times.patch new file mode 100644 index 000000000..da6ff24ab --- /dev/null +++ b/network/patches/0234-ports-Require-type-to-be-set-at-all-times.patch @@ -0,0 +1,133 @@ +From 06bc93d3136c4bd2d75f7c50051b8b96d29dab59 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 11:15:15 +0000 +Subject: [PATCH 234/304] ports: Require type to be set at all times + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 50 ++++++++++++++++++++++++++++++-------------- + src/networkd/port.h | 5 ++++- + src/networkd/ports.c | 2 +- + 3 files changed, 39 insertions(+), 18 deletions(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 7638c7b..aad6210 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -128,14 +128,6 @@ static int nw_port_setup_common(nw_port* port) { + return 0; + } + +-static nw_port_type_t nw_port_setup_type(nw_port* port) { +- const char* type = nw_config_get(port->config, "TYPE"); +- if (!type) +- return NW_PORT_UNKNOWN; +- +- return nw_port_type_from_string(type); +-} +- + static int nw_port_set_link(nw_port* port, nw_link* link) { + // Do nothing if the same link is being re-assigned + if (port->link == link) +@@ -184,13 +176,6 @@ static int nw_port_setup(nw_port* port) { + if (r) + goto ERROR; + +- // Determine type +- port->type = nw_port_setup_type(port); +- if (!port->type) { +- ERROR("Could not determine type of port %s\n", port->name); +- goto ERROR; +- } +- + // Perform some common initialization + r = nw_port_setup_common(port); + if (r) +@@ -211,7 +196,7 @@ ERROR: + return r; + } + +-int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name) { ++int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const char* name) { + int r; + + // Allocate a new object +@@ -225,6 +210,9 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name) { + // Initialize reference counter + p->nrefs = 1; + ++ // Store the type ++ p->type = type; ++ + // Store the name + r = nw_string_set(p->name, name); + if (r) +@@ -243,6 +231,36 @@ ERROR: + return r; + } + ++int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, ++ const char* name, const char* path) { ++ nw_config* config = NULL; ++ int r; ++ ++ // Initialize the configuration ++ r = nw_config_create(&config, path); ++ if (r) ++ goto ERROR; ++ ++ // Fetch the type ++ const char* type = nw_config_get(config, "TYPE"); ++ if (!type) { ++ ERROR("Port configuration %s has no TYPE\n", path); ++ r = 1; ++ goto ERROR; ++ } ++ ++ // Create a new port ++ r = nw_port_create(port, daemon, nw_port_type_from_string(type), name); ++ if (r) ++ goto ERROR; ++ ++ERROR: ++ if (config) ++ nw_config_unref(config); ++ ++ return r; ++} ++ + nw_port* nw_port_ref(nw_port* port) { + port->nrefs++; + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 9dcd6c2..2f4319b 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -33,7 +33,10 @@ typedef struct nw_port nw_port; + #include "address.h" + #include "daemon.h" + +-int nw_port_create(nw_port** port, nw_daemon* daemon, const char* name); ++int nw_port_create(nw_port** port, nw_daemon* daemon, ++ nw_port_type_t type, const char* name); ++int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, ++ const char* name, const char* path); + + nw_port* nw_port_ref(nw_port* port); + nw_port* nw_port_unref(nw_port* port); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 87135d8..f0a3ebb 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -151,7 +151,7 @@ static int __nw_ports_enumerate(const char* path, const struct stat* s, void* da + return 0; + + // Create a new port +- r = nw_port_create(&port, ports->daemon, name); ++ r = nw_port_create_from_config(&port, ports->daemon, name, path); + if (r) + goto ERROR; + +-- +2.39.2 + diff --git a/network/patches/0235-port-Implement-reading-writing-VLAN-settings.patch b/network/patches/0235-port-Implement-reading-writing-VLAN-settings.patch new file mode 100644 index 000000000..687e9eb94 --- /dev/null +++ b/network/patches/0235-port-Implement-reading-writing-VLAN-settings.patch @@ -0,0 +1,287 @@ +From c7761af8c8f278f3adb7d422144e13f845089a4b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 11:16:33 +0000 +Subject: [PATCH 235/304] port: Implement reading/writing VLAN settings + +This is just simple test to see where the configuration could be going. + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 166 +++++++++++++++++++++++++++++++++++++++++- + src/networkd/port.h | 13 ++++ + src/networkd/string.h | 5 ++ + 3 files changed, 182 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index aad6210..a240c61 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -40,21 +40,32 @@ struct nw_port { + // Link + nw_link* link; + +- char name[IF_NAMESIZE]; + nw_port_type_t type; ++ char name[IF_NAMESIZE]; + + // Configuration + nw_config *config; + + // Common attributes + nw_address_t address; ++ ++ // VLAN settings ++ struct nw_port_vlan { ++ nw_port* parent; ++ int id; ++ ++ // If the parent has not been read from the configuration we will ++ // save the name and try to find it later. ++ char __parent_name[IF_NAMESIZE]; ++ } vlan; + }; + + static const struct nw_port_type_map { + nw_port_type_t type; + const char* name; + } nw_port_type_map[] = { +- { NW_PORT_DUMMY, "dummy" }, ++ { NW_PORT_DUMMY, "dummy" }, ++ { NW_PORT_VLAN, "vlan" }, + { NW_PORT_UNKNOWN, NULL }, + }; + +@@ -128,6 +139,28 @@ static int nw_port_setup_common(nw_port* port) { + return 0; + } + ++static int nw_port_setup_vlan(nw_port* port) { ++ int r; ++ ++ // VLAN ID ++ int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); ++ if (id) { ++ r = nw_port_set_vlan_id(port, id); ++ if (r) ++ return r; ++ } ++ ++ // Parent Port ++ const char* parent = nw_config_get(port->config, "VLAN_PARENT"); ++ if (parent) { ++ r = nw_string_set(port->vlan.__parent_name, parent); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ + static int nw_port_set_link(nw_port* port, nw_link* link) { + // Do nothing if the same link is being re-assigned + if (port->link == link) +@@ -183,6 +216,12 @@ static int nw_port_setup(nw_port* port) { + + // Call any custom initialization + switch (port->type) { ++ case NW_PORT_VLAN: ++ r = nw_port_setup_vlan(port); ++ if (r) ++ goto ERROR; ++ break; ++ + // These do not need any special initialization + case NW_PORT_DUMMY: + case NW_PORT_UNKNOWN: +@@ -275,14 +314,50 @@ nw_port* nw_port_unref(nw_port* port) { + return NULL; + } + ++static int nw_port_save_vlan(nw_port* port) { ++ int r; ++ ++ // VLAN ID ++ r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); ++ if (r) ++ return r; ++ ++ // Parent Port ++ r = nw_config_set(port->config, "VLAN_PARENT", ++ (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ + int nw_port_save(nw_port* port) { + int r; + ++ switch (port->type) { ++ // VLAN ++ case NW_PORT_VLAN: ++ r = nw_port_save_vlan(port); ++ if (r) ++ goto ERROR; ++ break; ++ ++ // These types do not have any special settings ++ case NW_PORT_DUMMY: ++ case NW_PORT_UNKNOWN: ++ break; ++ } ++ + r = nw_config_write(port->config); + if (r) + return r; + + return 0; ++ ++ERROR: ++ ERROR("Could not save configuration for port %s: %m\n", port->name); ++ ++ return 1; + } + + const char* nw_port_name(nw_port* port) { +@@ -404,3 +479,90 @@ int nw_port_update_stats(nw_port* port) { + + return 0; + } ++ ++static int nw_port_check_type(nw_port* port, const nw_port_type_t type) { ++ if (port->type == type) ++ return 0; ++ ++ errno = ENOTSUP; ++ return -errno; ++} ++ ++/* ++ VLAN ++*/ ++int nw_port_get_vlan_id(nw_port* port) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ return port->vlan.id; ++} ++ ++int nw_port_set_vlan_id(nw_port* port, int id) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ // Check if the VLAN ID is within range ++ if (id < NW_VLAN_ID_MIN || id > NW_VLAN_ID_MAX) ++ return -EINVAL; ++ ++ // Store the ID ++ port->vlan.id = id; ++ ++ DEBUG("Port %s: Set VLAN ID to %d\n", port->name, port->vlan.id); ++ ++ return 0; ++} ++ ++nw_port* nw_port_get_vlan_parent(nw_port* port) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return NULL; ++ ++ // Try to find a reference to the parent if none exists ++ if (!port->vlan.parent && *port->vlan.__parent_name) ++ port->vlan.parent = nw_daemon_get_port_by_name(port->daemon, port->vlan.__parent_name); ++ ++ if (port->vlan.parent) ++ return nw_port_ref(port->vlan.parent); ++ ++ // No port found ++ return NULL; ++} ++ ++int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ // Reset the former parent name ++ nw_string_empty(port->vlan.__parent_name); ++ ++ // Dereference the former parent ++ if (port->vlan.parent) { ++ nw_port_unref(port->vlan.parent); ++ port->vlan.parent = NULL; ++ } ++ ++ // Store the new parent ++ if (parent) ++ port->vlan.parent = nw_port_ref(parent); ++ ++ DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); ++ ++ return 0; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 2f4319b..d89e1e0 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -26,8 +26,14 @@ + typedef enum nw_port_type { + NW_PORT_UNKNOWN = 0, + NW_PORT_DUMMY, ++ NW_PORT_VLAN, + } nw_port_type_t; + ++// VLAN ++#define NW_VLAN_ID_INVALID 0 ++#define NW_VLAN_ID_MIN 1 ++#define NW_VLAN_ID_MAX 4096 ++ + typedef struct nw_port nw_port; + + #include "address.h" +@@ -61,4 +67,11 @@ const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); + int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); + int nw_port_update_stats(nw_port* port); + ++// VLAN ++int nw_port_get_vlan_id(nw_port* port); ++int nw_port_set_vlan_id(nw_port* port, int id); ++ ++nw_port* nw_port_get_vlan_parent(nw_port* port); ++int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); ++ + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 6ff44f9..5bdfc3d 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -120,6 +120,11 @@ static inline int nw_string_strip(char* s) { + return 0; + } + ++static inline void nw_string_empty(char* s) { ++ if (s) ++ *s = '\0'; ++} ++ + /* + Paths + */ +-- +2.39.2 + diff --git a/network/patches/0236-ports-Implement-destroying-a-port.patch b/network/patches/0236-ports-Implement-destroying-a-port.patch new file mode 100644 index 000000000..121334aac --- /dev/null +++ b/network/patches/0236-ports-Implement-destroying-a-port.patch @@ -0,0 +1,193 @@ +From c403eb4c480316090d9ca3fd2915b1bf25ac10c0 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 15 Apr 2023 11:46:22 +0000 +Subject: [PATCH 236/304] ports: Implement destroying a port + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 12 ++++++++++ + src/networkd/config.h | 2 ++ + src/networkd/link.c | 2 ++ + src/networkd/port.c | 54 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/port.h | 3 +++ + src/networkd/zone.c | 9 ++++++++ + src/networkd/zone.h | 2 ++ + 7 files changed, 84 insertions(+) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 27cfad8..8269ede 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "config.h" + #include "logging.h" +@@ -135,6 +136,17 @@ nw_config* nw_config_unref(nw_config* config) { + return NULL; + } + ++int nw_config_destroy(nw_config* config) { ++ int r; ++ ++ // Drop all entries ++ r = nw_config_flush(config); ++ if (r) ++ return r; ++ ++ return unlink(config->path); ++} ++ + const char* nw_config_path(nw_config* config) { + if (*config->path) + return config->path; +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 0b25f75..e17c016 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -33,6 +33,8 @@ int nw_config_create(nw_config** config, const char* path); + nw_config* nw_config_ref(nw_config* config); + nw_config* nw_config_unref(nw_config* config); + ++int nw_config_destroy(nw_config* config); ++ + const char* nw_config_path(nw_config* config); + + int nw_config_flush(nw_config* config); +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 1edf20d..603aabe 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -308,12 +308,14 @@ static int nw_link_update_flags(nw_link* link, sd_netlink_message* message) { + return 1; + } + ++#if 0 + // Fetch operstate + r = sd_netlink_message_read_u8(message, IFLA_OPERSTATE, &operstate); + if (r < 1) { + ERROR("Could not read operstate: %m\n"); + return 1; + } ++#endif + + // End here if there have been no changes + if (link->flags == flags && link->operstate == operstate) +diff --git a/src/networkd/port.c b/src/networkd/port.c +index a240c61..23ffd0b 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -314,6 +314,60 @@ nw_port* nw_port_unref(nw_port* port) { + return NULL; + } + ++int nw_port_destroy(nw_port* port) { ++ int r; ++ ++ DEBUG("Destroying port %s\n", port->name); ++ ++ // Destroy the physical link (if exists) ++ if (port->link) { ++ r = nw_link_destroy(port->link); ++ if (r) ++ return r; ++ } ++ ++ // Dereference the port from other ports ++ r = nw_daemon_ports_walk(port->daemon, __nw_port_drop_port, port); ++ if (r) ++ return r; ++ ++ // Dereference the port from other zones ++ r = nw_daemon_zones_walk(port->daemon, __nw_zone_drop_port, port); ++ if (r) ++ return r; ++ ++ // Destroy the configuration ++ r = nw_config_destroy(port->config); ++ if (r) ++ return r; ++ ++ // Reset type ++ port->type = NW_PORT_UNKNOWN; ++ ++ return 0; ++} ++ ++int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { ++ nw_port* dropped_port = (nw_port*)data; ++ int r; ++ ++ switch (port->type) { ++ case NW_PORT_VLAN: ++ if (port->vlan.parent == dropped_port) { ++ r = nw_port_set_vlan_parent(port, NULL); ++ if (r) ++ return r; ++ } ++ break; ++ ++ case NW_PORT_DUMMY: ++ case NW_PORT_UNKNOWN: ++ break; ++ } ++ ++ return 0; ++} ++ + static int nw_port_save_vlan(nw_port* port) { + int r; + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index d89e1e0..032d82c 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -47,6 +47,9 @@ int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, + nw_port* nw_port_ref(nw_port* port); + nw_port* nw_port_unref(nw_port* port); + ++int nw_port_destroy(nw_port* port); ++int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data); ++ + int nw_port_save(nw_port* port); + + const char* nw_port_name(nw_port* port); +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 3f47a26..9f5b7f8 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -183,6 +183,15 @@ nw_zone* nw_zone_unref(nw_zone* zone) { + return NULL; + } + ++int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data) { ++ nw_port* dropped_port = (nw_port*)data; ++ ++ // XXX TODO ++ (void)dropped_port; ++ ++ return 0; ++} ++ + int nw_zone_save(nw_zone* zone) { + int r; + +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 9737b45..480440f 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -37,6 +37,8 @@ int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name); + nw_zone* nw_zone_ref(nw_zone* zone); + nw_zone* nw_zone_unref(nw_zone* zone); + ++int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data); ++ + int nw_zone_save(nw_zone* zone); + + const char* nw_zone_name(nw_zone* zone); +-- +2.39.2 + diff --git a/network/patches/0237-ports-Create-scaffolding-for-operations-struct.patch b/network/patches/0237-ports-Create-scaffolding-for-operations-struct.patch new file mode 100644 index 000000000..69b8e3caf --- /dev/null +++ b/network/patches/0237-ports-Create-scaffolding-for-operations-struct.patch @@ -0,0 +1,156 @@ +From 9e8af30e5ff0ab717f7d878f8e9c62323ec161a1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 14:28:35 +0000 +Subject: [PATCH 237/304] ports: Create scaffolding for operations struct + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/port-dummy.c | 28 ++++++++++++++++++++++++++++ + src/networkd/port-dummy.h | 28 ++++++++++++++++++++++++++++ + src/networkd/port.c | 11 +++++++++++ + src/networkd/port.h | 7 +++++++ + 5 files changed, 76 insertions(+) + create mode 100644 src/networkd/port-dummy.c + create mode 100644 src/networkd/port-dummy.h + +diff --git a/Makefile.am b/Makefile.am +index 22d90d4..15e9fa0 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -332,6 +332,8 @@ dist_networkd_SOURCES = \ + src/networkd/port.h \ + src/networkd/port-bus.c \ + src/networkd/port-bus.h \ ++ src/networkd/port-dummy.c \ ++ src/networkd/port-dummy.h \ + src/networkd/stats-collector.c \ + src/networkd/stats-collector.h \ + src/networkd/string.h \ +diff --git a/src/networkd/port-dummy.c b/src/networkd/port-dummy.c +new file mode 100644 +index 0000000..cc4b649 +--- /dev/null ++++ b/src/networkd/port-dummy.c +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include "port.h" ++#include "port-dummy.h" ++ ++nw_port_ops_t nw_port_ops_dummy = { ++ // There is no special configuration ++ .config_read = NULL, ++ .config_write = NULL, ++}; +diff --git a/src/networkd/port-dummy.h b/src/networkd/port-dummy.h +new file mode 100644 +index 0000000..0a29c84 +--- /dev/null ++++ b/src/networkd/port-dummy.h +@@ -0,0 +1,28 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_DUMMY_H ++#define NETWORKD_PORT_DUMMY_H ++ ++#include "port.h" ++ ++extern nw_port_ops_t nw_port_ops_dummy; ++ ++#endif /* NETWORKD_PORT_DUMMY_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 23ffd0b..6ba4875 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -30,6 +30,7 @@ + #include "link.h" + #include "logging.h" + #include "port.h" ++#include "port-dummy.h" + #include "stats-collector.h" + #include "string.h" + +@@ -49,6 +50,9 @@ struct nw_port { + // Common attributes + nw_address_t address; + ++ // Type Operations ++ nw_port_ops_t ops; ++ + // VLAN settings + struct nw_port_vlan { + nw_port* parent; +@@ -252,6 +256,13 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const + // Store the type + p->type = type; + ++ // Set operations ++ switch (p->type) { ++ case NW_PORT_DUMMY: ++ p->ops = nw_port_ops_dummy; ++ break; ++ } ++ + // Store the name + r = nw_string_set(p->name, name); + if (r) +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 032d82c..76df7a7 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -37,8 +37,15 @@ typedef enum nw_port_type { + typedef struct nw_port nw_port; + + #include "address.h" ++#include "config.h" + #include "daemon.h" + ++typedef struct nw_port_ops { ++ // Configuration ++ int (*config_read)(nw_port* port, nw_config* config); ++ int (*config_write)(nw_port* port, nw_config* config); ++} nw_port_ops_t; ++ + int nw_port_create(nw_port** port, nw_daemon* daemon, + nw_port_type_t type, const char* name); + int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, +-- +2.39.2 + diff --git a/network/patches/0238-ports-Move-VLAN-stuff-into-its-own-file.patch b/network/patches/0238-ports-Move-VLAN-stuff-into-its-own-file.patch new file mode 100644 index 000000000..3e83ff9c5 --- /dev/null +++ b/network/patches/0238-ports-Move-VLAN-stuff-into-its-own-file.patch @@ -0,0 +1,591 @@ +From ff88697584a58e86b3abdad0b5017fda382f50e9 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 14:54:58 +0000 +Subject: [PATCH 238/304] ports: Move VLAN stuff into its own file + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/port-vlan.c | 150 +++++++++++++++++++++++++++++ + src/networkd/port-vlan.h | 36 +++++++ + src/networkd/port.c | 203 ++++++--------------------------------- + src/networkd/port.h | 51 ++++++++-- + src/networkd/ports.h | 1 + + 6 files changed, 261 insertions(+), 182 deletions(-) + create mode 100644 src/networkd/port-vlan.c + create mode 100644 src/networkd/port-vlan.h + +diff --git a/Makefile.am b/Makefile.am +index 15e9fa0..aafa59c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -334,6 +334,8 @@ dist_networkd_SOURCES = \ + src/networkd/port-bus.h \ + src/networkd/port-dummy.c \ + src/networkd/port-dummy.h \ ++ src/networkd/port-vlan.c \ ++ src/networkd/port-vlan.h \ + src/networkd/stats-collector.c \ + src/networkd/stats-collector.h \ + src/networkd/string.h \ +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +new file mode 100644 +index 0000000..c9581f6 +--- /dev/null ++++ b/src/networkd/port-vlan.c +@@ -0,0 +1,150 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include "config.h" ++#include "daemon.h" ++#include "logging.h" ++#include "port.h" ++#include "port-vlan.h" ++#include "string.h" ++ ++static int nw_port_vlan_config_read(nw_port* port) { ++ int r; ++ ++ // VLAN ID ++ int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); ++ if (id) { ++ r = nw_port_set_vlan_id(port, id); ++ if (r) ++ return r; ++ } ++ ++ // Parent Port ++ const char* parent = nw_config_get(port->config, "VLAN_PARENT"); ++ if (parent) { ++ r = nw_string_set(port->vlan.__parent_name, parent); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ ++static int nw_port_vlan_config_write(nw_port* port) { ++ int r; ++ ++ // VLAN ID ++ r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); ++ if (r) ++ return r; ++ ++ // Parent Port ++ r = nw_config_set(port->config, "VLAN_PARENT", ++ (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ ++nw_port_ops_t nw_port_ops_vlan = { ++ // Configuration ++ .config_read = nw_port_vlan_config_read, ++ .config_write = nw_port_vlan_config_write, ++}; ++ ++/* ++ VLAN ++*/ ++int nw_port_get_vlan_id(nw_port* port) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ return port->vlan.id; ++} ++ ++int nw_port_set_vlan_id(nw_port* port, int id) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ // Check if the VLAN ID is within range ++ if (id < NW_VLAN_ID_MIN || id > NW_VLAN_ID_MAX) ++ return -EINVAL; ++ ++ // Store the ID ++ port->vlan.id = id; ++ ++ DEBUG("Port %s: Set VLAN ID to %d\n", port->name, port->vlan.id); ++ ++ return 0; ++} ++ ++nw_port* nw_port_get_vlan_parent(nw_port* port) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return NULL; ++ ++ // Try to find a reference to the parent if none exists ++ if (!port->vlan.parent && *port->vlan.__parent_name) ++ port->vlan.parent = nw_daemon_get_port_by_name(port->daemon, port->vlan.__parent_name); ++ ++ if (port->vlan.parent) ++ return nw_port_ref(port->vlan.parent); ++ ++ // No port found ++ return NULL; ++} ++ ++int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { ++ int r; ++ ++ // Check type ++ r = nw_port_check_type(port, NW_PORT_VLAN); ++ if (r < 0) ++ return r; ++ ++ // Reset the former parent name ++ nw_string_empty(port->vlan.__parent_name); ++ ++ // Dereference the former parent ++ if (port->vlan.parent) { ++ nw_port_unref(port->vlan.parent); ++ port->vlan.parent = NULL; ++ } ++ ++ // Store the new parent ++ if (parent) ++ port->vlan.parent = nw_port_ref(parent); ++ ++ DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); ++ ++ return 0; ++} +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +new file mode 100644 +index 0000000..2bacb24 +--- /dev/null ++++ b/src/networkd/port-vlan.h +@@ -0,0 +1,36 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_VLAN_H ++#define NETWORKD_PORT_VLAN_H ++ ++#include "port.h" ++ ++extern nw_port_ops_t nw_port_ops_vlan; ++ ++// ID ++int nw_port_get_vlan_id(nw_port* port); ++int nw_port_set_vlan_id(nw_port* port, int id); ++ ++// Parent Port ++nw_port* nw_port_get_vlan_parent(nw_port* port); ++int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); ++ ++#endif /* NETWORKD_PORT_VLAN_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 6ba4875..b3b7d66 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -31,39 +31,10 @@ + #include "logging.h" + #include "port.h" + #include "port-dummy.h" ++#include "port-vlan.h" + #include "stats-collector.h" + #include "string.h" + +-struct nw_port { +- nw_daemon* daemon; +- int nrefs; +- +- // Link +- nw_link* link; +- +- nw_port_type_t type; +- char name[IF_NAMESIZE]; +- +- // Configuration +- nw_config *config; +- +- // Common attributes +- nw_address_t address; +- +- // Type Operations +- nw_port_ops_t ops; +- +- // VLAN settings +- struct nw_port_vlan { +- nw_port* parent; +- int id; +- +- // If the parent has not been read from the configuration we will +- // save the name and try to find it later. +- char __parent_name[IF_NAMESIZE]; +- } vlan; +-}; +- + static const struct nw_port_type_map { + nw_port_type_t type; + const char* name; +@@ -143,28 +114,6 @@ static int nw_port_setup_common(nw_port* port) { + return 0; + } + +-static int nw_port_setup_vlan(nw_port* port) { +- int r; +- +- // VLAN ID +- int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); +- if (id) { +- r = nw_port_set_vlan_id(port, id); +- if (r) +- return r; +- } +- +- // Parent Port +- const char* parent = nw_config_get(port->config, "VLAN_PARENT"); +- if (parent) { +- r = nw_string_set(port->vlan.__parent_name, parent); +- if (r) +- return r; +- } +- +- return 0; +-} +- + static int nw_port_set_link(nw_port* port, nw_link* link) { + // Do nothing if the same link is being re-assigned + if (port->link == link) +@@ -219,17 +168,10 @@ static int nw_port_setup(nw_port* port) { + goto ERROR; + + // Call any custom initialization +- switch (port->type) { +- case NW_PORT_VLAN: +- r = nw_port_setup_vlan(port); +- if (r) +- goto ERROR; +- break; +- +- // These do not need any special initialization +- case NW_PORT_DUMMY: +- case NW_PORT_UNKNOWN: +- break; ++ if (port->ops.config_read) { ++ r = port->ops.config_read(port); ++ if (r) ++ goto ERROR; + } + + ERROR: +@@ -261,6 +203,10 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const + case NW_PORT_DUMMY: + p->ops = nw_port_ops_dummy; + break; ++ ++ case NW_PORT_VLAN: ++ p->ops = nw_port_ops_vlan; ++ break; + } + + // Store the name +@@ -379,40 +325,17 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + return 0; + } + +-static int nw_port_save_vlan(nw_port* port) { +- int r; +- +- // VLAN ID +- r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); +- if (r) +- return r; +- +- // Parent Port +- r = nw_config_set(port->config, "VLAN_PARENT", +- (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); +- if (r) +- return r; +- +- return 0; +-} +- + int nw_port_save(nw_port* port) { + int r; + +- switch (port->type) { +- // VLAN +- case NW_PORT_VLAN: +- r = nw_port_save_vlan(port); +- if (r) +- goto ERROR; +- break; +- +- // These types do not have any special settings +- case NW_PORT_DUMMY: +- case NW_PORT_UNKNOWN: +- break; ++ // Call the custom handler ++ if (port->ops.config_write) { ++ r = port->ops.config_write(port); ++ if (r) ++ goto ERROR; + } + ++ // Write the configuration + r = nw_config_write(port->config); + if (r) + return r; +@@ -481,7 +404,20 @@ static int nw_port_is_disabled(nw_port* port) { + } + + static int nw_port_create_link(nw_port* port) { +- return 0; // XXX TODO ++ int r; ++ ++ // Fail if the function isn't set ++ if (!port->ops.create_link) { ++ errno = ENOTSUP; ++ return -errno; ++ } ++ ++ // Create the link ++ r = port->ops.create_link(port); ++ if (r) ++ ERROR("Could not create link %s: %m\n", port->name); ++ ++ return r; + } + + int nw_port_reconfigure(nw_port* port) { +@@ -545,89 +481,10 @@ int nw_port_update_stats(nw_port* port) { + return 0; + } + +-static int nw_port_check_type(nw_port* port, const nw_port_type_t type) { ++int nw_port_check_type(nw_port* port, const nw_port_type_t type) { + if (port->type == type) + return 0; + + errno = ENOTSUP; + return -errno; + } +- +-/* +- VLAN +-*/ +-int nw_port_get_vlan_id(nw_port* port) { +- int r; +- +- // Check type +- r = nw_port_check_type(port, NW_PORT_VLAN); +- if (r < 0) +- return r; +- +- return port->vlan.id; +-} +- +-int nw_port_set_vlan_id(nw_port* port, int id) { +- int r; +- +- // Check type +- r = nw_port_check_type(port, NW_PORT_VLAN); +- if (r < 0) +- return r; +- +- // Check if the VLAN ID is within range +- if (id < NW_VLAN_ID_MIN || id > NW_VLAN_ID_MAX) +- return -EINVAL; +- +- // Store the ID +- port->vlan.id = id; +- +- DEBUG("Port %s: Set VLAN ID to %d\n", port->name, port->vlan.id); +- +- return 0; +-} +- +-nw_port* nw_port_get_vlan_parent(nw_port* port) { +- int r; +- +- // Check type +- r = nw_port_check_type(port, NW_PORT_VLAN); +- if (r < 0) +- return NULL; +- +- // Try to find a reference to the parent if none exists +- if (!port->vlan.parent && *port->vlan.__parent_name) +- port->vlan.parent = nw_daemon_get_port_by_name(port->daemon, port->vlan.__parent_name); +- +- if (port->vlan.parent) +- return nw_port_ref(port->vlan.parent); +- +- // No port found +- return NULL; +-} +- +-int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { +- int r; +- +- // Check type +- r = nw_port_check_type(port, NW_PORT_VLAN); +- if (r < 0) +- return r; +- +- // Reset the former parent name +- nw_string_empty(port->vlan.__parent_name); +- +- // Dereference the former parent +- if (port->vlan.parent) { +- nw_port_unref(port->vlan.parent); +- port->vlan.parent = NULL; +- } +- +- // Store the new parent +- if (parent) +- port->vlan.parent = nw_port_ref(parent); +- +- DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); +- +- return 0; +-} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 76df7a7..5253d69 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -21,6 +21,10 @@ + #ifndef NETWORKD_PORT_H + #define NETWORKD_PORT_H + ++#ifndef IF_NAMESIZE ++#define IF_NAMESIZE 16 ++#endif ++ + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" + + typedef enum nw_port_type { +@@ -42,10 +46,44 @@ typedef struct nw_port nw_port; + + typedef struct nw_port_ops { + // Configuration +- int (*config_read)(nw_port* port, nw_config* config); +- int (*config_write)(nw_port* port, nw_config* config); ++ int (*config_read)(nw_port* port); ++ int (*config_write)(nw_port* port); ++ ++ // Link ++ int (*create_link)(nw_port* port); ++ int (*destroy_link)(nw_port* port); + } nw_port_ops_t; + ++struct nw_port { ++ nw_daemon* daemon; ++ int nrefs; ++ ++ // Link ++ nw_link* link; ++ ++ nw_port_type_t type; ++ char name[IF_NAMESIZE]; ++ ++ // Configuration ++ nw_config *config; ++ ++ // Common attributes ++ nw_address_t address; ++ ++ // Type Operations ++ nw_port_ops_t ops; ++ ++ // VLAN settings ++ struct nw_port_vlan { ++ nw_port* parent; ++ int id; ++ ++ // If the parent has not been read from the configuration we will ++ // save the name and try to find it later. ++ char __parent_name[IF_NAMESIZE]; ++ } vlan; ++}; ++ + int nw_port_create(nw_port** port, nw_daemon* daemon, + nw_port_type_t type, const char* name); + int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, +@@ -72,16 +110,11 @@ int nw_port_reconfigure(nw_port* port); + + int nw_port_has_carrier(nw_port* port); + ++int nw_port_check_type(nw_port* port, const nw_port_type_t type); ++ + // Stats + const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); + int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); + int nw_port_update_stats(nw_port* port); + +-// VLAN +-int nw_port_get_vlan_id(nw_port* port); +-int nw_port_set_vlan_id(nw_port* port, int id); +- +-nw_port* nw_port_get_vlan_parent(nw_port* port); +-int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); +- + #endif /* NETWORKD_PORT_H */ +diff --git a/src/networkd/ports.h b/src/networkd/ports.h +index 68ae532..4e41f11 100644 +--- a/src/networkd/ports.h ++++ b/src/networkd/ports.h +@@ -26,6 +26,7 @@ typedef struct nw_ports nw_ports; + typedef int (*nw_ports_walk_callback)(nw_daemon* daemon, nw_port* port, void* data); + + #include "daemon.h" ++#include "port.h" + + int nw_ports_create(nw_ports** ports, nw_daemon* daemon); + +-- +2.39.2 + diff --git a/network/patches/0239-ports-Implement-creating-links-from-ports.patch b/network/patches/0239-ports-Implement-creating-links-from-ports.patch new file mode 100644 index 000000000..6c7f890f0 --- /dev/null +++ b/network/patches/0239-ports-Implement-creating-links-from-ports.patch @@ -0,0 +1,294 @@ +From 240e331b2043ae254c6468ed3ce2ec6d8caf98db Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 16:26:44 +0000 +Subject: [PATCH 239/304] ports: Implement creating links from ports + +Signed-off-by: Michael Tremer +--- + src/networkd/port-dummy.c | 5 +- + src/networkd/port-vlan.c | 20 +++++ + src/networkd/port.c | 149 +++++++++++++++++++++++++++++++++++--- + src/networkd/port.h | 10 ++- + 4 files changed, 170 insertions(+), 14 deletions(-) + +diff --git a/src/networkd/port-dummy.c b/src/networkd/port-dummy.c +index cc4b649..09367d8 100644 +--- a/src/networkd/port-dummy.c ++++ b/src/networkd/port-dummy.c +@@ -18,11 +18,8 @@ + # # + #############################################################################*/ + +-#include "port.h" + #include "port-dummy.h" + + nw_port_ops_t nw_port_ops_dummy = { +- // There is no special configuration +- .config_read = NULL, +- .config_write = NULL, ++ .kind = "dummy", + }; +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index c9581f6..edf91d9 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -18,6 +18,8 @@ + # # + #############################################################################*/ + ++#include ++ + #include "config.h" + #include "daemon.h" + #include "logging.h" +@@ -64,10 +66,28 @@ static int nw_port_vlan_config_write(nw_port* port) { + return 0; + } + ++static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { ++ int r; ++ ++ // Set VLAN ID ++ r = sd_netlink_message_append_u16(m, IFLA_VLAN_ID, port->vlan.id); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + nw_port_ops_t nw_port_ops_vlan = { ++ .kind = "vlan", ++ + // Configuration + .config_read = nw_port_vlan_config_read, + .config_write = nw_port_vlan_config_write, ++ ++ .get_parent_port = nw_port_get_vlan_parent, ++ ++ // Link ++ .create_link = nw_port_vlan_create_link, + }; + + /* +diff --git a/src/networkd/port.c b/src/networkd/port.c +index b3b7d66..a7cbab6 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -72,7 +72,7 @@ static int nw_port_setup_address(nw_port* port) { + // Read ADDRESS from configuration + const char* s = nw_config_get(port->config, "ADDRESS"); + if (!s) { +- ERROR("Port %s: Address isn't set\n", port->name); ++ ERROR("Port %s: Address is not set\n", port->name); + goto ERROR; + } + +@@ -271,6 +271,16 @@ nw_port* nw_port_unref(nw_port* port) { + return NULL; + } + ++/* ++ This is a helper function for when we pass a reference to the event loop ++ it will have to dereference the port instance later. ++*/ ++static void __nw_port_unref(void* data) { ++ nw_port* port = (nw_port*)data; ++ ++ nw_port_unref(port); ++} ++ + int nw_port_destroy(nw_port* port) { + int r; + +@@ -395,6 +405,17 @@ int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data) { + return 0; + } + ++static nw_link* nw_port_get_link(nw_port* port) { ++ // Fetch the link if not set ++ if (!port->link) ++ port->link = nw_daemon_get_link_by_name(port->daemon, port->name); ++ ++ if (!port->link) ++ return NULL; ++ ++ return nw_link_ref(port->link); ++} ++ + const nw_address_t* nw_port_get_address(nw_port* port) { + return &port->address; + } +@@ -403,19 +424,129 @@ static int nw_port_is_disabled(nw_port* port) { + return nw_config_get_bool(port->config, "DISABLED"); + } + ++static nw_link* nw_port_get_parent_link(nw_port* port) { ++ nw_port* parent = NULL; ++ nw_link* link = NULL; ++ ++ // Do nothing if not implemented ++ if (!port->ops.get_parent_port) ++ goto ERROR; ++ ++ // Fetch the parent ++ parent = port->ops.get_parent_port(port); ++ if (!parent) ++ goto ERROR; ++ ++ // Fetch the link ++ link = nw_port_get_link(parent); ++ ++ERROR: ++ if (parent) ++ nw_port_unref(parent); ++ ++ return link; ++} ++ ++static int __nw_port_create_link(sd_netlink* rtnl, sd_netlink_message* m, void* data) { ++ nw_port* port = (nw_port*)data; ++ int r; ++ ++ // Check if the operation was successful ++ r = sd_netlink_message_get_errno(m); ++ if (r < 0) { ++ ERROR("Could not create port %s: %s\n", port->name, strerror(-r)); ++ // XXX We should extract the error message ++ ++ return 0; ++ } ++ ++ DEBUG("Successfully created %s\n", port->name); ++ ++ return 0; ++} ++ + static int nw_port_create_link(nw_port* port) { ++ sd_netlink_message* m = NULL; ++ nw_link* link = NULL; + int r; + +- // Fail if the function isn't set +- if (!port->ops.create_link) { +- errno = ENOTSUP; +- return -errno; ++ sd_netlink* rtnl = nw_daemon_get_rtnl(port->daemon); ++ ++ // Create a new link ++ r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0); ++ if (r < 0) { ++ ERROR("Could not create netlink message: %m\n"); ++ goto ERROR; + } + +- // Create the link +- r = port->ops.create_link(port); +- if (r) +- ERROR("Could not create link %s: %m\n", port->name); ++ // Set the name ++ r = sd_netlink_message_append_string(m, IFLA_IFNAME, port->name); ++ if (r < 0) { ++ ERROR("Could not set port name: %s\n", strerror(-r)); ++ goto ERROR; ++ } ++ ++ // XXX Set common things like MAC address, etc. ++ ++ // Fetch the parent link ++ link = nw_port_get_parent_link(port); ++ if (link) { ++ r = sd_netlink_message_append_u32(m, IFLA_LINK, nw_link_ifindex(link)); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ // Open an IFLA_LINKINFO container ++ r = sd_netlink_message_open_container(m, IFLA_LINKINFO); ++ if (r < 0) ++ goto ERROR; ++ ++ // Run the custom setup ++ if (port->ops.create_link) { ++ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, port->ops.kind); ++ if (r < 0) { ++ ERROR("Could not open IFLA_INFO_DATA container: %s\n", strerror(-r)); ++ goto ERROR; ++ } ++ ++ r = port->ops.create_link(port, m); ++ if (r) { ++ ERROR("Could not create port %s: %m\n", port->name); ++ goto ERROR; ++ } ++ ++ // Close the container ++ r = sd_netlink_message_close_container(m); ++ if (r < 0) ++ goto ERROR; ++ ++ // Just set IFLA_INFO_KIND if there is no custom function ++ } else { ++ r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, port->ops.kind); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ // Close the container ++ r = sd_netlink_message_close_container(m); ++ if (r < 0) ++ goto ERROR; ++ ++ // Send the message ++ r = sd_netlink_call_async(rtnl, NULL, m, __nw_port_create_link, ++ __nw_port_unref, nw_port_ref(port), -1, NULL); ++ if (r < 0) { ++ ERROR("Could not send netlink message: %s\n", strerror(-r)); ++ goto ERROR; ++ } ++ ++ r = 0; ++ ++ERROR: ++ if (m) ++ sd_netlink_message_unref(m); ++ if (link) ++ nw_link_unref(link); + + return r; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 5253d69..d44ecb6 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_PORT_H + #define NETWORKD_PORT_H + ++#include ++ + #ifndef IF_NAMESIZE + #define IF_NAMESIZE 16 + #endif +@@ -45,12 +47,18 @@ typedef struct nw_port nw_port; + #include "daemon.h" + + typedef struct nw_port_ops { ++ // IFLA_INFO_KIND/IFLA_INFO_DATA ++ const char* kind; ++ + // Configuration + int (*config_read)(nw_port* port); + int (*config_write)(nw_port* port); + ++ // Get Parent Port ++ nw_port* (*get_parent_port)(nw_port* port); ++ + // Link +- int (*create_link)(nw_port* port); ++ int (*create_link)(nw_port* port, sd_netlink_message* message); + int (*destroy_link)(nw_port* port); + } nw_port_ops_t; + +-- +2.39.2 + diff --git a/network/patches/0240-ports-Rename-the-ops-struct-as-we-will-need-to-store.patch b/network/patches/0240-ports-Rename-the-ops-struct-as-we-will-need-to-store.patch new file mode 100644 index 000000000..45390b028 --- /dev/null +++ b/network/patches/0240-ports-Rename-the-ops-struct-as-we-will-need-to-store.patch @@ -0,0 +1,219 @@ +From 89f8f6af09b8ebf897ca6f91a3abb3b3f40fcaad Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 16:42:11 +0000 +Subject: [PATCH 240/304] ports: Rename the ops struct as we will need to store + more things than function pointers + +Signed-off-by: Michael Tremer +--- + src/networkd/port-dummy.c | 2 +- + src/networkd/port-dummy.h | 2 +- + src/networkd/port-vlan.c | 17 ++++++++++------- + src/networkd/port-vlan.h | 2 +- + src/networkd/port.c | 24 ++++++++++++------------ + src/networkd/port.h | 27 ++++++++++++++++----------- + 6 files changed, 41 insertions(+), 33 deletions(-) + +diff --git a/src/networkd/port-dummy.c b/src/networkd/port-dummy.c +index 09367d8..d6842d0 100644 +--- a/src/networkd/port-dummy.c ++++ b/src/networkd/port-dummy.c +@@ -20,6 +20,6 @@ + + #include "port-dummy.h" + +-nw_port_ops_t nw_port_ops_dummy = { ++nw_port_info_t nw_port_info_dummy = { + .kind = "dummy", + }; +diff --git a/src/networkd/port-dummy.h b/src/networkd/port-dummy.h +index 0a29c84..b07cf39 100644 +--- a/src/networkd/port-dummy.h ++++ b/src/networkd/port-dummy.h +@@ -23,6 +23,6 @@ + + #include "port.h" + +-extern nw_port_ops_t nw_port_ops_dummy; ++extern nw_port_info_t nw_port_info_dummy; + + #endif /* NETWORKD_PORT_DUMMY_H */ +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index edf91d9..f1cd9fb 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -77,17 +77,20 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { + return 0; + } + +-nw_port_ops_t nw_port_ops_vlan = { ++nw_port_info_t nw_port_info_vlan = { + .kind = "vlan", + +- // Configuration +- .config_read = nw_port_vlan_config_read, +- .config_write = nw_port_vlan_config_write, ++ // Operations ++ .ops = { ++ // Configuration ++ .config_read = nw_port_vlan_config_read, ++ .config_write = nw_port_vlan_config_write, + +- .get_parent_port = nw_port_get_vlan_parent, ++ .get_parent_port = nw_port_get_vlan_parent, + +- // Link +- .create_link = nw_port_vlan_create_link, ++ // Link ++ .create_link = nw_port_vlan_create_link, ++ }, + }; + + /* +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index 2bacb24..c666dfb 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -23,7 +23,7 @@ + + #include "port.h" + +-extern nw_port_ops_t nw_port_ops_vlan; ++extern nw_port_info_t nw_port_info_vlan; + + // ID + int nw_port_get_vlan_id(nw_port* port); +diff --git a/src/networkd/port.c b/src/networkd/port.c +index a7cbab6..061e13c 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -168,8 +168,8 @@ static int nw_port_setup(nw_port* port) { + goto ERROR; + + // Call any custom initialization +- if (port->ops.config_read) { +- r = port->ops.config_read(port); ++ if (NW_PORT_OPS(port)->config_read) { ++ r = NW_PORT_OPS(port)->config_read(port); + if (r) + goto ERROR; + } +@@ -201,11 +201,11 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const + // Set operations + switch (p->type) { + case NW_PORT_DUMMY: +- p->ops = nw_port_ops_dummy; ++ p->info = &nw_port_info_dummy; + break; + + case NW_PORT_VLAN: +- p->ops = nw_port_ops_vlan; ++ p->info = &nw_port_info_vlan; + break; + } + +@@ -339,8 +339,8 @@ int nw_port_save(nw_port* port) { + int r; + + // Call the custom handler +- if (port->ops.config_write) { +- r = port->ops.config_write(port); ++ if (NW_PORT_OPS(port)->config_write) { ++ r = NW_PORT_OPS(port)->config_write(port); + if (r) + goto ERROR; + } +@@ -429,11 +429,11 @@ static nw_link* nw_port_get_parent_link(nw_port* port) { + nw_link* link = NULL; + + // Do nothing if not implemented +- if (!port->ops.get_parent_port) ++ if (!NW_PORT_OPS(port)->get_parent_port) + goto ERROR; + + // Fetch the parent +- parent = port->ops.get_parent_port(port); ++ parent = NW_PORT_OPS(port)->get_parent_port(port); + if (!parent) + goto ERROR; + +@@ -502,14 +502,14 @@ static int nw_port_create_link(nw_port* port) { + goto ERROR; + + // Run the custom setup +- if (port->ops.create_link) { +- r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, port->ops.kind); ++ if (NW_PORT_OPS(port)->create_link) { ++ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, NW_PORT_INFO(port)->kind); + if (r < 0) { + ERROR("Could not open IFLA_INFO_DATA container: %s\n", strerror(-r)); + goto ERROR; + } + +- r = port->ops.create_link(port, m); ++ r = NW_PORT_OPS(port)->create_link(port, m); + if (r) { + ERROR("Could not create port %s: %m\n", port->name); + goto ERROR; +@@ -522,7 +522,7 @@ static int nw_port_create_link(nw_port* port) { + + // Just set IFLA_INFO_KIND if there is no custom function + } else { +- r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, port->ops.kind); ++ r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, NW_PORT_INFO(port)->kind); + if (r < 0) + goto ERROR; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index d44ecb6..b73c5fe 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -46,21 +46,26 @@ typedef struct nw_port nw_port; + #include "config.h" + #include "daemon.h" + +-typedef struct nw_port_ops { ++typedef struct nw_port_info { + // IFLA_INFO_KIND/IFLA_INFO_DATA + const char* kind; + +- // Configuration +- int (*config_read)(nw_port* port); +- int (*config_write)(nw_port* port); ++ struct nw_port_ops { ++ // Configuration ++ int (*config_read)(nw_port* port); ++ int (*config_write)(nw_port* port); + +- // Get Parent Port +- nw_port* (*get_parent_port)(nw_port* port); ++ // Get Parent Port ++ nw_port* (*get_parent_port)(nw_port* port); + +- // Link +- int (*create_link)(nw_port* port, sd_netlink_message* message); +- int (*destroy_link)(nw_port* port); +-} nw_port_ops_t; ++ // Link ++ int (*create_link)(nw_port* port, sd_netlink_message* message); ++ int (*destroy_link)(nw_port* port); ++ } ops; ++} nw_port_info_t; ++ ++#define NW_PORT_INFO(port) (port->info) ++#define NW_PORT_OPS(port) (&NW_PORT_INFO(port)->ops) + + struct nw_port { + nw_daemon* daemon; +@@ -79,7 +84,7 @@ struct nw_port { + nw_address_t address; + + // Type Operations +- nw_port_ops_t ops; ++ nw_port_info_t* info; + + // VLAN settings + struct nw_port_vlan { +-- +2.39.2 + diff --git a/network/patches/0241-ports-Implement-listing-ports-over-DBus.patch b/network/patches/0241-ports-Implement-listing-ports-over-DBus.patch new file mode 100644 index 000000000..8c08bc270 --- /dev/null +++ b/network/patches/0241-ports-Implement-listing-ports-over-DBus.patch @@ -0,0 +1,256 @@ +From 4c99b8ed5da20ba81845486bbcb9a841b7cd2119 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 16:50:35 +0000 +Subject: [PATCH 241/304] ports: Implement listing ports over DBus + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkctl/main.c | 2 + + src/networkctl/port.c | 97 +++++++++++++++++++++++++++++++++++++++ + src/networkctl/port.h | 26 +++++++++++ + src/networkd/daemon-bus.c | 51 ++++++++++++++++++++ + 5 files changed, 178 insertions(+) + create mode 100644 src/networkctl/port.c + create mode 100644 src/networkctl/port.h + +diff --git a/Makefile.am b/Makefile.am +index aafa59c..273302b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -392,6 +392,8 @@ dist_networkctl_SOURCES = \ + src/networkctl/command.c \ + src/networkctl/command.h \ + src/networkctl/main.c \ ++ src/networkctl/port.c \ ++ src/networkctl/port.h \ + src/networkctl/zone.c \ + src/networkctl/zone.h + +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index a08256c..73908f8 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -26,6 +26,7 @@ + #include + + #include "command.h" ++#include "port.h" + #include "zone.h" + + static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { +@@ -35,6 +36,7 @@ static int networkctl_status(sd_bus* bus, int argc, char* argv[]) { + + static int networkctl_main(sd_bus* bus, int argc, char* argv[]) { + static const struct command commands[] = { ++ { "port", 0, networkctl_port }, + { "status", 0, networkctl_status }, + { "zone", 0, networkctl_zone }, + { NULL }, +diff --git a/src/networkctl/port.c b/src/networkctl/port.c +new file mode 100644 +index 0000000..689e2f1 +--- /dev/null ++++ b/src/networkctl/port.c +@@ -0,0 +1,97 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "command.h" ++#include "port.h" ++ ++typedef int (*networkctl_port_walk_callback) ++ (sd_bus* bus, const char* path, const char* name, void* data); ++ ++static int networkctl_port_walk(sd_bus* bus, ++ networkctl_port_walk_callback callback, void* data) { ++ sd_bus_message* reply = NULL; ++ sd_bus_error error = SD_BUS_ERROR_NULL; ++ int r; ++ ++ // Call Listports ++ r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1", ++ "org.ipfire.network1", "ListPorts", &error, &reply, ""); ++ if (r < 0) { ++ fprintf(stderr, "Listports call failed: %m\n"); ++ goto ERROR; ++ } ++ ++ const char* name = NULL; ++ const char* path = NULL; ++ ++ // Open the container ++ r = sd_bus_message_enter_container(reply, 'a', "(so)"); ++ if (r < 0) { ++ fprintf(stderr, "Could not open container: %m\n"); ++ goto ERROR; ++ } ++ ++ // Iterate over all ports ++ for (;;) { ++ r = sd_bus_message_read(reply, "(so)", &name, &path); ++ if (r < 0) ++ goto ERROR; ++ ++ // Break if we reached the end of the container ++ if (r == 0) ++ break; ++ ++ // Call the callback ++ r = callback(bus, path, name, data); ++ if (r) ++ goto ERROR; ++ } ++ ++ // Close the container ++ sd_bus_message_exit_container(reply); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ sd_bus_error_free(&error); ++ ++ return r; ++} ++ ++static int __networkctl_port_list(sd_bus* bus, const char* path, const char* name, void* data) { ++ printf("%s\n", name); ++ ++ return 0; ++} ++ ++static int networkctl_port_list(sd_bus* bus, int argc, char* argv[]) { ++ return networkctl_port_walk(bus, __networkctl_port_list, NULL); ++} ++ ++int networkctl_port(sd_bus* bus, int argc, char* argv[]) { ++ static const struct command commands[] = { ++ { "list", 0, networkctl_port_list }, ++ { NULL }, ++ }; ++ ++ return command_dispatch(bus, commands, argc, argv); ++} +diff --git a/src/networkctl/port.h b/src/networkctl/port.h +new file mode 100644 +index 0000000..2326ce6 +--- /dev/null ++++ b/src/networkctl/port.h +@@ -0,0 +1,26 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKCTL_PORT_H ++#define NETWORKCTL_PORT_H ++ ++int networkctl_port(sd_bus* bus, int argc, char* argv[]); ++ ++#endif /* NETWORKCTL_PORT_H */ +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +index 7620eed..4de8c0f 100644 +--- a/src/networkd/daemon-bus.c ++++ b/src/networkd/daemon-bus.c +@@ -39,6 +39,55 @@ static int nw_daemon_bus_reload(sd_bus_message* m, void* data, sd_bus_error* err + return sd_bus_reply_method_return(m, NULL); + } + ++static int __nw_daemon_bus_list_ports(nw_daemon* daemon, nw_port* port, void* data) { ++ sd_bus_message* reply = (sd_bus_message*)data; ++ int r; ++ ++ // Fetch port name ++ const char* name = nw_port_name(port); ++ ++ // Fetch bus path ++ char* path = nw_port_bus_path(port); ++ ++ r = sd_bus_message_append(reply, "(so)", name, path); ++ ++ free(path); ++ ++ return r; ++} ++ ++static int nw_daemon_bus_list_ports(sd_bus_message* m, void* data, sd_bus_error* error) { ++ nw_daemon* daemon = (nw_daemon*)data; ++ sd_bus_message* reply = NULL; ++ int r; ++ ++ // Form a reply message ++ r = sd_bus_message_new_method_return(m, &reply); ++ if (r < 0) ++ goto ERROR; ++ ++ r = sd_bus_message_open_container(reply, 'a', "(so)"); ++ if (r < 0) ++ goto ERROR; ++ ++ r = nw_daemon_ports_walk(daemon, __nw_daemon_bus_list_ports, reply); ++ if (r < 0) ++ goto ERROR; ++ ++ r = sd_bus_message_close_container(reply); ++ if (r < 0) ++ goto ERROR; ++ ++ // Send the reply ++ r = sd_bus_send(NULL, reply, NULL); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ ++ return r; ++} ++ + static int __nw_daemon_bus_list_zones(nw_daemon* daemon, nw_zone* zone, void* data) { + sd_bus_message* reply = (sd_bus_message*)data; + int r; +@@ -90,6 +139,8 @@ ERROR: + + static const sd_bus_vtable daemon_vtable[] = { + SD_BUS_VTABLE_START(0), ++ SD_BUS_METHOD_WITH_ARGS("ListPorts", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links), ++ nw_daemon_bus_list_ports, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("ListZones", SD_BUS_NO_ARGS, SD_BUS_RESULT("a(so)", links), + nw_daemon_bus_list_zones, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("Reload", SD_BUS_NO_ARGS, SD_BUS_NO_RESULT, +-- +2.39.2 + diff --git a/network/patches/0242-daemon-Fix-return-code-handling-when-listing-ports-z.patch b/network/patches/0242-daemon-Fix-return-code-handling-when-listing-ports-z.patch new file mode 100644 index 000000000..ad4948402 --- /dev/null +++ b/network/patches/0242-daemon-Fix-return-code-handling-when-listing-ports-z.patch @@ -0,0 +1,56 @@ +From 78b41a2319c3c247a0223187edaea4c9ba98e83b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 16:52:59 +0000 +Subject: [PATCH 242/304] daemon: Fix return code handling when listing + ports/zones + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon-bus.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/daemon-bus.c b/src/networkd/daemon-bus.c +index 4de8c0f..f5f7abd 100644 +--- a/src/networkd/daemon-bus.c ++++ b/src/networkd/daemon-bus.c +@@ -49,9 +49,17 @@ static int __nw_daemon_bus_list_ports(nw_daemon* daemon, nw_port* port, void* da + // Fetch bus path + char* path = nw_port_bus_path(port); + ++ // Append the port to the message + r = sd_bus_message_append(reply, "(so)", name, path); ++ if (r < 0) ++ goto ERROR; + +- free(path); ++ // Success ++ r = 0; ++ ++ERROR: ++ if (path) ++ free(path); + + return r; + } +@@ -98,9 +106,17 @@ static int __nw_daemon_bus_list_zones(nw_daemon* daemon, nw_zone* zone, void* da + // Fetch bus path + char* path = nw_zone_bus_path(zone); + ++ // Append the zone to the message + r = sd_bus_message_append(reply, "(so)", name, path); ++ if (r < 0) ++ goto ERROR; + +- free(path); ++ // Success ++ r = 0; ++ ++ERROR: ++ if (path) ++ free(path); + + return r; + } +-- +2.39.2 + diff --git a/network/patches/0243-ports-Do-not-expect-to-come-back-after-creating-link.patch b/network/patches/0243-ports-Do-not-expect-to-come-back-after-creating-link.patch new file mode 100644 index 000000000..53d7548f5 --- /dev/null +++ b/network/patches/0243-ports-Do-not-expect-to-come-back-after-creating-link.patch @@ -0,0 +1,32 @@ +From 895f7134d55c38f3059e88e128d5670187222e69 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 17:05:06 +0000 +Subject: [PATCH 243/304] ports: Do not expect to come back after creating + links + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 061e13c..c87ed59 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -566,11 +566,8 @@ int nw_port_reconfigure(nw_port* port) { + } + + // If there is no link, we will try to create it +- if (!port->link) { +- r = nw_port_create_link(port); +- if (r) +- return r; +- } ++ if (!port->link) ++ return nw_port_create_link(port); + + // XXX TODO + +-- +2.39.2 + diff --git a/network/patches/0244-ports-Set-the-configure-MAC-address-when-creating-li.patch b/network/patches/0244-ports-Set-the-configure-MAC-address-when-creating-li.patch new file mode 100644 index 000000000..f979cdc40 --- /dev/null +++ b/network/patches/0244-ports-Set-the-configure-MAC-address-when-creating-li.patch @@ -0,0 +1,34 @@ +From 1574bc0061fa712150316d7bc77954f3264363f8 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 17:09:01 +0000 +Subject: [PATCH 244/304] ports: Set the configure MAC address when creating + links + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index c87ed59..891b831 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -486,7 +486,14 @@ static int nw_port_create_link(nw_port* port) { + goto ERROR; + } + +- // XXX Set common things like MAC address, etc. ++ // XXX Set common things like MTU, etc. ++ ++ // Set MAC address ++ r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, &port->address); ++ if (r < 0) { ++ ERROR("Could not set MAC address: %s\n", strerror(-r)); ++ goto ERROR; ++ } + + // Fetch the parent link + link = nw_port_get_parent_link(port); +-- +2.39.2 + diff --git a/network/patches/0245-ports-Show-message-when-creating-ports.patch b/network/patches/0245-ports-Show-message-when-creating-ports.patch new file mode 100644 index 000000000..ee3cf696a --- /dev/null +++ b/network/patches/0245-ports-Show-message-when-creating-ports.patch @@ -0,0 +1,26 @@ +From 575d1a3f407c29ab5b388d11ba94424adb86423a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 17:10:34 +0000 +Subject: [PATCH 245/304] ports: Show message when creating ports + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 891b831..dfce5b6 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -472,6 +472,8 @@ static int nw_port_create_link(nw_port* port) { + + sd_netlink* rtnl = nw_daemon_get_rtnl(port->daemon); + ++ DEBUG("Creating port %s...\n", port->name); ++ + // Create a new link + r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0); + if (r < 0) { +-- +2.39.2 + diff --git a/network/patches/0246-ports-Constify-info-struct.patch b/network/patches/0246-ports-Constify-info-struct.patch new file mode 100644 index 000000000..5cc786617 --- /dev/null +++ b/network/patches/0246-ports-Constify-info-struct.patch @@ -0,0 +1,80 @@ +From 5ddde002bc70617e45632ddc3dfdcf792a2ee745 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 17:12:52 +0000 +Subject: [PATCH 246/304] ports: Constify info struct + +Signed-off-by: Michael Tremer +--- + src/networkd/port-dummy.c | 2 +- + src/networkd/port-dummy.h | 2 +- + src/networkd/port-vlan.c | 2 +- + src/networkd/port-vlan.h | 2 +- + src/networkd/port.h | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/port-dummy.c b/src/networkd/port-dummy.c +index d6842d0..e71e740 100644 +--- a/src/networkd/port-dummy.c ++++ b/src/networkd/port-dummy.c +@@ -20,6 +20,6 @@ + + #include "port-dummy.h" + +-nw_port_info_t nw_port_info_dummy = { ++const nw_port_info_t nw_port_info_dummy = { + .kind = "dummy", + }; +diff --git a/src/networkd/port-dummy.h b/src/networkd/port-dummy.h +index b07cf39..b74c991 100644 +--- a/src/networkd/port-dummy.h ++++ b/src/networkd/port-dummy.h +@@ -23,6 +23,6 @@ + + #include "port.h" + +-extern nw_port_info_t nw_port_info_dummy; ++extern const nw_port_info_t nw_port_info_dummy; + + #endif /* NETWORKD_PORT_DUMMY_H */ +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index f1cd9fb..5e970e9 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -77,7 +77,7 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { + return 0; + } + +-nw_port_info_t nw_port_info_vlan = { ++const nw_port_info_t nw_port_info_vlan = { + .kind = "vlan", + + // Operations +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index c666dfb..f02c529 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -23,7 +23,7 @@ + + #include "port.h" + +-extern nw_port_info_t nw_port_info_vlan; ++extern const nw_port_info_t nw_port_info_vlan; + + // ID + int nw_port_get_vlan_id(nw_port* port); +diff --git a/src/networkd/port.h b/src/networkd/port.h +index b73c5fe..8bc4db8 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -84,7 +84,7 @@ struct nw_port { + nw_address_t address; + + // Type Operations +- nw_port_info_t* info; ++ const nw_port_info_t* info; + + // VLAN settings + struct nw_port_vlan { +-- +2.39.2 + diff --git a/network/patches/0247-ports-Log-when-we-created-a-random-Ethernet-address.patch b/network/patches/0247-ports-Log-when-we-created-a-random-Ethernet-address.patch new file mode 100644 index 000000000..df9d75b6a --- /dev/null +++ b/network/patches/0247-ports-Log-when-we-created-a-random-Ethernet-address.patch @@ -0,0 +1,50 @@ +From d667fff47beb1fbdf570006b112e64500528a139 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 4 Jun 2023 17:19:19 +0000 +Subject: [PATCH 247/304] ports: Log when we created a random Ethernet address + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index dfce5b6..d5ffe42 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -67,6 +67,7 @@ static void nw_port_free(nw_port* port) { + } + + static int nw_port_setup_address(nw_port* port) { ++ char* __address = NULL; + int r; + + // Read ADDRESS from configuration +@@ -100,6 +101,15 @@ ERROR: + return r; + } + ++ // Format the generated address ++ __address = nw_address_to_string(&port->address); ++ if (__address) { ++ ERROR("Generated a random Ethernet address for %s: %s\n", port->name, __address); ++ ++ // Free the address ++ free(__address); ++ } ++ + return 0; + } + +@@ -490,7 +500,7 @@ static int nw_port_create_link(nw_port* port) { + + // XXX Set common things like MTU, etc. + +- // Set MAC address ++ // Set Ethernet address + r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, &port->address); + if (r < 0) { + ERROR("Could not set MAC address: %s\n", strerror(-r)); +-- +2.39.2 + diff --git a/network/patches/0248-ports-Add-the-most-basic-supports-for-bonding.patch b/network/patches/0248-ports-Add-the-most-basic-supports-for-bonding.patch new file mode 100644 index 000000000..8e75993b1 --- /dev/null +++ b/network/patches/0248-ports-Add-the-most-basic-supports-for-bonding.patch @@ -0,0 +1,309 @@ +From 95c5dca23c2fa6326cdc59736f48f20e40ed3561 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 14:51:41 +0000 +Subject: [PATCH 248/304] ports: Add the most basic supports for bonding + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/port-bonding.c | 142 ++++++++++++++++++++++++++++++++++++ + src/networkd/port-bonding.h | 37 ++++++++++ + src/networkd/port.c | 7 ++ + src/networkd/port.h | 10 ++- + 5 files changed, 196 insertions(+), 2 deletions(-) + create mode 100644 src/networkd/port-bonding.c + create mode 100644 src/networkd/port-bonding.h + +diff --git a/Makefile.am b/Makefile.am +index 273302b..ad42f49 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -330,6 +330,8 @@ dist_networkd_SOURCES = \ + src/networkd/ports.h \ + src/networkd/port.c \ + src/networkd/port.h \ ++ src/networkd/port-bonding.c \ ++ src/networkd/port-bonding.h \ + src/networkd/port-bus.c \ + src/networkd/port-bus.h \ + src/networkd/port-dummy.c \ +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +new file mode 100644 +index 0000000..6bddc43 +--- /dev/null ++++ b/src/networkd/port-bonding.c +@@ -0,0 +1,142 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "config.h" ++#include "daemon.h" ++#include "logging.h" ++#include "port.h" ++#include "port-bonding.h" ++#include "string.h" ++ ++const struct nw_port_bonding_mode { ++ const int mode; ++ const char* string; ++} nw_port_bonding_modes[] = { ++ { BOND_MODE_ROUNDROBIN, "round-robin" }, ++ { BOND_MODE_ACTIVEBACKUP, "active-backup" }, ++ { BOND_MODE_XOR, "xor" }, ++ { BOND_MODE_BROADCAST, "broadcast" }, ++ { BOND_MODE_8023AD, "802.3ad" }, ++ { BOND_MODE_TLB, "tlb" }, ++ { BOND_MODE_ALB, "alb" }, ++ { -1, NULL }, ++}; ++ ++static int nw_port_bonding_mode_from_string(const char* string) { ++ const struct nw_port_bonding_mode* m = NULL; ++ ++ for (m = nw_port_bonding_modes; m->string; m++) { ++ if (strcmp(m->string, string) == 0) ++ return m->mode; ++ } ++ ++ return -1; ++} ++ ++static const char* nw_port_bonding_mode_to_string(const int mode) { ++ const struct nw_port_bonding_mode* m = NULL; ++ ++ for (m = nw_port_bonding_modes; m->string; m++) { ++ if (m->mode == mode) ++ return m->string; ++ } ++ ++ return NULL; ++} ++ ++static int nw_port_bonding_config_read(nw_port* port) { ++ int r; ++ ++ // Mode ++ const char* mode = nw_config_get(port->config, "BONDING_MODE"); ++ if (mode) { ++ r = nw_port_bonding_set_mode(port, mode); ++ if (r) ++ return r; ++ } ++ ++ return 0; ++} ++ ++static int nw_port_bonding_config_write(nw_port* port) { ++ int r; ++ ++ // Mode ++ r = nw_config_set(port->config, "BONDING_MODE", ++ nw_port_bonding_mode_to_string(port->bonding.mode)); ++ if (r) ++ return r; ++ ++ return 0; ++} ++ ++static int nw_port_bonding_create_link(nw_port* port, sd_netlink_message* m) { ++ int r; ++ ++ // Set mode ++ r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, port->bonding.mode); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++const nw_port_info_t nw_port_info_bonding = { ++ .kind = "bond", ++ ++ // Operations ++ .ops = { ++ // Configuration ++ .config_read = nw_port_bonding_config_read, ++ .config_write = nw_port_bonding_config_write, ++ ++ // Link ++ .create_link = nw_port_bonding_create_link, ++ }, ++}; ++ ++const char* nw_port_bonding_get_mode(nw_port* port) { ++ return nw_port_bonding_mode_to_string(port->bonding.mode); ++} ++ ++int nw_port_bonding_set_mode(nw_port* port, const char* mode) { ++ const int m = nw_port_bonding_mode_from_string(mode); ++ ++ switch (m) { ++ case BOND_MODE_ROUNDROBIN: ++ case BOND_MODE_ACTIVEBACKUP: ++ case BOND_MODE_XOR: ++ case BOND_MODE_BROADCAST: ++ case BOND_MODE_8023AD: ++ case BOND_MODE_TLB: ++ case BOND_MODE_ALB: ++ port->bonding.mode = m; ++ break; ++ ++ default: ++ ERROR("%s: Unsupported bonding mode '%s'\n", port->name, mode); ++ errno = ENOTSUP; ++ return 1; ++ } ++ ++ return 0; ++} +diff --git a/src/networkd/port-bonding.h b/src/networkd/port-bonding.h +new file mode 100644 +index 0000000..5cd2c43 +--- /dev/null ++++ b/src/networkd/port-bonding.h +@@ -0,0 +1,37 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_BONDING_H ++#define NETWORKD_PORT_BONDING_H ++ ++#include ++ ++#include "port.h" ++ ++struct nw_port_bonding { ++ int mode; ++}; ++ ++extern const nw_port_info_t nw_port_info_bonding; ++ ++const char* nw_port_bonding_get_mode(nw_port* port); ++int nw_port_bonding_set_mode(nw_port* port, const char* mode); ++ ++#endif /* NETWORKD_PORT_BONDING_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index d5ffe42..b44cc88 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -30,6 +30,7 @@ + #include "link.h" + #include "logging.h" + #include "port.h" ++#include "port-bonding.h" + #include "port-dummy.h" + #include "port-vlan.h" + #include "stats-collector.h" +@@ -39,6 +40,7 @@ static const struct nw_port_type_map { + nw_port_type_t type; + const char* name; + } nw_port_type_map[] = { ++ { NW_PORT_BONDING, "bonding" }, + { NW_PORT_DUMMY, "dummy" }, + { NW_PORT_VLAN, "vlan" }, + { NW_PORT_UNKNOWN, NULL }, +@@ -210,6 +212,10 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const + + // Set operations + switch (p->type) { ++ case NW_PORT_BONDING: ++ p->info = &nw_port_info_bonding; ++ break; ++ + case NW_PORT_DUMMY: + p->info = &nw_port_info_dummy; + break; +@@ -337,6 +343,7 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + } + break; + ++ case NW_PORT_BONDING: + case NW_PORT_DUMMY: + case NW_PORT_UNKNOWN: + break; +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 8bc4db8..f8beed3 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -31,6 +31,7 @@ + + typedef enum nw_port_type { + NW_PORT_UNKNOWN = 0, ++ NW_PORT_BONDING, + NW_PORT_DUMMY, + NW_PORT_VLAN, + } nw_port_type_t; +@@ -41,12 +42,14 @@ typedef enum nw_port_type { + #define NW_VLAN_ID_MAX 4096 + + typedef struct nw_port nw_port; ++typedef struct nw_port_info nw_port_info_t; + + #include "address.h" + #include "config.h" + #include "daemon.h" ++#include "port-bonding.h" + +-typedef struct nw_port_info { ++struct nw_port_info { + // IFLA_INFO_KIND/IFLA_INFO_DATA + const char* kind; + +@@ -62,7 +65,7 @@ typedef struct nw_port_info { + int (*create_link)(nw_port* port, sd_netlink_message* message); + int (*destroy_link)(nw_port* port); + } ops; +-} nw_port_info_t; ++}; + + #define NW_PORT_INFO(port) (port->info) + #define NW_PORT_OPS(port) (&NW_PORT_INFO(port)->ops) +@@ -86,6 +89,9 @@ struct nw_port { + // Type Operations + const nw_port_info_t* info; + ++ // Bonding Settings ++ struct nw_port_bonding bonding; ++ + // VLAN settings + struct nw_port_vlan { + nw_port* parent; +-- +2.39.2 + diff --git a/network/patches/0249-ports-Move-VLAN-settings-into-its-own-header-file.patch b/network/patches/0249-ports-Move-VLAN-settings-into-its-own-header-file.patch new file mode 100644 index 000000000..3772a8caf --- /dev/null +++ b/network/patches/0249-ports-Move-VLAN-settings-into-its-own-header-file.patch @@ -0,0 +1,64 @@ +From 4d6ac814d5a46ca08a6f3cd6a1431a17cd65bc3e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 14:54:20 +0000 +Subject: [PATCH 249/304] ports: Move VLAN settings into its own header file + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.h | 11 +++++++++++ + src/networkd/port.h | 10 ++-------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index f02c529..cffc178 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -23,6 +23,17 @@ + + #include "port.h" + ++struct nw_port_vlan { ++ nw_port* parent; ++ ++ // The VLAN ID ++ int id; ++ ++ // If the parent has not been read from the configuration we will ++ // save the name and try to find it later. ++ char __parent_name[IF_NAMESIZE]; ++}; ++ + extern const nw_port_info_t nw_port_info_vlan; + + // ID +diff --git a/src/networkd/port.h b/src/networkd/port.h +index f8beed3..21e2a12 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -48,6 +48,7 @@ typedef struct nw_port_info nw_port_info_t; + #include "config.h" + #include "daemon.h" + #include "port-bonding.h" ++#include "port-vlan.h" + + struct nw_port_info { + // IFLA_INFO_KIND/IFLA_INFO_DATA +@@ -93,14 +94,7 @@ struct nw_port { + struct nw_port_bonding bonding; + + // VLAN settings +- struct nw_port_vlan { +- nw_port* parent; +- int id; +- +- // If the parent has not been read from the configuration we will +- // save the name and try to find it later. +- char __parent_name[IF_NAMESIZE]; +- } vlan; ++ struct nw_port_vlan vlan; + }; + + int nw_port_create(nw_port** port, nw_daemon* daemon, +-- +2.39.2 + diff --git a/network/patches/0250-networkctl-Fix-typo-in-bus-method-name.patch b/network/patches/0250-networkctl-Fix-typo-in-bus-method-name.patch new file mode 100644 index 000000000..89c6ff5ea --- /dev/null +++ b/network/patches/0250-networkctl-Fix-typo-in-bus-method-name.patch @@ -0,0 +1,26 @@ +From 0744719e820e526593c5c7c0b4b86ce756509333 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 14:55:00 +0000 +Subject: [PATCH 250/304] networkctl: Fix typo in bus method name + +Signed-off-by: Michael Tremer +--- + src/networkctl/port.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/networkctl/port.c b/src/networkctl/port.c +index 689e2f1..3a886ff 100644 +--- a/src/networkctl/port.c ++++ b/src/networkctl/port.c +@@ -36,7 +36,7 @@ static int networkctl_port_walk(sd_bus* bus, + r = sd_bus_call_method(bus, "org.ipfire.network1", "/org/ipfire/network1", + "org.ipfire.network1", "ListPorts", &error, &reply, ""); + if (r < 0) { +- fprintf(stderr, "Listports call failed: %m\n"); ++ fprintf(stderr, "ListPorts call failed: %m\n"); + goto ERROR; + } + +-- +2.39.2 + diff --git a/network/patches/0251-ports-Implement-a-function-the-generally-fetches-the.patch b/network/patches/0251-ports-Implement-a-function-the-generally-fetches-the.patch new file mode 100644 index 000000000..bc749276e --- /dev/null +++ b/network/patches/0251-ports-Implement-a-function-the-generally-fetches-the.patch @@ -0,0 +1,163 @@ +From 5a5c346c5dac343ec8242adcd04f1fbe542640ff Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 16:47:14 +0000 +Subject: [PATCH 251/304] ports: Implement a function the generally fetches the + parent port + +Signed-off-by: Michael Tremer +--- + src/networkd/json.h | 89 +++++++++++++++++++++++++++++++++++++++++++++ + src/networkd/port.c | 17 +++++---- + src/networkd/port.h | 2 + + 3 files changed, 101 insertions(+), 7 deletions(-) + create mode 100644 src/networkd/json.h + +diff --git a/src/networkd/json.h b/src/networkd/json.h +new file mode 100644 +index 0000000..33e237a +--- /dev/null ++++ b/src/networkd/json.h +@@ -0,0 +1,89 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_JSON_H ++#define NETWORKD_JSON_H ++ ++#include ++ ++#include ++ ++// Give some sane names to the reference count functions ++#define json_object_ref json_object_get ++#define json_object_unref json_object_put ++ ++static inline int __json_object_add(struct json_object* o, ++ const char* key, struct json_object* value) { ++ int r; ++ ++ // Add the object ++ r = json_object_object_add(o, key, value); ++ if (r < 0) { ++ if (value) ++ json_object_unref(value); ++ } ++ ++ return r; ++} ++ ++static inline int json_object_add_string(struct json_object* o, ++ const char* key, const char* value) { ++ struct json_object* element = NULL; ++ ++ // Create a JSON object from the string ++ element = json_object_new_string(value); ++ if (!element) ++ return -errno; ++ ++ return __json_object_add(o, key, element); ++} ++ ++static inline int json_object_add_int64(struct json_object* o, ++ const char* key, const int64_t value) { ++ struct json_object* element = NULL; ++ ++ // Create a JSON object ++ element = json_object_new_int64(value); ++ if (!element) ++ return -errno; ++ ++ return __json_object_add(o, key, element); ++} ++ ++static inline int json_to_string(struct json_object* o, char** s, size_t* l) { ++ // Format JSON to string ++ const char* buffer = json_object_to_json_string_ext(o, ++ JSON_C_TO_STRING_PRETTY|JSON_C_TO_STRING_PRETTY_TAB); ++ if (!buffer) ++ return -errno; ++ ++ // Copy the string to the heap ++ *s = strdup(buffer); ++ if (!*s) ++ return -errno; ++ ++ // If requested, store the length of the string ++ if (l) ++ *l = strlen(*s); ++ ++ return 0; ++} ++ ++#endif /* NETWORKD_JSON_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index b44cc88..c9440d4 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -441,23 +441,26 @@ static int nw_port_is_disabled(nw_port* port) { + return nw_config_get_bool(port->config, "DISABLED"); + } + ++nw_port* nw_port_get_parent_port(nw_port* port) { ++ if (!NW_PORT_OPS(port)->get_parent_port) ++ return NULL; ++ ++ return NW_PORT_OPS(port)->get_parent_port(port); ++} ++ + static nw_link* nw_port_get_parent_link(nw_port* port) { + nw_port* parent = NULL; + nw_link* link = NULL; + +- // Do nothing if not implemented +- if (!NW_PORT_OPS(port)->get_parent_port) +- goto ERROR; +- + // Fetch the parent +- parent = NW_PORT_OPS(port)->get_parent_port(port); ++ parent = nw_port_get_parent_port(port); + if (!parent) +- goto ERROR; ++ return NULL; + + // Fetch the link + link = nw_port_get_link(parent); + +-ERROR: ++ // Cleanup + if (parent) + nw_port_unref(parent); + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 21e2a12..38d19d1 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -119,6 +119,8 @@ int __nw_port_drop_link(nw_daemon* daemon, nw_port* port, void* data); + + const nw_address_t* nw_port_get_address(nw_port* port); + ++nw_port* nw_port_get_parent_port(nw_port* port); ++ + int nw_port_reconfigure(nw_port* port); + + int nw_port_has_carrier(nw_port* port); +-- +2.39.2 + diff --git a/network/patches/0252-config-Compare-truthiness-case-insensitively.patch b/network/patches/0252-config-Compare-truthiness-case-insensitively.patch new file mode 100644 index 000000000..528a6ef4f --- /dev/null +++ b/network/patches/0252-config-Compare-truthiness-case-insensitively.patch @@ -0,0 +1,26 @@ +From 8923434ceb4264fea6044564ca7254bd28cf106e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 16:47:41 +0000 +Subject: [PATCH 252/304] config: Compare truthiness case-insensitively + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 8269ede..78448df 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -407,7 +407,7 @@ int nw_config_get_bool(nw_config* config, const char* key) { + + // Check if we match any known true words + for (const char** s = nw_config_true; *s; s++) { +- if (strcmp(value, *s) == 0) ++ if (strcasecmp(value, *s) == 0) + return 1; + } + +-- +2.39.2 + diff --git a/network/patches/0253-configure-Depend-on-JSON-C.patch b/network/patches/0253-configure-Depend-on-JSON-C.patch new file mode 100644 index 000000000..0e485e0a9 --- /dev/null +++ b/network/patches/0253-configure-Depend-on-JSON-C.patch @@ -0,0 +1,46 @@ +From 6384cfdf37f873154f695f6cac67fe1926b5bad8 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 16:48:30 +0000 +Subject: [PATCH 253/304] configure: Depend on JSON-C + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + configure.ac | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index ad42f49..466ad73 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -357,6 +357,7 @@ networkd_CPPFLAGS = \ + networkd_CFLAGS = \ + $(AM_CFLAGS) \ + $(CAP_CFLAGS) \ ++ $(JSON_C_CFLAGS) \ + $(SYSTEMD_CFLAGS) + + networkd_LDFLAGS = \ +@@ -365,6 +366,7 @@ networkd_LDFLAGS = \ + networkd_LDADD = \ + src/libnetwork.la \ + $(CAP_LIBS) \ ++ $(JSON_C_LIBS) \ + $(SYSTEMD_LIBS) + + dist_dbuspolicy_DATA += \ +diff --git a/configure.ac b/configure.ac +index e1baa64..7883ae9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -173,6 +173,7 @@ AM_CONDITIONAL(HAVE_UDEV, [test -n "$with_udevdir"]) + # ------------------------------------------------------------------------------ + + PKG_CHECK_MODULES([CAP], [libcap]) ++PKG_CHECK_MODULES([JSON_C], [json-c]) + PKG_CHECK_MODULES([LIBNL], [libnl-3.0 libnl-genl-3.0]) + PKG_CHECK_MODULES([SYSTEMD], [libsystemd]) + +-- +2.39.2 + diff --git a/network/patches/0254-ports-Add-bus-method-to-export-port-information-as-J.patch b/network/patches/0254-ports-Add-bus-method-to-export-port-information-as-J.patch new file mode 100644 index 000000000..e1650a218 --- /dev/null +++ b/network/patches/0254-ports-Add-bus-method-to-export-port-information-as-J.patch @@ -0,0 +1,302 @@ +From e9b0614e1d653a733c76a3246fd800566e3e1561 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Mon, 5 Jun 2023 16:48:43 +0000 +Subject: [PATCH 254/304] ports: Add bus method to export port information as + JSON + +Signed-off-by: Michael Tremer +--- + Makefile.am | 1 + + src/networkd/port-bonding.c | 16 +++++++++++ + src/networkd/port-bus.c | 46 +++++++++++++++++++++++++++++++ + src/networkd/port-vlan.c | 28 +++++++++++++++++++ + src/networkd/port.c | 55 +++++++++++++++++++++++++++++++++++++ + src/networkd/port.h | 9 ++++++ + 6 files changed, 155 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 466ad73..f4c22b4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -319,6 +319,7 @@ dist_networkd_SOURCES = \ + src/networkd/daemon-bus.h \ + src/networkd/devmon.c \ + src/networkd/devmon.h \ ++ src/networkd/json.h \ + src/networkd/link.c \ + src/networkd/link.h \ + src/networkd/links.c \ +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index 6bddc43..bbc3fb7 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -100,6 +100,19 @@ static int nw_port_bonding_create_link(nw_port* port, sd_netlink_message* m) { + return 0; + } + ++static int nw_port_bonding_to_json(nw_port* port, struct json_object* o) { ++ int r; ++ ++ // Add mode ++ r = json_object_add_string(o, "BondingMode", ++ nw_port_bonding_mode_to_string(port->bonding.mode)); ++ if (r < 0) ++ goto ERROR; ++ ++ERROR: ++ return r; ++} ++ + const nw_port_info_t nw_port_info_bonding = { + .kind = "bond", + +@@ -111,6 +124,9 @@ const nw_port_info_t nw_port_info_bonding = { + + // Link + .create_link = nw_port_bonding_create_link, ++ ++ // JSON ++ .to_json = nw_port_bonding_to_json, + }, + }; + +diff --git a/src/networkd/port-bus.c b/src/networkd/port-bus.c +index 996be92..41f8ec4 100644 +--- a/src/networkd/port-bus.c ++++ b/src/networkd/port-bus.c +@@ -20,10 +20,12 @@ + + #include + #include ++#include + + #include "address.h" + #include "bus.h" + #include "daemon.h" ++#include "json.h" + #include "logging.h" + #include "port.h" + #include "port-bus.h" +@@ -105,6 +107,46 @@ ERROR: + return r; + } + ++static int nw_port_bus_describe(sd_bus_message* message, void* data, ++ sd_bus_error* error) { ++ sd_bus_message* reply = NULL; ++ struct json_object* json = NULL; ++ char* text = NULL; ++ int r; ++ ++ nw_port* port = (nw_port*)data; ++ ++ // Export all data to JSON ++ r = nw_port_to_json(port, &json); ++ if (r < 0) ++ goto ERROR; ++ ++ // Convert JSON to string ++ r = json_to_string(json, &text, NULL); ++ if (r < 0) ++ goto ERROR; ++ ++ // Create a reply message ++ r = sd_bus_message_new_method_return(message, &reply); ++ if (r < 0) ++ goto ERROR; ++ ++ r = sd_bus_message_append(reply, "s", text); ++ if (r < 0) ++ goto ERROR; ++ ++ // Send the reply ++ r = sd_bus_send(NULL, reply, NULL); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ if (text) ++ free(text); ++ ++ return r; ++} ++ + static const sd_bus_vtable port_vtable[] = { + SD_BUS_VTABLE_START(0), + +@@ -112,6 +154,10 @@ static const sd_bus_vtable port_vtable[] = { + SD_BUS_PROPERTY("Address", "s", nw_port_bus_get_address, + 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + ++ // Operations ++ SD_BUS_METHOD_WITH_ARGS("Describe", SD_BUS_NO_ARGS, SD_BUS_RESULT("s", json), ++ nw_port_bus_describe, SD_BUS_VTABLE_UNPRIVILEGED), ++ + SD_BUS_VTABLE_END + }; + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 5e970e9..ac4a5b4 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -22,6 +22,7 @@ + + #include "config.h" + #include "daemon.h" ++#include "json.h" + #include "logging.h" + #include "port.h" + #include "port-vlan.h" +@@ -77,6 +78,30 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { + return 0; + } + ++static int nw_port_vlan_to_json(nw_port* port, struct json_object* o) { ++ nw_port* parent = NULL; ++ int r; ++ ++ // Add the VLAN ID ++ r = json_object_add_int64(o, "VLANId", port->vlan.id); ++ if (r < 0) ++ goto ERROR; ++ ++ // Fetch the parent ++ parent = nw_port_get_parent_port(port); ++ if (parent) { ++ r = json_object_add_string(o, "VLANParentPort", nw_port_name(parent)); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ERROR: ++ if (parent) ++ nw_port_unref(parent); ++ ++ return r; ++} ++ + const nw_port_info_t nw_port_info_vlan = { + .kind = "vlan", + +@@ -90,6 +115,9 @@ const nw_port_info_t nw_port_info_vlan = { + + // Link + .create_link = nw_port_vlan_create_link, ++ ++ // JSON ++ .to_json = nw_port_vlan_to_json, + }, + }; + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index c9440d4..a7fb826 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -27,6 +27,7 @@ + + #include "address.h" + #include "config.h" ++#include "json.h" + #include "link.h" + #include "logging.h" + #include "port.h" +@@ -645,3 +646,57 @@ int nw_port_check_type(nw_port* port, const nw_port_type_t type) { + errno = ENOTSUP; + return -errno; + } ++ ++/* ++ JSON ++*/ ++int nw_port_to_json(nw_port* port, struct json_object** object) { ++ char* address = NULL; ++ int r; ++ ++ // Create a new JSON object ++ struct json_object* o = json_object_new_object(); ++ if (!o) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Add name ++ r = json_object_add_string(o, "Name", port->name); ++ if (r < 0) ++ goto ERROR; ++ ++ // Add Type ++ r = json_object_add_string(o, "Type", NW_PORT_INFO(port)->kind); ++ if (r < 0) ++ goto ERROR; ++ ++ // Add address ++ address = nw_address_to_string(&port->address); ++ if (address) { ++ r = json_object_add_string(o, "Address", address); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ // Call custom stuff ++ if (NW_PORT_OPS(port)->to_json) { ++ r = NW_PORT_OPS(port)->to_json(port, o); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ // Success ++ r = 0; ++ ++ // Return a reference to the created object ++ *object = json_object_ref(o); ++ ++ERROR: ++ if (address) ++ free(address); ++ if (o) ++ json_object_unref(o); ++ ++ return r; ++} +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 38d19d1..e16b957 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -21,6 +21,8 @@ + #ifndef NETWORKD_PORT_H + #define NETWORKD_PORT_H + ++#include ++ + #include + + #ifndef IF_NAMESIZE +@@ -47,6 +49,7 @@ typedef struct nw_port_info nw_port_info_t; + #include "address.h" + #include "config.h" + #include "daemon.h" ++#include "json.h" + #include "port-bonding.h" + #include "port-vlan.h" + +@@ -65,6 +68,9 @@ struct nw_port_info { + // Link + int (*create_link)(nw_port* port, sd_netlink_message* message); + int (*destroy_link)(nw_port* port); ++ ++ // JSON ++ int (*to_json)(nw_port* port, struct json_object* object); + } ops; + }; + +@@ -132,4 +138,7 @@ const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); + int __nw_port_update_stats(nw_daemon* daemon, nw_port* port, void* data); + int nw_port_update_stats(nw_port* port); + ++// JSON ++int nw_port_to_json(nw_port* port, struct json_object** object); ++ + #endif /* NETWORKD_PORT_H */ +-- +2.39.2 + diff --git a/network/patches/0255-networkctl-Fix-parsing-commands.patch b/network/patches/0255-networkctl-Fix-parsing-commands.patch new file mode 100644 index 000000000..77544697d --- /dev/null +++ b/network/patches/0255-networkctl-Fix-parsing-commands.patch @@ -0,0 +1,52 @@ +From d4028bc3f6b422a45f8f2ad41df2e59152474b6e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Tue, 6 Jun 2023 10:24:08 +0000 +Subject: [PATCH 255/304] networkctl: Fix parsing commands + +We used to send the argument that was last parsed to the next function +which probably isn't very useful. + +Signed-off-by: Michael Tremer +--- + src/networkctl/command.c | 6 +----- + src/networkctl/main.c | 2 +- + 2 files changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/networkctl/command.c b/src/networkctl/command.c +index 7114efe..99202dd 100644 +--- a/src/networkctl/command.c ++++ b/src/networkctl/command.c +@@ -36,10 +36,6 @@ static const struct command* command_find(const struct command* commands, const + int command_dispatch(sd_bus* bus, const struct command* commands, int argc, char* argv[]) { + const struct command* command = NULL; + +- argc -= optind; +- argv += optind; +- optind = 1; +- + if (!argc) { + fprintf(stderr, "Command required\n"); + return -EINVAL; +@@ -54,5 +50,5 @@ int command_dispatch(sd_bus* bus, const struct command* commands, int argc, char + return -EINVAL; + } + +- return command->callback(bus, argc, argv); ++ return command->callback(bus, argc - 1, argv + 1); + } +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 73908f8..0ba7284 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -115,7 +115,7 @@ int main(int argc, char* argv[]) { + } + + // Run a command +- r = networkctl_main(bus, argc, argv); ++ r = networkctl_main(bus, argc - 1, argv + 1); + + ERROR: + if (bus) +-- +2.39.2 + diff --git a/network/patches/0256-networkctl-Implement-dump-command-for-ports-which-sh.patch b/network/patches/0256-networkctl-Implement-dump-command-for-ports-which-sh.patch new file mode 100644 index 000000000..45fd3b24d --- /dev/null +++ b/network/patches/0256-networkctl-Implement-dump-command-for-ports-which-sh.patch @@ -0,0 +1,94 @@ +From d566048705bb24b12d46fa4ed7cf9352286d8086 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Tue, 6 Jun 2023 10:24:45 +0000 +Subject: [PATCH 256/304] networkctl: Implement "dump" command for ports which + shows the JSON + +This is just for debugging purposes. + +Signed-off-by: Michael Tremer +--- + src/networkctl/port.c | 51 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/src/networkctl/port.c b/src/networkctl/port.c +index 3a886ff..67bc003 100644 +--- a/src/networkctl/port.c ++++ b/src/networkctl/port.c +@@ -18,8 +18,11 @@ + # # + #############################################################################*/ + ++#include ++ + #include + ++#include "../networkd/string.h" + #include "command.h" + #include "port.h" + +@@ -77,6 +80,53 @@ ERROR: + return r; + } + ++// Dump ++ ++static int networkctl_port_dump(sd_bus* bus, int argc, char* argv[]) { ++ sd_bus_message* reply = NULL; ++ sd_bus_error error = SD_BUS_ERROR_NULL; ++ char path[PATH_MAX]; ++ const char* text = NULL; ++ int r; ++ ++ if (argc < 1) { ++ fprintf(stderr, "Port required\n"); ++ return -EINVAL; ++ } ++ ++ // Make port path ++ r = nw_string_format(path, "/org/ipfire/network1/port/%s", argv[0]); ++ if (r < 0) ++ goto ERROR; ++ ++ // Call Describe ++ r = sd_bus_call_method(bus, "org.ipfire.network1", path, ++ "org.ipfire.network1.Port", "Describe", &error, &reply, ""); ++ if (r < 0) { ++ fprintf(stderr, "Describe() call failed: %m\n"); ++ goto ERROR; ++ } ++ ++ // Read the text ++ r = sd_bus_message_read(reply, "s", &text); ++ if (r < 0) { ++ fprintf(stderr, "Could not parse bus message: %s\n", strerror(-r)); ++ goto ERROR; ++ } ++ ++ // Print the text ++ if (text) ++ printf("%s\n", text); ++ ++ERROR: ++ if (reply) ++ sd_bus_message_unref(reply); ++ ++ return r; ++} ++ ++// List ++ + static int __networkctl_port_list(sd_bus* bus, const char* path, const char* name, void* data) { + printf("%s\n", name); + +@@ -89,6 +139,7 @@ static int networkctl_port_list(sd_bus* bus, int argc, char* argv[]) { + + int networkctl_port(sd_bus* bus, int argc, char* argv[]) { + static const struct command commands[] = { ++ { "dump", 0, networkctl_port_dump }, + { "list", 0, networkctl_port_list }, + { NULL }, + }; +-- +2.39.2 + diff --git a/network/patches/0257-string-Add-macros-to-easily-define-string-table-look.patch b/network/patches/0257-string-Add-macros-to-easily-define-string-table-look.patch new file mode 100644 index 000000000..29a80be49 --- /dev/null +++ b/network/patches/0257-string-Add-macros-to-easily-define-string-table-look.patch @@ -0,0 +1,70 @@ +From f9975100fdb9b9d66d9f21436e7973f9824bbcde Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 7 Jun 2023 13:16:58 +0000 +Subject: [PATCH 257/304] string: Add macros to easily define string table + lookups + +Signed-off-by: Michael Tremer +--- + src/networkd/string.h | 45 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 5bdfc3d..d94e270 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -125,6 +125,51 @@ static inline void nw_string_empty(char* s) { + *s = '\0'; + } + ++/* ++ Tables ++*/ ++ ++struct nw_string_table { ++ const int id; ++ const char* string; ++}; ++ ++static inline const char* nw_string_table_lookup_string( ++ const struct nw_string_table* table, const int id) { ++ const struct nw_string_table* entry = NULL; ++ ++ for (entry = table; entry->string; entry++) ++ if (entry->id == id) ++ return entry->string; ++ ++ return NULL; ++} ++ ++static inline int nw_string_table_lookup_id( ++ const struct nw_string_table* table, const char* string) { ++ const struct nw_string_table* entry = NULL; ++ ++ for (entry = table; entry->string; entry++) ++ if (strcmp(entry->string, string) == 0) ++ return entry->id; ++ ++ return -1; ++} ++ ++#define NW_STRING_TABLE_LOOKUP_ID(type, table, method) \ ++ __attribute__((unused)) static type method(const char* s) { \ ++ return nw_string_table_lookup_id(table, s); \ ++ } ++ ++#define NW_STRING_TABLE_LOOKUP_STRING(type, table, method) \ ++ __attribute__((unused)) static const char* method(const type id) { \ ++ return nw_string_table_lookup_string(table, id); \ ++ } ++ ++#define NW_STRING_TABLE_LOOKUP(type, table) \ ++ NW_STRING_TABLE_LOOKUP_ID(type, table, table ## _from_string) \ ++ NW_STRING_TABLE_LOOKUP_STRING(type, table, table ## _to_string) ++ + /* + Paths + */ +-- +2.39.2 + diff --git a/network/patches/0258-ports-VLAN-Implement-choosing-a-protocol.patch b/network/patches/0258-ports-VLAN-Implement-choosing-a-protocol.patch new file mode 100644 index 000000000..ac95117c0 --- /dev/null +++ b/network/patches/0258-ports-VLAN-Implement-choosing-a-protocol.patch @@ -0,0 +1,156 @@ +From d872e169c7d38b741b0fd01796202a19357d622c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Wed, 7 Jun 2023 13:17:36 +0000 +Subject: [PATCH 258/304] ports: VLAN: Implement choosing a protocol + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.c | 49 ++++++++++++++++++++++++++++++++++++++++ + src/networkd/port-vlan.h | 14 ++++++++++++ + 2 files changed, 63 insertions(+) + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index ac4a5b4..6e13ba9 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -18,6 +18,8 @@ + # # + #############################################################################*/ + ++#include ++ + #include + + #include "config.h" +@@ -28,6 +30,14 @@ + #include "port-vlan.h" + #include "string.h" + ++const struct nw_string_table nw_port_vlan_proto[] = { ++ { NW_VLAN_PROTO_8021Q, "802.1Q" }, ++ { NW_VLAN_PROTO_8021ad, "802.1ad" }, ++ { -1, NULL }, ++}; ++ ++NW_STRING_TABLE_LOOKUP(nw_port_vlan_proto_t, nw_port_vlan_proto) ++ + static int nw_port_vlan_config_read(nw_port* port) { + int r; + +@@ -39,6 +49,14 @@ static int nw_port_vlan_config_read(nw_port* port) { + return r; + } + ++ // VLAN Protocol ++ const char* proto = nw_config_get(port->config, "VLAN_PROTO"); ++ if (proto) { ++ r = nw_port_set_vlan_proto(port, nw_port_vlan_proto_from_string(proto)); ++ if (r) ++ return r; ++ } ++ + // Parent Port + const char* parent = nw_config_get(port->config, "VLAN_PARENT"); + if (parent) { +@@ -58,6 +76,12 @@ static int nw_port_vlan_config_write(nw_port* port) { + if (r) + return r; + ++ // VLAN Protocol ++ r = nw_config_set(port->config, "VLAN_PROTO", ++ nw_port_vlan_proto_to_string(port->vlan.proto)); ++ if (r) ++ return r; ++ + // Parent Port + r = nw_config_set(port->config, "VLAN_PARENT", + (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); +@@ -75,6 +99,11 @@ static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { + if (r < 0) + return r; + ++ // Set VLAN protocol ++ r = sd_netlink_message_append_u16(m, IFLA_VLAN_PROTOCOL, htobe16(port->vlan.proto)); ++ if (r < 0) ++ return r; ++ + return 0; + } + +@@ -87,6 +116,12 @@ static int nw_port_vlan_to_json(nw_port* port, struct json_object* o) { + if (r < 0) + goto ERROR; + ++ // Add the VLAN Protocol ++ r = json_object_add_string(o, "VLANProtocol", ++ nw_port_vlan_proto_to_string(port->vlan.proto)); ++ if (r < 0) ++ goto ERROR; ++ + // Fetch the parent + parent = nw_port_get_parent_port(port); + if (parent) { +@@ -155,6 +190,20 @@ int nw_port_set_vlan_id(nw_port* port, int id) { + return 0; + } + ++int nw_port_set_vlan_proto(nw_port* port, const nw_port_vlan_proto_t proto) { ++ switch (proto) { ++ case NW_VLAN_PROTO_8021Q: ++ case NW_VLAN_PROTO_8021ad: ++ port->vlan.proto = proto; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + nw_port* nw_port_get_vlan_parent(nw_port* port) { + int r; + +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index cffc178..17d3134 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -21,14 +21,25 @@ + #ifndef NETWORKD_PORT_VLAN_H + #define NETWORKD_PORT_VLAN_H + ++#include ++#include ++ + #include "port.h" + ++typedef enum nw_port_vlan_proto { ++ NW_VLAN_PROTO_8021Q = ETH_P_8021Q, ++ NW_VLAN_PROTO_8021ad = ETH_P_8021AD, ++} nw_port_vlan_proto_t; ++ + struct nw_port_vlan { + nw_port* parent; + + // The VLAN ID + int id; + ++ // Protocol ++ nw_port_vlan_proto_t proto; ++ + // If the parent has not been read from the configuration we will + // save the name and try to find it later. + char __parent_name[IF_NAMESIZE]; +@@ -40,6 +51,9 @@ extern const nw_port_info_t nw_port_info_vlan; + int nw_port_get_vlan_id(nw_port* port); + int nw_port_set_vlan_id(nw_port* port, int id); + ++// Protocol ++int nw_port_set_vlan_proto(nw_port* port, const nw_port_vlan_proto_t proto); ++ + // Parent Port + nw_port* nw_port_get_vlan_parent(nw_port* port); + int nw_port_set_vlan_parent(nw_port* port, nw_port* parent); +-- +2.39.2 + diff --git a/network/patches/0259-config-Extend-the-parser-to-easier-read-write-config.patch b/network/patches/0259-config-Extend-the-parser-to-easier-read-write-config.patch new file mode 100644 index 000000000..6b593b0f3 --- /dev/null +++ b/network/patches/0259-config-Extend-the-parser-to-easier-read-write-config.patch @@ -0,0 +1,716 @@ +From 082d81a3b4115422a0d58fe8c3cf504350c76bfe Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:04:38 +0000 +Subject: [PATCH 259/304] config: Extend the parser to easier read/write + configs + +Signed-off-by: Michael Tremer +--- + src/networkd/address.h | 6 +- + src/networkd/config.c | 197 +++++++++++++++++++++++++++++++++++- + src/networkd/config.h | 38 +++++++ + src/networkd/port-bonding.c | 34 ++++--- + src/networkd/port-vlan.c | 57 ++++------- + src/networkd/port.c | 113 ++++++--------------- + src/networkd/port.h | 5 +- + 7 files changed, 313 insertions(+), 137 deletions(-) + +diff --git a/src/networkd/address.h b/src/networkd/address.h +index 7937d62..afcbca1 100644 +--- a/src/networkd/address.h ++++ b/src/networkd/address.h +@@ -21,6 +21,7 @@ + #ifndef NETWORKD_ADDRESS_H + #define NETWORKD_ADDRESS_H + ++#include + #include + #include + #include +@@ -35,9 +36,12 @@ enum { + }; + + static inline int nw_address_from_string(nw_address_t* addr, const char* s) { ++ if (!s) ++ return -EINVAL; ++ + struct ether_addr* p = ether_aton_r(s, addr); + if (!p) +- return 1; ++ return -errno; + + return 0; + } +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 78448df..6f22da2 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -26,6 +26,7 @@ + #include + #include + ++#include "address.h" + #include "config.h" + #include "logging.h" + #include "string.h" +@@ -37,19 +38,37 @@ struct nw_config_entry { + char value[NETWORK_CONFIG_KEY_MAX_LENGTH]; + }; + ++struct nw_config_option { ++ STAILQ_ENTRY(nw_config_option) nodes; ++ ++ const char* key; ++ void* data; ++ ++ // Callbacks ++ nw_config_option_read_callback_t read_callback; ++ nw_config_option_write_callback_t write_callback; ++}; ++ + struct nw_config { + int nrefs; + + // The path to the configuration file + char path[PATH_MAX]; + +- STAILQ_HEAD(entries, nw_config_entry) entries; ++ STAILQ_HEAD(config_entries, nw_config_entry) entries; ++ ++ // Options ++ STAILQ_HEAD(parser_entries, nw_config_option) options; + }; + + static void nw_config_entry_free(struct nw_config_entry* entry) { + free(entry); + } + ++static void nw_config_option_free(struct nw_config_option* option) { ++ free(option); ++} ++ + static struct nw_config_entry* nw_config_entry_create( + nw_config* config, const char* key) { + int r; +@@ -81,9 +100,20 @@ ERROR: + } + + static void nw_config_free(nw_config* config) { ++ struct nw_config_option* option = NULL; ++ + // Flush all entries + nw_config_flush(config); + ++ // Free all options ++ while (!STAILQ_EMPTY(&config->options)) { ++ option = STAILQ_FIRST(&config->options); ++ STAILQ_REMOVE_HEAD(&config->options, nodes); ++ ++ // Free the options ++ nw_config_option_free(option); ++ } ++ + free(config); + } + +@@ -100,6 +130,9 @@ int nw_config_create(nw_config** config, const char* path) { + // Initialise entries + STAILQ_INIT(&c->entries); + ++ // Initialise options ++ STAILQ_INIT(&c->options); ++ + // Store the path + if (path) { + r = nw_string_set(c->path, path); +@@ -147,6 +180,33 @@ int nw_config_destroy(nw_config* config) { + return unlink(config->path); + } + ++int nw_config_copy(nw_config* config, nw_config** copy) { ++ struct nw_config_entry* entry = NULL; ++ nw_config* c = NULL; ++ int r; ++ ++ // Create a new configuration ++ r = nw_config_create(&c, NULL); ++ if (r) ++ return r; ++ ++ // Copy everything ++ STAILQ_FOREACH(entry, &config->entries, nodes) { ++ r = nw_config_set(c, entry->key, entry->value); ++ if (r) ++ goto ERROR; ++ } ++ ++ *copy = c; ++ return 0; ++ ++ERROR: ++ if (c) ++ nw_config_unref(c); ++ ++ return r; ++} ++ + const char* nw_config_path(nw_config* config) { + if (*config->path) + return config->path; +@@ -341,6 +401,9 @@ const char* nw_config_get(nw_config* config, const char* key) { + int nw_config_set(nw_config* config, const char* key, const char* value) { + struct nw_config_entry* entry = NULL; + ++ // Log the change ++ DEBUG("%p: Setting %s = %s\n", config, key, value); ++ + // Delete the entry if val is NULL + if (!value) + return nw_config_del(config, key); +@@ -418,3 +481,135 @@ int nw_config_get_bool(nw_config* config, const char* key) { + int nw_config_set_bool(nw_config* config, const char* key, const int value) { + return nw_config_set(config, key, value ? "true" : "false"); + } ++ ++/* ++ Options ++*/ ++ ++int nw_config_options_read(nw_config* config) { ++ struct nw_config_option* option = NULL; ++ int r; ++ ++ STAILQ_FOREACH(option, &config->options, nodes) { ++ r = option->read_callback(config, option->key, option->data); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ ++int nw_config_options_write(nw_config* config) { ++ struct nw_config_option* option = NULL; ++ int r; ++ ++ STAILQ_FOREACH(option, &config->options, nodes) { ++ r = option->write_callback(config, option->key, option->data); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ ++int nw_config_option_add(nw_config* config, const char* key, void* data, ++ nw_config_option_read_callback_t read_callback, ++ nw_config_option_write_callback_t write_callback) { ++ // Check input ++ if (!key || !data || !read_callback || !write_callback) ++ return -EINVAL; ++ ++ // Allocate a new option ++ struct nw_config_option* option = calloc(1, sizeof(*option)); ++ if (!option) ++ return -errno; ++ ++ // Set key ++ option->key = key; ++ ++ // Set data ++ option->data = data; ++ ++ // Set callbacks ++ option->read_callback = read_callback; ++ option->write_callback = write_callback; ++ ++ // Append the new option ++ STAILQ_INSERT_TAIL(&config->options, option, nodes); ++ ++ return 0; ++} ++ ++int nw_config_read_int(nw_config* config, const char* key, void* data) { ++ int* p = (int*)data; ++ ++ // Fetch the value ++ *p = nw_config_get_int(config, key, -1); ++ ++ return 0; ++} ++ ++int nw_config_write_int(nw_config* config, const char* key, const void* data) { ++ return 0; ++} ++ ++// String ++ ++int nw_config_read_string(nw_config* config, const char* key, void* data) { ++ const char** p = (const char**)data; ++ ++ // Fetch the value ++ const char* value = nw_config_get(config, key); ++ if (value) ++ *p = value; ++ ++ return 0; ++} ++ ++int nw_config_write_string(nw_config* config, const char* key, const void* data) { ++ const char** value = (const char**)data; ++ ++ return nw_config_set(config, key, *value); ++} ++ ++// Address ++ ++int nw_config_read_address(nw_config* config, const char* key, void* data) { ++ nw_address_t* address = (nw_address_t*)data; ++ int r; ++ ++ // Fetch the value ++ const char* value = nw_config_get(config, key); ++ if (!value) ++ return -EINVAL; ++ ++ r = nw_address_from_string(address, value); ++ if (r < 0) ++ ERROR("Could not parse address: %s\n", value); ++ ++ return r; ++} ++ ++int nw_config_write_address(nw_config* config, const char* key, const void* data) { ++ const nw_address_t* address = (nw_address_t*)data; ++ int r; ++ ++ // Format the address to string ++ char* value = nw_address_to_string(address); ++ if (!value) ++ return -errno; ++ ++ // Store the value ++ r = nw_config_set(config, key, value); ++ if (r < 0) ++ goto ERROR; ++ ++ // Success ++ r = 0; ++ ++ERROR: ++ if (value) ++ free(value); ++ ++ return r; ++} +diff --git a/src/networkd/config.h b/src/networkd/config.h +index e17c016..b5417e4 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -34,6 +34,7 @@ nw_config* nw_config_ref(nw_config* config); + nw_config* nw_config_unref(nw_config* config); + + int nw_config_destroy(nw_config* config); ++int nw_config_copy(nw_config* config, nw_config** copy); + + const char* nw_config_path(nw_config* config); + +@@ -53,4 +54,41 @@ int nw_config_set_int(nw_config* config, const char* key, const int value); + int nw_config_get_bool(nw_config* config, const char* key); + int nw_config_set_bool(nw_config* config, const char* key, const int value); + ++/* ++ Options ++*/ ++ ++int nw_config_options_read(nw_config* config); ++int nw_config_options_write(nw_config* config); ++ ++typedef int (*nw_config_option_read_callback_t) ++ (nw_config* config, const char* key, void* data); ++typedef int (*nw_config_option_write_callback_t) ++ (nw_config* config, const char* key, const void* data); ++ ++int nw_config_option_add(nw_config* config, const char* key, void* value, ++ nw_config_option_read_callback_t read_callback, ++ nw_config_option_write_callback_t write_callback); ++ ++#define NW_CONFIG_OPTION(config, key, data, read_callback, write_callback) \ ++ nw_config_option_add(config, key, data, read_callback, write_callback) ++ ++#define NW_CONFIG_OPTION_STRING(config, key, data) \ ++ nw_config_option_add(config, key, data, nw_config_read_string, nw_config_write_string) ++ ++int nw_config_read_string(nw_config* config, const char* key, void* data); ++int nw_config_write_string(nw_config* config, const char* key, const void* data); ++ ++#define NW_CONFIG_OPTION_INT(config, key, data) \ ++ nw_config_option_add(config, key, data, nw_config_read_int, nw_config_write_int) ++ ++int nw_config_read_int(nw_config* config, const char* key, void* data); ++int nw_config_write_int(nw_config* config, const char* key, const void* data); ++ ++#define NW_CONFIG_OPTION_ADDRESS(config, key, data) \ ++ nw_config_option_add(config, key, data, nw_config_read_address, nw_config_write_address) ++ ++int nw_config_read_address(nw_config* config, const char* key, void* data); ++int nw_config_write_address(nw_config* config, const char* key, const void* data); ++ + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index bbc3fb7..a2e0fc3 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -63,27 +63,32 @@ static const char* nw_port_bonding_mode_to_string(const int mode) { + return NULL; + } + +-static int nw_port_bonding_config_read(nw_port* port) { +- int r; +- +- // Mode +- const char* mode = nw_config_get(port->config, "BONDING_MODE"); +- if (mode) { +- r = nw_port_bonding_set_mode(port, mode); +- if (r) +- return r; ++static int nw_port_bonding_read_mode(nw_config* config, const char* key, void* data) { ++ int* mode = (int*)data; ++ ++ const char* value = nw_config_get(config, key); ++ if (value) { ++ *mode = nw_port_bonding_mode_from_string(value); ++ if (!*mode) ++ return -errno; + } + + return 0; + } + +-static int nw_port_bonding_config_write(nw_port* port) { ++static int nw_port_bonding_write_mode(nw_config* config, const char* key, const void* data) { ++ const int* mode = (int*)data; ++ ++ return nw_config_set(config, key, nw_port_bonding_mode_to_string(*mode)); ++} ++ ++static int nw_port_bonding_setup(nw_port* port) { + int r; + + // Mode +- r = nw_config_set(port->config, "BONDING_MODE", +- nw_port_bonding_mode_to_string(port->bonding.mode)); +- if (r) ++ r = NW_CONFIG_OPTION(port->config, "BONDING_MODE", &port->bonding.mode, ++ nw_port_bonding_read_mode, nw_port_bonding_write_mode); ++ if (r < 0) + return r; + + return 0; +@@ -119,8 +124,7 @@ const nw_port_info_t nw_port_info_bonding = { + // Operations + .ops = { + // Configuration +- .config_read = nw_port_bonding_config_read, +- .config_write = nw_port_bonding_config_write, ++ .setup = nw_port_bonding_setup, + + // Link + .create_link = nw_port_bonding_create_link, +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 6e13ba9..2d89a09 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -38,54 +38,42 @@ const struct nw_string_table nw_port_vlan_proto[] = { + + NW_STRING_TABLE_LOOKUP(nw_port_vlan_proto_t, nw_port_vlan_proto) + +-static int nw_port_vlan_config_read(nw_port* port) { +- int r; +- +- // VLAN ID +- int id = nw_config_get_int(port->config, "VLAN_ID", NW_VLAN_ID_INVALID); +- if (id) { +- r = nw_port_set_vlan_id(port, id); +- if (r) +- return r; ++static int nw_port_vlan_read_proto(nw_config* config, const char* key, void* data) { ++ nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)data; ++ ++ const char* value = nw_config_get(config, key); ++ if (value) { ++ *proto = nw_port_vlan_proto_from_string(data); ++ if (!*proto) ++ return -errno; + } + +- // VLAN Protocol +- const char* proto = nw_config_get(port->config, "VLAN_PROTO"); +- if (proto) { +- r = nw_port_set_vlan_proto(port, nw_port_vlan_proto_from_string(proto)); +- if (r) +- return r; +- } ++ return 0; ++} + +- // Parent Port +- const char* parent = nw_config_get(port->config, "VLAN_PARENT"); +- if (parent) { +- r = nw_string_set(port->vlan.__parent_name, parent); +- if (r) +- return r; +- } ++static int nw_port_vlan_write_proto(nw_config* config, const char* key, const void* data) { ++ const nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)data; + +- return 0; ++ return nw_config_set(config, key, nw_port_vlan_proto_to_string(*proto)); + } + +-static int nw_port_vlan_config_write(nw_port* port) { ++static int nw_port_vlan_setup(nw_port* port) { + int r; + + // VLAN ID +- r = nw_config_set_int(port->config, "VLAN_ID", port->vlan.id); +- if (r) ++ r = NW_CONFIG_OPTION_INT(port->config, "VLAN_ID", &port->vlan.id); ++ if (r < 0) + return r; + + // VLAN Protocol +- r = nw_config_set(port->config, "VLAN_PROTO", +- nw_port_vlan_proto_to_string(port->vlan.proto)); +- if (r) ++ r = NW_CONFIG_OPTION(port->config, "VLAN_PROTO", &port->vlan.proto, ++ nw_port_vlan_read_proto, nw_port_vlan_write_proto); ++ if (r < 0) + return r; + + // Parent Port +- r = nw_config_set(port->config, "VLAN_PARENT", +- (port->vlan.parent) ? nw_port_name(port->vlan.parent) : port->vlan.__parent_name); +- if (r) ++ r = NW_CONFIG_OPTION_STRING(port->config, "VLAN_PARENT", &port->vlan.__parent_name); ++ if (r < 0) + return r; + + return 0; +@@ -143,8 +131,7 @@ const nw_port_info_t nw_port_info_vlan = { + // Operations + .ops = { + // Configuration +- .config_read = nw_port_vlan_config_read, +- .config_write = nw_port_vlan_config_write, ++ .setup = nw_port_vlan_setup, + + .get_parent_port = nw_port_get_vlan_parent, + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index a7fb826..cab8fc5 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -69,64 +69,6 @@ static void nw_port_free(nw_port* port) { + free(port); + } + +-static int nw_port_setup_address(nw_port* port) { +- char* __address = NULL; +- int r; +- +- // Read ADDRESS from configuration +- const char* s = nw_config_get(port->config, "ADDRESS"); +- if (!s) { +- ERROR("Port %s: Address is not set\n", port->name); +- goto ERROR; +- } +- +- // Parse the address +- r = nw_address_from_string(&port->address, s); +- if (r) { +- ERROR("Port %s: Could not parse address: %m\n", port->name); +- goto ERROR; +- } +- +- // Check if this address is usable +- r = nw_address_is_multicast(&port->address); +- if (r) { +- DEBUG("Port %s: Multicast bit is set on Ethernet address\n", port->name); +- goto ERROR; +- } +- +- return 0; +- +-ERROR: +- // Generate a random Ethernet address +- r = nw_address_generate(&port->address); +- if (r) { +- ERROR("Could not generate a random Ethernet address: %m\n"); +- return r; +- } +- +- // Format the generated address +- __address = nw_address_to_string(&port->address); +- if (__address) { +- ERROR("Generated a random Ethernet address for %s: %s\n", port->name, __address); +- +- // Free the address +- free(__address); +- } +- +- return 0; +-} +- +-static int nw_port_setup_common(nw_port* port) { +- int r; +- +- // Address +- r = nw_port_setup_address(port); +- if (r) +- return r; +- +- return 0; +-} +- + static int nw_port_set_link(nw_port* port, nw_link* link) { + // Do nothing if the same link is being re-assigned + if (port->link == link) +@@ -154,7 +96,6 @@ static int nw_port_set_link(nw_port* port, nw_link* link) { + + static int nw_port_setup(nw_port* port) { + nw_link* link = NULL; +- char path[PATH_MAX]; + int r; + + // Find the link +@@ -165,28 +106,32 @@ static int nw_port_setup(nw_port* port) { + goto ERROR; + } + +- // Compose the path to the main configuration file +- r = nw_path_join(path, PORT_CONFIG_DIR, port->name); +- if (r) +- goto ERROR; +- +- // Initialize the configuration +- r = nw_config_create(&port->config, path); +- if (r) ++ // Generate a random Ethernet address ++ r = nw_address_generate(&port->address); ++ if (r < 0) { ++ ERROR("Could not generate an Ethernet address: %s\n", strerror(-r)); + goto ERROR; ++ } + +- // Perform some common initialization +- r = nw_port_setup_common(port); +- if (r) ++ // Setup options ++ r = NW_CONFIG_OPTION_ADDRESS(port->config, "ADDRESS", &port->address); ++ if (r < 0) + goto ERROR; + + // Call any custom initialization +- if (NW_PORT_OPS(port)->config_read) { +- r = NW_PORT_OPS(port)->config_read(port); +- if (r) ++ if (NW_PORT_OPS(port)->setup) { ++ r = NW_PORT_OPS(port)->setup(port); ++ if (r < 0) + goto ERROR; + } + ++ // Parse the configuration ++ r = nw_config_options_read(port->config); ++ if (r < 0) { ++ ERROR("Could not read configuration for port %s: %s\n", port->name, strerror(-r)); ++ goto ERROR; ++ } ++ + ERROR: + if (link) + nw_link_unref(link); +@@ -194,7 +139,8 @@ ERROR: + return r; + } + +-int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const char* name) { ++int nw_port_create(nw_port** port, nw_daemon* daemon, ++ nw_port_type_t type, const char* name, nw_config* config) { + int r; + + // Allocate a new object +@@ -231,6 +177,11 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, nw_port_type_t type, const + if (r) + goto ERROR; + ++ // Copy the configuration ++ r = nw_config_copy(config, &p->config); ++ if (r) ++ goto ERROR; ++ + // Setup the port + r = nw_port_setup(p); + if (r) +@@ -263,7 +214,7 @@ int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, + } + + // Create a new port +- r = nw_port_create(port, daemon, nw_port_type_from_string(type), name); ++ r = nw_port_create(port, daemon, nw_port_type_from_string(type), name, config); + if (r) + goto ERROR; + +@@ -356,12 +307,10 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + int nw_port_save(nw_port* port) { + int r; + +- // Call the custom handler +- if (NW_PORT_OPS(port)->config_write) { +- r = NW_PORT_OPS(port)->config_write(port); +- if (r) +- goto ERROR; +- } ++ // Write out the configuration ++ r = nw_config_options_write(port->config); ++ if (r < 0) ++ goto ERROR; + + // Write the configuration + r = nw_config_write(port->config); +@@ -371,7 +320,7 @@ int nw_port_save(nw_port* port) { + return 0; + + ERROR: +- ERROR("Could not save configuration for port %s: %m\n", port->name); ++ ERROR("Could not save configuration for port %s: %s\n", port->name, strerror(-r)); + + return 1; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index e16b957..ef68a89 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -59,8 +59,7 @@ struct nw_port_info { + + struct nw_port_ops { + // Configuration +- int (*config_read)(nw_port* port); +- int (*config_write)(nw_port* port); ++ int (*setup)(nw_port* port); + + // Get Parent Port + nw_port* (*get_parent_port)(nw_port* port); +@@ -104,7 +103,7 @@ struct nw_port { + }; + + int nw_port_create(nw_port** port, nw_daemon* daemon, +- nw_port_type_t type, const char* name); ++ nw_port_type_t type, const char* name, nw_config* config); + int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, + const char* name, const char* path); + +-- +2.39.2 + diff --git a/network/patches/0260-ports-bonding-Convert-mode-to-string-table.patch b/network/patches/0260-ports-bonding-Convert-mode-to-string-table.patch new file mode 100644 index 000000000..2723006fd --- /dev/null +++ b/network/patches/0260-ports-bonding-Convert-mode-to-string-table.patch @@ -0,0 +1,93 @@ +From 582536b21276f11b040eef80e185635b312556da Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:12:00 +0000 +Subject: [PATCH 260/304] ports: bonding: Convert mode to string table + +Signed-off-by: Michael Tremer +--- + src/networkd/port-bonding.c | 41 ++++++++----------------------------- + src/networkd/port-bonding.h | 12 ++++++++++- + 2 files changed, 20 insertions(+), 33 deletions(-) + +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index a2e0fc3..e765791 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -27,41 +27,18 @@ + #include "port-bonding.h" + #include "string.h" + +-const struct nw_port_bonding_mode { +- const int mode; +- const char* string; +-} nw_port_bonding_modes[] = { +- { BOND_MODE_ROUNDROBIN, "round-robin" }, +- { BOND_MODE_ACTIVEBACKUP, "active-backup" }, +- { BOND_MODE_XOR, "xor" }, +- { BOND_MODE_BROADCAST, "broadcast" }, +- { BOND_MODE_8023AD, "802.3ad" }, +- { BOND_MODE_TLB, "tlb" }, +- { BOND_MODE_ALB, "alb" }, ++const struct nw_string_table nw_port_bonding_mode[] = { ++ { NW_BONDING_MODE_ROUNDROBIN, "round-robin" }, ++ { NW_BONDING_MODE_ACTIVEBACKUP, "active-backup" }, ++ { NW_BONDING_MODE_XOR, "xor" }, ++ { NW_BONDING_MODE_BROADCAST, "broadcast" }, ++ { NW_BONDING_MODE_8023AD, "802.3ad" }, ++ { NW_BONDING_MODE_TLB, "tlb" }, ++ { NW_BONDING_MODE_ALB, "alb" }, + { -1, NULL }, + }; + +-static int nw_port_bonding_mode_from_string(const char* string) { +- const struct nw_port_bonding_mode* m = NULL; +- +- for (m = nw_port_bonding_modes; m->string; m++) { +- if (strcmp(m->string, string) == 0) +- return m->mode; +- } +- +- return -1; +-} +- +-static const char* nw_port_bonding_mode_to_string(const int mode) { +- const struct nw_port_bonding_mode* m = NULL; +- +- for (m = nw_port_bonding_modes; m->string; m++) { +- if (m->mode == mode) +- return m->string; +- } +- +- return NULL; +-} ++NW_STRING_TABLE_LOOKUP(nw_port_bonding_mode_t, nw_port_bonding_mode) + + static int nw_port_bonding_read_mode(nw_config* config, const char* key, void* data) { + int* mode = (int*)data; +diff --git a/src/networkd/port-bonding.h b/src/networkd/port-bonding.h +index 5cd2c43..e21c251 100644 +--- a/src/networkd/port-bonding.h ++++ b/src/networkd/port-bonding.h +@@ -25,8 +25,18 @@ + + #include "port.h" + ++typedef enum nw_port_bonding_mode { ++ NW_BONDING_MODE_ROUNDROBIN = BOND_MODE_ROUNDROBIN, ++ NW_BONDING_MODE_ACTIVEBACKUP = BOND_MODE_ACTIVEBACKUP, ++ NW_BONDING_MODE_XOR = BOND_MODE_XOR, ++ NW_BONDING_MODE_BROADCAST = BOND_MODE_BROADCAST, ++ NW_BONDING_MODE_8023AD = BOND_MODE_8023AD, ++ NW_BONDING_MODE_TLB = BOND_MODE_TLB, ++ NW_BONDING_MODE_ALB = BOND_MODE_ALB, ++} nw_port_bonding_mode_t; ++ + struct nw_port_bonding { +- int mode; ++ nw_port_bonding_mode_t mode; + }; + + extern const nw_port_info_t nw_port_info_bonding; +-- +2.39.2 + diff --git a/network/patches/0261-config-Rename-data-to-value-as-it-holds-a-reference-.patch b/network/patches/0261-config-Rename-data-to-value-as-it-holds-a-reference-.patch new file mode 100644 index 000000000..0f032586d --- /dev/null +++ b/network/patches/0261-config-Rename-data-to-value-as-it-holds-a-reference-.patch @@ -0,0 +1,221 @@ +From cc54472edbcc3a4325b9bad6eff1532bcd42c891 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:17:24 +0000 +Subject: [PATCH 261/304] config: Rename "data" to "value" as it holds a + reference to it + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 64 ++++++++++++++++++++----------------------- + src/networkd/config.h | 28 +++++++++---------- + 2 files changed, 43 insertions(+), 49 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 6f22da2..b142d17 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -42,7 +42,7 @@ struct nw_config_option { + STAILQ_ENTRY(nw_config_option) nodes; + + const char* key; +- void* data; ++ void* value; + + // Callbacks + nw_config_option_read_callback_t read_callback; +@@ -491,7 +491,7 @@ int nw_config_options_read(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->read_callback(config, option->key, option->data); ++ r = option->read_callback(config, option->key, option->value); + if (r < 0) + return r; + } +@@ -504,7 +504,7 @@ int nw_config_options_write(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->write_callback(config, option->key, option->data); ++ r = option->write_callback(config, option->key, option->value); + if (r < 0) + return r; + } +@@ -512,11 +512,11 @@ int nw_config_options_write(nw_config* config) { + return 0; + } + +-int nw_config_option_add(nw_config* config, const char* key, void* data, ++int nw_config_option_add(nw_config* config, const char* key, void* value, + nw_config_option_read_callback_t read_callback, + nw_config_option_write_callback_t write_callback) { + // Check input +- if (!key || !data || !read_callback || !write_callback) ++ if (!key || !value || !read_callback || !write_callback) + return -EINVAL; + + // Allocate a new option +@@ -527,8 +527,8 @@ int nw_config_option_add(nw_config* config, const char* key, void* data, + // Set key + option->key = key; + +- // Set data +- option->data = data; ++ // Set value ++ option->value = value; + + // Set callbacks + option->read_callback = read_callback; +@@ -540,67 +540,61 @@ int nw_config_option_add(nw_config* config, const char* key, void* data, + return 0; + } + +-int nw_config_read_int(nw_config* config, const char* key, void* data) { +- int* p = (int*)data; +- ++int nw_config_read_int(nw_config* config, const char* key, void* value) { + // Fetch the value +- *p = nw_config_get_int(config, key, -1); ++ *(int*)value = nw_config_get_int(config, key, -1); + + return 0; + } + +-int nw_config_write_int(nw_config* config, const char* key, const void* data) { ++int nw_config_write_int(nw_config* config, const char* key, const void* value) { + return 0; + } + + // String + +-int nw_config_read_string(nw_config* config, const char* key, void* data) { +- const char** p = (const char**)data; +- ++int nw_config_read_string(nw_config* config, const char* key, void* value) { + // Fetch the value +- const char* value = nw_config_get(config, key); +- if (value) +- *p = value; ++ const char* p = nw_config_get(config, key); ++ if (p) ++ *(const char**)value = p; + + return 0; + } + +-int nw_config_write_string(nw_config* config, const char* key, const void* data) { +- const char** value = (const char**)data; +- +- return nw_config_set(config, key, *value); ++int nw_config_write_string(nw_config* config, const char* key, const void* value) { ++ return nw_config_set(config, key, *(const char**)value); + } + + // Address + +-int nw_config_read_address(nw_config* config, const char* key, void* data) { +- nw_address_t* address = (nw_address_t*)data; ++int nw_config_read_address(nw_config* config, const char* key, void* value) { ++ nw_address_t* address = (nw_address_t*)value; + int r; + + // Fetch the value +- const char* value = nw_config_get(config, key); +- if (!value) ++ const char* p = nw_config_get(config, key); ++ if (!p) + return -EINVAL; + +- r = nw_address_from_string(address, value); ++ r = nw_address_from_string(address, p); + if (r < 0) +- ERROR("Could not parse address: %s\n", value); ++ ERROR("Could not parse address: %s\n", p); + + return r; + } + +-int nw_config_write_address(nw_config* config, const char* key, const void* data) { +- const nw_address_t* address = (nw_address_t*)data; ++int nw_config_write_address(nw_config* config, const char* key, const void* value) { ++ const nw_address_t* address = (nw_address_t*)value; + int r; + + // Format the address to string +- char* value = nw_address_to_string(address); +- if (!value) ++ char* p = nw_address_to_string(address); ++ if (!p) + return -errno; + + // Store the value +- r = nw_config_set(config, key, value); ++ r = nw_config_set(config, key, p); + if (r < 0) + goto ERROR; + +@@ -608,8 +602,8 @@ int nw_config_write_address(nw_config* config, const char* key, const void* data + r = 0; + + ERROR: +- if (value) +- free(value); ++ if (p) ++ free(p); + + return r; + } +diff --git a/src/networkd/config.h b/src/networkd/config.h +index b5417e4..7185038 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -62,9 +62,9 @@ int nw_config_options_read(nw_config* config); + int nw_config_options_write(nw_config* config); + + typedef int (*nw_config_option_read_callback_t) +- (nw_config* config, const char* key, void* data); ++ (nw_config* config, const char* key, void* value); + typedef int (*nw_config_option_write_callback_t) +- (nw_config* config, const char* key, const void* data); ++ (nw_config* config, const char* key, const void* value); + + int nw_config_option_add(nw_config* config, const char* key, void* value, + nw_config_option_read_callback_t read_callback, +@@ -73,22 +73,22 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + #define NW_CONFIG_OPTION(config, key, data, read_callback, write_callback) \ + nw_config_option_add(config, key, data, read_callback, write_callback) + +-#define NW_CONFIG_OPTION_STRING(config, key, data) \ +- nw_config_option_add(config, key, data, nw_config_read_string, nw_config_write_string) ++#define NW_CONFIG_OPTION_STRING(config, key, value) \ ++ nw_config_option_add(config, key, value, nw_config_read_string, nw_config_write_string) + +-int nw_config_read_string(nw_config* config, const char* key, void* data); +-int nw_config_write_string(nw_config* config, const char* key, const void* data); ++int nw_config_read_string(nw_config* config, const char* key, void* value); ++int nw_config_write_string(nw_config* config, const char* key, const void* value); + +-#define NW_CONFIG_OPTION_INT(config, key, data) \ +- nw_config_option_add(config, key, data, nw_config_read_int, nw_config_write_int) ++#define NW_CONFIG_OPTION_INT(config, key, value) \ ++ nw_config_option_add(config, key, value, nw_config_read_int, nw_config_write_int) + +-int nw_config_read_int(nw_config* config, const char* key, void* data); +-int nw_config_write_int(nw_config* config, const char* key, const void* data); ++int nw_config_read_int(nw_config* config, const char* key, void* value); ++int nw_config_write_int(nw_config* config, const char* key, const void* value); + +-#define NW_CONFIG_OPTION_ADDRESS(config, key, data) \ +- nw_config_option_add(config, key, data, nw_config_read_address, nw_config_write_address) ++#define NW_CONFIG_OPTION_ADDRESS(config, key, value) \ ++ nw_config_option_add(config, key, value, nw_config_read_address, nw_config_write_address) + +-int nw_config_read_address(nw_config* config, const char* key, void* data); +-int nw_config_write_address(nw_config* config, const char* key, const void* data); ++int nw_config_read_address(nw_config* config, const char* key, void* value); ++int nw_config_write_address(nw_config* config, const char* key, const void* value); + + #endif /* NETWORKD_CONFIG_H */ +-- +2.39.2 + diff --git a/network/patches/0262-config-Add-data-pointer-to-callbacks.patch b/network/patches/0262-config-Add-data-pointer-to-callbacks.patch new file mode 100644 index 000000000..a97c8d0ac --- /dev/null +++ b/network/patches/0262-config-Add-data-pointer-to-callbacks.patch @@ -0,0 +1,255 @@ +From 3eeb38b7ad3a343645127f11fea281ed2a22e80a Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:23:10 +0000 +Subject: [PATCH 262/304] config: Add data pointer to callbacks + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 23 ++++++++++++++--------- + src/networkd/config.h | 28 ++++++++++++++-------------- + src/networkd/port-bonding.c | 18 ++++++++++-------- + src/networkd/port-vlan.c | 18 ++++++++++-------- + 4 files changed, 48 insertions(+), 39 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index b142d17..39e9881 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -47,6 +47,7 @@ struct nw_config_option { + // Callbacks + nw_config_option_read_callback_t read_callback; + nw_config_option_write_callback_t write_callback; ++ void* data; + }; + + struct nw_config { +@@ -491,7 +492,7 @@ int nw_config_options_read(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->read_callback(config, option->key, option->value); ++ r = option->read_callback(config, option->key, option->value, option->data); + if (r < 0) + return r; + } +@@ -504,7 +505,7 @@ int nw_config_options_write(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->write_callback(config, option->key, option->value); ++ r = option->write_callback(config, option->key, option->value, option->data); + if (r < 0) + return r; + } +@@ -514,7 +515,7 @@ int nw_config_options_write(nw_config* config) { + + int nw_config_option_add(nw_config* config, const char* key, void* value, + nw_config_option_read_callback_t read_callback, +- nw_config_option_write_callback_t write_callback) { ++ nw_config_option_write_callback_t write_callback, void* data) { + // Check input + if (!key || !value || !read_callback || !write_callback) + return -EINVAL; +@@ -533,6 +534,7 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + // Set callbacks + option->read_callback = read_callback; + option->write_callback = write_callback; ++ option->data = data; + + // Append the new option + STAILQ_INSERT_TAIL(&config->options, option, nodes); +@@ -540,20 +542,21 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + return 0; + } + +-int nw_config_read_int(nw_config* config, const char* key, void* value) { ++int nw_config_read_int(nw_config* config, const char* key, void* value, void* data) { + // Fetch the value + *(int*)value = nw_config_get_int(config, key, -1); + + return 0; + } + +-int nw_config_write_int(nw_config* config, const char* key, const void* value) { ++int nw_config_write_int(nw_config* config, ++ const char* key, const void* value, void* data) { + return 0; + } + + // String + +-int nw_config_read_string(nw_config* config, const char* key, void* value) { ++int nw_config_read_string(nw_config* config, const char* key, void* value, void* data) { + // Fetch the value + const char* p = nw_config_get(config, key); + if (p) +@@ -562,13 +565,14 @@ int nw_config_read_string(nw_config* config, const char* key, void* value) { + return 0; + } + +-int nw_config_write_string(nw_config* config, const char* key, const void* value) { ++int nw_config_write_string(nw_config* config, ++ const char* key, const void* value, void* data) { + return nw_config_set(config, key, *(const char**)value); + } + + // Address + +-int nw_config_read_address(nw_config* config, const char* key, void* value) { ++int nw_config_read_address(nw_config* config, const char* key, void* value, void* data) { + nw_address_t* address = (nw_address_t*)value; + int r; + +@@ -584,7 +588,8 @@ int nw_config_read_address(nw_config* config, const char* key, void* value) { + return r; + } + +-int nw_config_write_address(nw_config* config, const char* key, const void* value) { ++int nw_config_write_address(nw_config* config, ++ const char* key, const void* value, void* data) { + const nw_address_t* address = (nw_address_t*)value; + int r; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 7185038..d6b8db8 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -62,33 +62,33 @@ int nw_config_options_read(nw_config* config); + int nw_config_options_write(nw_config* config); + + typedef int (*nw_config_option_read_callback_t) +- (nw_config* config, const char* key, void* value); ++ (nw_config* config, const char* key, void* value, void* data); + typedef int (*nw_config_option_write_callback_t) +- (nw_config* config, const char* key, const void* value); ++ (nw_config* config, const char* key, const void* value, void* data); + + int nw_config_option_add(nw_config* config, const char* key, void* value, + nw_config_option_read_callback_t read_callback, +- nw_config_option_write_callback_t write_callback); ++ nw_config_option_write_callback_t write_callback, void* data); + +-#define NW_CONFIG_OPTION(config, key, data, read_callback, write_callback) \ +- nw_config_option_add(config, key, data, read_callback, write_callback) ++#define NW_CONFIG_OPTION(config, key, value, read_callback, write_callback, data) \ ++ nw_config_option_add(config, key, value, read_callback, write_callback, data) + + #define NW_CONFIG_OPTION_STRING(config, key, value) \ +- nw_config_option_add(config, key, value, nw_config_read_string, nw_config_write_string) ++ nw_config_option_add(config, key, value, nw_config_read_string, nw_config_write_string, NULL) + +-int nw_config_read_string(nw_config* config, const char* key, void* value); +-int nw_config_write_string(nw_config* config, const char* key, const void* value); ++int nw_config_read_string(nw_config* config, const char* key, void* value, void* data); ++int nw_config_write_string(nw_config* config, const char* key, const void* value, void* data); + + #define NW_CONFIG_OPTION_INT(config, key, value) \ +- nw_config_option_add(config, key, value, nw_config_read_int, nw_config_write_int) ++ nw_config_option_add(config, key, value, nw_config_read_int, nw_config_write_int, NULL) + +-int nw_config_read_int(nw_config* config, const char* key, void* value); +-int nw_config_write_int(nw_config* config, const char* key, const void* value); ++int nw_config_read_int(nw_config* config, const char* key, void* value, void* data); ++int nw_config_write_int(nw_config* config, const char* key, const void* value, void* data); + + #define NW_CONFIG_OPTION_ADDRESS(config, key, value) \ +- nw_config_option_add(config, key, value, nw_config_read_address, nw_config_write_address) ++ nw_config_option_add(config, key, value, nw_config_read_address, nw_config_write_address, NULL) + +-int nw_config_read_address(nw_config* config, const char* key, void* value); +-int nw_config_write_address(nw_config* config, const char* key, const void* value); ++int nw_config_read_address(nw_config* config, const char* key, void* value, void* data); ++int nw_config_write_address(nw_config* config, const char* key, const void* value, void* data); + + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index e765791..7bd54e1 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -40,12 +40,13 @@ const struct nw_string_table nw_port_bonding_mode[] = { + + NW_STRING_TABLE_LOOKUP(nw_port_bonding_mode_t, nw_port_bonding_mode) + +-static int nw_port_bonding_read_mode(nw_config* config, const char* key, void* data) { +- int* mode = (int*)data; ++static int nw_port_bonding_read_mode(nw_config* config, ++ const char* key, void* value, void* data) { ++ int* mode = (int*)value; + +- const char* value = nw_config_get(config, key); +- if (value) { +- *mode = nw_port_bonding_mode_from_string(value); ++ const char* p = nw_config_get(config, key); ++ if (p) { ++ *mode = nw_port_bonding_mode_from_string(p); + if (!*mode) + return -errno; + } +@@ -53,8 +54,9 @@ static int nw_port_bonding_read_mode(nw_config* config, const char* key, void* d + return 0; + } + +-static int nw_port_bonding_write_mode(nw_config* config, const char* key, const void* data) { +- const int* mode = (int*)data; ++static int nw_port_bonding_write_mode(nw_config* config, ++ const char* key, const void* value, void* data) { ++ const int* mode = (int*)value; + + return nw_config_set(config, key, nw_port_bonding_mode_to_string(*mode)); + } +@@ -64,7 +66,7 @@ static int nw_port_bonding_setup(nw_port* port) { + + // Mode + r = NW_CONFIG_OPTION(port->config, "BONDING_MODE", &port->bonding.mode, +- nw_port_bonding_read_mode, nw_port_bonding_write_mode); ++ nw_port_bonding_read_mode, nw_port_bonding_write_mode, NULL); + if (r < 0) + return r; + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 2d89a09..e3f93d7 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -38,12 +38,13 @@ const struct nw_string_table nw_port_vlan_proto[] = { + + NW_STRING_TABLE_LOOKUP(nw_port_vlan_proto_t, nw_port_vlan_proto) + +-static int nw_port_vlan_read_proto(nw_config* config, const char* key, void* data) { +- nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)data; ++static int nw_port_vlan_read_proto(nw_config* config, ++ const char* key, void* value, void* data) { ++ nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)value; + +- const char* value = nw_config_get(config, key); +- if (value) { +- *proto = nw_port_vlan_proto_from_string(data); ++ const char* p = nw_config_get(config, key); ++ if (p) { ++ *proto = nw_port_vlan_proto_from_string(p); + if (!*proto) + return -errno; + } +@@ -51,8 +52,9 @@ static int nw_port_vlan_read_proto(nw_config* config, const char* key, void* dat + return 0; + } + +-static int nw_port_vlan_write_proto(nw_config* config, const char* key, const void* data) { +- const nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)data; ++static int nw_port_vlan_write_proto(nw_config* config, ++ const char* key, const void* value, void* data) { ++ const nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)value; + + return nw_config_set(config, key, nw_port_vlan_proto_to_string(*proto)); + } +@@ -67,7 +69,7 @@ static int nw_port_vlan_setup(nw_port* port) { + + // VLAN Protocol + r = NW_CONFIG_OPTION(port->config, "VLAN_PROTO", &port->vlan.proto, +- nw_port_vlan_read_proto, nw_port_vlan_write_proto); ++ nw_port_vlan_read_proto, nw_port_vlan_write_proto, NULL); + if (r < 0) + return r; + +-- +2.39.2 + diff --git a/network/patches/0263-string-Define-an-own-type-for-string-tables.patch b/network/patches/0263-string-Define-an-own-type-for-string-tables.patch new file mode 100644 index 000000000..b309634cb --- /dev/null +++ b/network/patches/0263-string-Define-an-own-type-for-string-tables.patch @@ -0,0 +1,75 @@ +From 644eb1c88dc179c3efdeb6af32c5d153d5483957 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:30:41 +0000 +Subject: [PATCH 263/304] string: Define an own type for string tables + +Signed-off-by: Michael Tremer +--- + src/networkd/port-bonding.c | 2 +- + src/networkd/port-vlan.c | 2 +- + src/networkd/string.h | 12 ++++++------ + 3 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index 7bd54e1..b1d2c18 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -27,7 +27,7 @@ + #include "port-bonding.h" + #include "string.h" + +-const struct nw_string_table nw_port_bonding_mode[] = { ++const nw_string_table_t nw_port_bonding_mode[] = { + { NW_BONDING_MODE_ROUNDROBIN, "round-robin" }, + { NW_BONDING_MODE_ACTIVEBACKUP, "active-backup" }, + { NW_BONDING_MODE_XOR, "xor" }, +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index e3f93d7..792fd28 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -30,7 +30,7 @@ + #include "port-vlan.h" + #include "string.h" + +-const struct nw_string_table nw_port_vlan_proto[] = { ++const nw_string_table_t nw_port_vlan_proto[] = { + { NW_VLAN_PROTO_8021Q, "802.1Q" }, + { NW_VLAN_PROTO_8021ad, "802.1ad" }, + { -1, NULL }, +diff --git a/src/networkd/string.h b/src/networkd/string.h +index d94e270..270ed6b 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -129,14 +129,14 @@ static inline void nw_string_empty(char* s) { + Tables + */ + +-struct nw_string_table { ++typedef struct nw_string_table { + const int id; + const char* string; +-}; ++} nw_string_table_t; + + static inline const char* nw_string_table_lookup_string( +- const struct nw_string_table* table, const int id) { +- const struct nw_string_table* entry = NULL; ++ const nw_string_table_t* table, const int id) { ++ const nw_string_table_t* entry = NULL; + + for (entry = table; entry->string; entry++) + if (entry->id == id) +@@ -146,8 +146,8 @@ static inline const char* nw_string_table_lookup_string( + } + + static inline int nw_string_table_lookup_id( +- const struct nw_string_table* table, const char* string) { +- const struct nw_string_table* entry = NULL; ++ const nw_string_table_t* table, const char* string) { ++ const nw_string_table_t* entry = NULL; + + for (entry = table; entry->string; entry++) + if (strcmp(entry->string, string) == 0) +-- +2.39.2 + diff --git a/network/patches/0264-config-Implement-option-that-looks-up-string-tables.patch b/network/patches/0264-config-Implement-option-that-looks-up-string-tables.patch new file mode 100644 index 000000000..6faf489ad --- /dev/null +++ b/network/patches/0264-config-Implement-option-that-looks-up-string-tables.patch @@ -0,0 +1,184 @@ +From 7442668a42febaf6ad533c6d7647ad7847cb4775 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:46:20 +0000 +Subject: [PATCH 264/304] config: Implement option that looks up string tables + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 37 +++++++++++++++++++++++++++++++++++++ + src/networkd/config.h | 14 ++++++++++++++ + src/networkd/port-bonding.c | 25 ++----------------------- + src/networkd/port-vlan.c | 25 ++----------------------- + 4 files changed, 55 insertions(+), 46 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 39e9881..ee5e8b8 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -570,6 +570,43 @@ int nw_config_write_string(nw_config* config, + return nw_config_set(config, key, *(const char**)value); + } + ++// String Table ++ ++int nw_config_read_string_table(nw_config* config, const char* key, void* value, void* data) { ++ const char* s = NULL; ++ int* v = (int*)value; ++ ++ const nw_string_table_t* table = (nw_string_table_t*)data; ++ ++ // Fetch the string ++ s = nw_config_get(config, key); ++ if (!s) ++ return -errno; ++ ++ // Lookup the string in the table ++ *v = nw_string_table_lookup_id(table, s); ++ ++ // If the result is negative, nothing was found ++ if (*v < 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++int nw_config_write_string_table(nw_config* config, ++ const char* key, const void* value, void* data) { ++ int* v = (int*)value; ++ ++ const nw_string_table_t* table = (nw_string_table_t*)data; ++ ++ // Lookup the string ++ const char* s = nw_string_table_lookup_string(table, *v); ++ if (!s) ++ return -errno; ++ ++ return nw_config_set(config, key, s); ++} ++ + // Address + + int nw_config_read_address(nw_config* config, const char* key, void* value, void* data) { +diff --git a/src/networkd/config.h b/src/networkd/config.h +index d6b8db8..63e9d18 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -73,18 +73,32 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + #define NW_CONFIG_OPTION(config, key, value, read_callback, write_callback, data) \ + nw_config_option_add(config, key, value, read_callback, write_callback, data) + ++// String ++ + #define NW_CONFIG_OPTION_STRING(config, key, value) \ + nw_config_option_add(config, key, value, nw_config_read_string, nw_config_write_string, NULL) + + int nw_config_read_string(nw_config* config, const char* key, void* value, void* data); + int nw_config_write_string(nw_config* config, const char* key, const void* value, void* data); + ++// String Table ++ ++#define NW_CONFIG_OPTION_STRING_TABLE(config, key, value, table) \ ++ nw_config_option_add(config, key, value, nw_config_read_string_table, nw_config_write_string_table, (void*)table) ++ ++int nw_config_read_string_table(nw_config* config, const char* key, void* value, void* data); ++int nw_config_write_string_table(nw_config* config, const char* key, const void* value, void* data); ++ ++// Integer ++ + #define NW_CONFIG_OPTION_INT(config, key, value) \ + nw_config_option_add(config, key, value, nw_config_read_int, nw_config_write_int, NULL) + + int nw_config_read_int(nw_config* config, const char* key, void* value, void* data); + int nw_config_write_int(nw_config* config, const char* key, const void* value, void* data); + ++// Address ++ + #define NW_CONFIG_OPTION_ADDRESS(config, key, value) \ + nw_config_option_add(config, key, value, nw_config_read_address, nw_config_write_address, NULL) + +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index b1d2c18..4e4c8a7 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -40,33 +40,12 @@ const nw_string_table_t nw_port_bonding_mode[] = { + + NW_STRING_TABLE_LOOKUP(nw_port_bonding_mode_t, nw_port_bonding_mode) + +-static int nw_port_bonding_read_mode(nw_config* config, +- const char* key, void* value, void* data) { +- int* mode = (int*)value; +- +- const char* p = nw_config_get(config, key); +- if (p) { +- *mode = nw_port_bonding_mode_from_string(p); +- if (!*mode) +- return -errno; +- } +- +- return 0; +-} +- +-static int nw_port_bonding_write_mode(nw_config* config, +- const char* key, const void* value, void* data) { +- const int* mode = (int*)value; +- +- return nw_config_set(config, key, nw_port_bonding_mode_to_string(*mode)); +-} +- + static int nw_port_bonding_setup(nw_port* port) { + int r; + + // Mode +- r = NW_CONFIG_OPTION(port->config, "BONDING_MODE", &port->bonding.mode, +- nw_port_bonding_read_mode, nw_port_bonding_write_mode, NULL); ++ r = NW_CONFIG_OPTION_STRING_TABLE(port->config, ++ "BONDING_MODE", &port->bonding.mode, nw_port_bonding_mode); + if (r < 0) + return r; + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 792fd28..8f5372e 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -38,27 +38,6 @@ const nw_string_table_t nw_port_vlan_proto[] = { + + NW_STRING_TABLE_LOOKUP(nw_port_vlan_proto_t, nw_port_vlan_proto) + +-static int nw_port_vlan_read_proto(nw_config* config, +- const char* key, void* value, void* data) { +- nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)value; +- +- const char* p = nw_config_get(config, key); +- if (p) { +- *proto = nw_port_vlan_proto_from_string(p); +- if (!*proto) +- return -errno; +- } +- +- return 0; +-} +- +-static int nw_port_vlan_write_proto(nw_config* config, +- const char* key, const void* value, void* data) { +- const nw_port_vlan_proto_t* proto = (nw_port_vlan_proto_t*)value; +- +- return nw_config_set(config, key, nw_port_vlan_proto_to_string(*proto)); +-} +- + static int nw_port_vlan_setup(nw_port* port) { + int r; + +@@ -68,8 +47,8 @@ static int nw_port_vlan_setup(nw_port* port) { + return r; + + // VLAN Protocol +- r = NW_CONFIG_OPTION(port->config, "VLAN_PROTO", &port->vlan.proto, +- nw_port_vlan_read_proto, nw_port_vlan_write_proto, NULL); ++ r = NW_CONFIG_OPTION_STRING_TABLE(port->config, ++ "VLAN_PROTO", &port->vlan.proto, nw_port_vlan_proto); + if (r < 0) + return r; + +-- +2.39.2 + diff --git a/network/patches/0265-ports-Store-the-parent-name.patch b/network/patches/0265-ports-Store-the-parent-name.patch new file mode 100644 index 000000000..62d2d4863 --- /dev/null +++ b/network/patches/0265-ports-Store-the-parent-name.patch @@ -0,0 +1,32 @@ +From d200865e663a1a15b43d7462cbcddf7c13dc6997 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:48:20 +0000 +Subject: [PATCH 265/304] ports: Store the parent name + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 8f5372e..45abebe 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -209,9 +209,13 @@ int nw_port_set_vlan_parent(nw_port* port, nw_port* parent) { + } + + // Store the new parent +- if (parent) ++ if (parent) { + port->vlan.parent = nw_port_ref(parent); + ++ // Store the name ++ nw_string_set(port->vlan.__parent_name, nw_port_name(parent)); ++ } ++ + DEBUG("Port %s: Set VLAN parent to %s\n", port->name, nw_port_name(port->vlan.parent)); + + return 0; +-- +2.39.2 + diff --git a/network/patches/0266-ports-VLAN-Make-all-constants-uppercase.patch b/network/patches/0266-ports-VLAN-Make-all-constants-uppercase.patch new file mode 100644 index 000000000..cde9e5d33 --- /dev/null +++ b/network/patches/0266-ports-VLAN-Make-all-constants-uppercase.patch @@ -0,0 +1,49 @@ +From 4db7e54816eb20319d2f90336a029386b0cd3e91 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 15:49:27 +0000 +Subject: [PATCH 266/304] ports: VLAN: Make all constants uppercase + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.c | 4 ++-- + src/networkd/port-vlan.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 45abebe..56b0274 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -32,7 +32,7 @@ + + const nw_string_table_t nw_port_vlan_proto[] = { + { NW_VLAN_PROTO_8021Q, "802.1Q" }, +- { NW_VLAN_PROTO_8021ad, "802.1ad" }, ++ { NW_VLAN_PROTO_8021AD, "802.1ad" }, + { -1, NULL }, + }; + +@@ -161,7 +161,7 @@ int nw_port_set_vlan_id(nw_port* port, int id) { + int nw_port_set_vlan_proto(nw_port* port, const nw_port_vlan_proto_t proto) { + switch (proto) { + case NW_VLAN_PROTO_8021Q: +- case NW_VLAN_PROTO_8021ad: ++ case NW_VLAN_PROTO_8021AD: + port->vlan.proto = proto; + break; + +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index 17d3134..b4df562 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -28,7 +28,7 @@ + + typedef enum nw_port_vlan_proto { + NW_VLAN_PROTO_8021Q = ETH_P_8021Q, +- NW_VLAN_PROTO_8021ad = ETH_P_8021AD, ++ NW_VLAN_PROTO_8021AD = ETH_P_8021AD, + } nw_port_vlan_proto_t; + + struct nw_port_vlan { +-- +2.39.2 + diff --git a/network/patches/0267-ports-Unify-type.patch b/network/patches/0267-ports-Unify-type.patch new file mode 100644 index 000000000..d0ab4df5c --- /dev/null +++ b/network/patches/0267-ports-Unify-type.patch @@ -0,0 +1,440 @@ +From c464b5d1e146402f153f98a5e5d04b76b4d74e10 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:19:05 +0000 +Subject: [PATCH 267/304] ports: Unify type + +Signed-off-by: Michael Tremer +--- + src/networkd/port-bonding.c | 17 ++++------ + src/networkd/port-bonding.h | 2 +- + src/networkd/port-dummy.c | 2 +- + src/networkd/port-dummy.h | 2 +- + src/networkd/port-vlan.c | 19 +++++------ + src/networkd/port-vlan.h | 2 +- + src/networkd/port.c | 68 ++++++++++++++++--------------------- + src/networkd/port.h | 66 +++++++++++++++++------------------ + 8 files changed, 80 insertions(+), 98 deletions(-) + +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index 4e4c8a7..ad02b5d 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -76,20 +76,17 @@ ERROR: + return r; + } + +-const nw_port_info_t nw_port_info_bonding = { ++const nw_port_type_t nw_port_type_bonding = { + .kind = "bond", + +- // Operations +- .ops = { +- // Configuration +- .setup = nw_port_bonding_setup, ++ // Configuration ++ .setup = nw_port_bonding_setup, + +- // Link +- .create_link = nw_port_bonding_create_link, ++ // Link ++ .create_link = nw_port_bonding_create_link, + +- // JSON +- .to_json = nw_port_bonding_to_json, +- }, ++ // JSON ++ .to_json = nw_port_bonding_to_json, + }; + + const char* nw_port_bonding_get_mode(nw_port* port) { +diff --git a/src/networkd/port-bonding.h b/src/networkd/port-bonding.h +index e21c251..e5c8c32 100644 +--- a/src/networkd/port-bonding.h ++++ b/src/networkd/port-bonding.h +@@ -39,7 +39,7 @@ struct nw_port_bonding { + nw_port_bonding_mode_t mode; + }; + +-extern const nw_port_info_t nw_port_info_bonding; ++extern const nw_port_type_t nw_port_type_bonding; + + const char* nw_port_bonding_get_mode(nw_port* port); + int nw_port_bonding_set_mode(nw_port* port, const char* mode); +diff --git a/src/networkd/port-dummy.c b/src/networkd/port-dummy.c +index e71e740..8a44008 100644 +--- a/src/networkd/port-dummy.c ++++ b/src/networkd/port-dummy.c +@@ -20,6 +20,6 @@ + + #include "port-dummy.h" + +-const nw_port_info_t nw_port_info_dummy = { ++const nw_port_type_t nw_port_type_dummy = { + .kind = "dummy", + }; +diff --git a/src/networkd/port-dummy.h b/src/networkd/port-dummy.h +index b74c991..34a7265 100644 +--- a/src/networkd/port-dummy.h ++++ b/src/networkd/port-dummy.h +@@ -23,6 +23,6 @@ + + #include "port.h" + +-extern const nw_port_info_t nw_port_info_dummy; ++extern const nw_port_type_t nw_port_type_dummy; + + #endif /* NETWORKD_PORT_DUMMY_H */ +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 56b0274..06047ab 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -106,22 +106,19 @@ ERROR: + return r; + } + +-const nw_port_info_t nw_port_info_vlan = { ++const nw_port_type_t nw_port_type_vlan = { + .kind = "vlan", + +- // Operations +- .ops = { +- // Configuration +- .setup = nw_port_vlan_setup, ++ // Configuration ++ .setup = nw_port_vlan_setup, + +- .get_parent_port = nw_port_get_vlan_parent, ++ .get_parent_port = nw_port_get_vlan_parent, + +- // Link +- .create_link = nw_port_vlan_create_link, ++ // Link ++ .create_link = nw_port_vlan_create_link, + +- // JSON +- .to_json = nw_port_vlan_to_json, +- }, ++ // JSON ++ .to_json = nw_port_vlan_to_json, + }; + + /* +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index b4df562..6ecf6a4 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -45,7 +45,7 @@ struct nw_port_vlan { + char __parent_name[IF_NAMESIZE]; + }; + +-extern const nw_port_info_t nw_port_info_vlan; ++extern const nw_port_type_t nw_port_type_vlan; + + // ID + int nw_port_get_vlan_id(nw_port* port); +diff --git a/src/networkd/port.c b/src/networkd/port.c +index cab8fc5..c4d6ffe 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -37,26 +37,14 @@ + #include "stats-collector.h" + #include "string.h" + +-static const struct nw_port_type_map { +- nw_port_type_t type; +- const char* name; +-} nw_port_type_map[] = { ++static const nw_string_table_t nw_port_type_id[] = { + { NW_PORT_BONDING, "bonding" }, + { NW_PORT_DUMMY, "dummy" }, + { NW_PORT_VLAN, "vlan" }, +- { NW_PORT_UNKNOWN, NULL }, ++ { -1, NULL }, + }; + +-static nw_port_type_t nw_port_type_from_string(const char* s) { +- const struct nw_port_type_map* map = NULL; +- +- for (map = nw_port_type_map; *map->name; map++) { +- if (strcmp(map->name, s) == 0) +- return map->type; +- } +- +- return NW_PORT_UNKNOWN; +-} ++NW_STRING_TABLE_LOOKUP(nw_port_type_id_t, nw_port_type_id) + + static void nw_port_free(nw_port* port) { + if (port->link) +@@ -119,8 +107,8 @@ static int nw_port_setup(nw_port* port) { + goto ERROR; + + // Call any custom initialization +- if (NW_PORT_OPS(port)->setup) { +- r = NW_PORT_OPS(port)->setup(port); ++ if (NW_PORT_TYPE(port)->setup) { ++ r = NW_PORT_TYPE(port)->setup(port); + if (r < 0) + goto ERROR; + } +@@ -140,7 +128,7 @@ ERROR: + } + + int nw_port_create(nw_port** port, nw_daemon* daemon, +- nw_port_type_t type, const char* name, nw_config* config) { ++ const nw_port_type_id_t type, const char* name, nw_config* config) { + int r; + + // Allocate a new object +@@ -154,21 +142,18 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + // Initialize reference counter + p->nrefs = 1; + +- // Store the type +- p->type = type; +- + // Set operations +- switch (p->type) { ++ switch (type) { + case NW_PORT_BONDING: +- p->info = &nw_port_info_bonding; ++ p->type = &nw_port_type_bonding; + break; + + case NW_PORT_DUMMY: +- p->info = &nw_port_info_dummy; ++ p->type = &nw_port_type_dummy; + break; + + case NW_PORT_VLAN: +- p->info = &nw_port_info_vlan; ++ p->type = &nw_port_type_vlan; + break; + } + +@@ -214,7 +199,7 @@ int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, + } + + // Create a new port +- r = nw_port_create(port, daemon, nw_port_type_from_string(type), name, config); ++ r = nw_port_create(port, daemon, nw_port_type_id_from_string(type), name, config); + if (r) + goto ERROR; + +@@ -286,7 +271,7 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + nw_port* dropped_port = (nw_port*)data; + int r; + +- switch (port->type) { ++ switch (port->type->id) { + case NW_PORT_VLAN: + if (port->vlan.parent == dropped_port) { + r = nw_port_set_vlan_parent(port, NULL); +@@ -392,10 +377,10 @@ static int nw_port_is_disabled(nw_port* port) { + } + + nw_port* nw_port_get_parent_port(nw_port* port) { +- if (!NW_PORT_OPS(port)->get_parent_port) ++ if (!NW_PORT_TYPE(port)->get_parent_port) + return NULL; + +- return NW_PORT_OPS(port)->get_parent_port(port); ++ return NW_PORT_TYPE(port)->get_parent_port(port); + } + + static nw_link* nw_port_get_parent_link(nw_port* port) { +@@ -444,6 +429,13 @@ static int nw_port_create_link(nw_port* port) { + + DEBUG("Creating port %s...\n", port->name); + ++ // Check the kind ++ if (!NW_PORT_TYPE(port)->kind) { ++ ERROR("Port type has no kind\n"); ++ r = -ENOTSUP; ++ goto ERROR; ++ } ++ + // Create a new link + r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0); + if (r < 0) { +@@ -481,14 +473,14 @@ static int nw_port_create_link(nw_port* port) { + goto ERROR; + + // Run the custom setup +- if (NW_PORT_OPS(port)->create_link) { +- r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, NW_PORT_INFO(port)->kind); ++ if (NW_PORT_TYPE(port)->create_link) { ++ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, NW_PORT_TYPE(port)->kind); + if (r < 0) { + ERROR("Could not open IFLA_INFO_DATA container: %s\n", strerror(-r)); + goto ERROR; + } + +- r = NW_PORT_OPS(port)->create_link(port, m); ++ r = NW_PORT_TYPE(port)->create_link(port, m); + if (r) { + ERROR("Could not create port %s: %m\n", port->name); + goto ERROR; +@@ -501,7 +493,7 @@ static int nw_port_create_link(nw_port* port) { + + // Just set IFLA_INFO_KIND if there is no custom function + } else { +- r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, NW_PORT_INFO(port)->kind); ++ r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, NW_PORT_TYPE(port)->kind); + if (r < 0) + goto ERROR; + } +@@ -588,8 +580,8 @@ int nw_port_update_stats(nw_port* port) { + return 0; + } + +-int nw_port_check_type(nw_port* port, const nw_port_type_t type) { +- if (port->type == type) ++int nw_port_check_type(nw_port* port, const nw_port_type_id_t type) { ++ if (port->type->id == type) + return 0; + + errno = ENOTSUP; +@@ -616,7 +608,7 @@ int nw_port_to_json(nw_port* port, struct json_object** object) { + goto ERROR; + + // Add Type +- r = json_object_add_string(o, "Type", NW_PORT_INFO(port)->kind); ++ r = json_object_add_string(o, "Type", nw_port_type_id_to_string(port->type->id)); + if (r < 0) + goto ERROR; + +@@ -629,8 +621,8 @@ int nw_port_to_json(nw_port* port, struct json_object** object) { + } + + // Call custom stuff +- if (NW_PORT_OPS(port)->to_json) { +- r = NW_PORT_OPS(port)->to_json(port, o); ++ if (NW_PORT_TYPE(port)->to_json) { ++ r = NW_PORT_TYPE(port)->to_json(port, o); + if (r < 0) + goto ERROR; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index ef68a89..c9add71 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -31,50 +31,49 @@ + + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" + +-typedef enum nw_port_type { +- NW_PORT_UNKNOWN = 0, +- NW_PORT_BONDING, +- NW_PORT_DUMMY, +- NW_PORT_VLAN, +-} nw_port_type_t; +- + // VLAN + #define NW_VLAN_ID_INVALID 0 + #define NW_VLAN_ID_MIN 1 + #define NW_VLAN_ID_MAX 4096 + + typedef struct nw_port nw_port; +-typedef struct nw_port_info nw_port_info_t; + +-#include "address.h" +-#include "config.h" +-#include "daemon.h" +-#include "json.h" +-#include "port-bonding.h" +-#include "port-vlan.h" ++typedef enum nw_port_type_id { ++ NW_PORT_UNKNOWN = 0, ++ NW_PORT_BONDING, ++ NW_PORT_DUMMY, ++ NW_PORT_VLAN, ++} nw_port_type_id_t; ++ ++typedef struct nw_port_type { ++ // Type ID ++ nw_port_type_id_t id; + +-struct nw_port_info { + // IFLA_INFO_KIND/IFLA_INFO_DATA + const char* kind; + +- struct nw_port_ops { +- // Configuration +- int (*setup)(nw_port* port); ++ // Configuration ++ int (*setup)(nw_port* port); + +- // Get Parent Port +- nw_port* (*get_parent_port)(nw_port* port); ++ // Get Parent Port ++ nw_port* (*get_parent_port)(nw_port* port); + +- // Link +- int (*create_link)(nw_port* port, sd_netlink_message* message); +- int (*destroy_link)(nw_port* port); ++ // Link ++ int (*create_link)(nw_port* port, sd_netlink_message* message); ++ int (*destroy_link)(nw_port* port); + +- // JSON +- int (*to_json)(nw_port* port, struct json_object* object); +- } ops; +-}; ++ // JSON ++ int (*to_json)(nw_port* port, struct json_object* object); ++} nw_port_type_t; ++ ++#include "address.h" ++#include "config.h" ++#include "daemon.h" ++#include "json.h" ++#include "port-bonding.h" ++#include "port-vlan.h" + +-#define NW_PORT_INFO(port) (port->info) +-#define NW_PORT_OPS(port) (&NW_PORT_INFO(port)->ops) ++#define NW_PORT_TYPE(port) (port->type) + + struct nw_port { + nw_daemon* daemon; +@@ -83,7 +82,7 @@ struct nw_port { + // Link + nw_link* link; + +- nw_port_type_t type; ++ const nw_port_type_t* type; + char name[IF_NAMESIZE]; + + // Configuration +@@ -92,9 +91,6 @@ struct nw_port { + // Common attributes + nw_address_t address; + +- // Type Operations +- const nw_port_info_t* info; +- + // Bonding Settings + struct nw_port_bonding bonding; + +@@ -103,7 +99,7 @@ struct nw_port { + }; + + int nw_port_create(nw_port** port, nw_daemon* daemon, +- nw_port_type_t type, const char* name, nw_config* config); ++ const nw_port_type_id_t type, const char* name, nw_config* config); + int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, + const char* name, const char* path); + +@@ -130,7 +126,7 @@ int nw_port_reconfigure(nw_port* port); + + int nw_port_has_carrier(nw_port* port); + +-int nw_port_check_type(nw_port* port, const nw_port_type_t type); ++int nw_port_check_type(nw_port* port, const nw_port_type_id_t type); + + // Stats + const struct rtnl_link_stats64* nw_port_get_stats64(nw_port* port); +-- +2.39.2 + diff --git a/network/patches/0268-ports-Move-VLAN-constants-to-VLAN-header.patch b/network/patches/0268-ports-Move-VLAN-constants-to-VLAN-header.patch new file mode 100644 index 000000000..87b90df53 --- /dev/null +++ b/network/patches/0268-ports-Move-VLAN-constants-to-VLAN-header.patch @@ -0,0 +1,46 @@ +From 81ab55ae98a4280265fc7b3bee2c3770d621c152 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:22:11 +0000 +Subject: [PATCH 268/304] ports: Move VLAN constants to VLAN header + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.h | 5 +++++ + src/networkd/port.h | 5 ----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index 6ecf6a4..e17f7e7 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -31,6 +31,11 @@ typedef enum nw_port_vlan_proto { + NW_VLAN_PROTO_8021AD = ETH_P_8021AD, + } nw_port_vlan_proto_t; + ++// VLAN ID ++#define NW_VLAN_ID_INVALID 0 ++#define NW_VLAN_ID_MIN 1 ++#define NW_VLAN_ID_MAX 4096 ++ + struct nw_port_vlan { + nw_port* parent; + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index c9add71..15b8bc1 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -31,11 +31,6 @@ + + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" + +-// VLAN +-#define NW_VLAN_ID_INVALID 0 +-#define NW_VLAN_ID_MIN 1 +-#define NW_VLAN_ID_MAX 4096 +- + typedef struct nw_port nw_port; + + typedef enum nw_port_type_id { +-- +2.39.2 + diff --git a/network/patches/0269-ports-Drop-UNKNOWN-type.patch b/network/patches/0269-ports-Drop-UNKNOWN-type.patch new file mode 100644 index 000000000..a82298573 --- /dev/null +++ b/network/patches/0269-ports-Drop-UNKNOWN-type.patch @@ -0,0 +1,48 @@ +From b249255d5ca7cdff8ea97e0a0cdd39f1bf0e6e63 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:26:13 +0000 +Subject: [PATCH 269/304] ports: Drop UNKNOWN type + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 4 ---- + src/networkd/port.h | 1 - + 2 files changed, 5 deletions(-) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index c4d6ffe..c14d439 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -261,9 +261,6 @@ int nw_port_destroy(nw_port* port) { + if (r) + return r; + +- // Reset type +- port->type = NW_PORT_UNKNOWN; +- + return 0; + } + +@@ -282,7 +279,6 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + + case NW_PORT_BONDING: + case NW_PORT_DUMMY: +- case NW_PORT_UNKNOWN: + break; + } + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 15b8bc1..b96b13e 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -34,7 +34,6 @@ + typedef struct nw_port nw_port; + + typedef enum nw_port_type_id { +- NW_PORT_UNKNOWN = 0, + NW_PORT_BONDING, + NW_PORT_DUMMY, + NW_PORT_VLAN, +-- +2.39.2 + diff --git a/network/patches/0270-ports-Implement-scaffolding-for-configuration.patch b/network/patches/0270-ports-Implement-scaffolding-for-configuration.patch new file mode 100644 index 000000000..b04a1bf4e --- /dev/null +++ b/network/patches/0270-ports-Implement-scaffolding-for-configuration.patch @@ -0,0 +1,74 @@ +From ea7dc1bbab6162c319ce738161af813f2d1b7241 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:35:33 +0000 +Subject: [PATCH 270/304] ports: Implement scaffolding for configuration + +Signed-off-by: Michael Tremer +--- + src/networkd/port.c | 30 ++++++++++++++++++++++++++++++ + src/networkd/port.h | 1 + + 2 files changed, 31 insertions(+) + +diff --git a/src/networkd/port.c b/src/networkd/port.c +index c14d439..fb5d418 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -127,6 +127,19 @@ ERROR: + return r; + } + ++static int nw_port_validate(nw_port* port) { ++ int r = 0; ++ ++ // Validate the port configuration ++ if (NW_PORT_TYPE(port)->validate) { ++ r = NW_PORT_TYPE(port)->validate(port); ++ if (r < 0) ++ ERROR("Could not check configuration for %s: %s\n", port->name, strerror(-r)); ++ } ++ ++ return r; ++} ++ + int nw_port_create(nw_port** port, nw_daemon* daemon, + const nw_port_type_id_t type, const char* name, nw_config* config) { + int r; +@@ -172,6 +185,23 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + if (r) + goto ERROR; + ++ // Validate the configuration ++ r = nw_port_validate(p); ++ switch (r) { ++ // Configuration is valid ++ case 0: ++ break; ++ ++ // Configuration is invalid ++ case 1: ++ ERROR("%s: Invalid configuration\n", p->name); ++ goto ERROR; ++ ++ // Error ++ default: ++ goto ERROR; ++ } ++ + *port = p; + return 0; + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index b96b13e..7c2e436 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -48,6 +48,7 @@ typedef struct nw_port_type { + + // Configuration + int (*setup)(nw_port* port); ++ int (*validate)(nw_port* port); + + // Get Parent Port + nw_port* (*get_parent_port)(nw_port* port); +-- +2.39.2 + diff --git a/network/patches/0271-ports-VLAN-Validate-configuration.patch b/network/patches/0271-ports-VLAN-Validate-configuration.patch new file mode 100644 index 000000000..6078928b7 --- /dev/null +++ b/network/patches/0271-ports-VLAN-Validate-configuration.patch @@ -0,0 +1,53 @@ +From 749b1a85fdbf4ec0ec0ac3b3fe07cdeffd72460c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:41:13 +0000 +Subject: [PATCH 271/304] ports: VLAN: Validate configuration + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 06047ab..25a59ee 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -60,6 +60,27 @@ static int nw_port_vlan_setup(nw_port* port) { + return 0; + } + ++static int nw_port_vlan_validate(nw_port* port) { ++ // Check if the VLAN ID is within range ++ if (port->vlan.id < NW_VLAN_ID_MIN || port->vlan.id > NW_VLAN_ID_MAX) { ++ ERROR("%s: Invalid VLAN ID %d\n", port->name, port->vlan.id); ++ return 1; ++ } ++ ++ // Validate protocol ++ switch (port->vlan.proto) { ++ case NW_VLAN_PROTO_8021Q: ++ case NW_VLAN_PROTO_8021AD: ++ break; ++ ++ default: ++ ERROR("%p: Invalid VLAN protocol\n", port->name); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static int nw_port_vlan_create_link(nw_port* port, sd_netlink_message* m) { + int r; + +@@ -111,6 +132,7 @@ const nw_port_type_t nw_port_type_vlan = { + + // Configuration + .setup = nw_port_vlan_setup, ++ .validate = nw_port_vlan_validate, + + .get_parent_port = nw_port_get_vlan_parent, + +-- +2.39.2 + diff --git a/network/patches/0272-daemon-Don-t-crash-when-a-port-could-not-be-loaded.patch b/network/patches/0272-daemon-Don-t-crash-when-a-port-could-not-be-loaded.patch new file mode 100644 index 000000000..a4daf071d --- /dev/null +++ b/network/patches/0272-daemon-Don-t-crash-when-a-port-could-not-be-loaded.patch @@ -0,0 +1,40 @@ +From ac7659bf6a5f84f473424c6976e4ccd6c2e72979 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 16:46:12 +0000 +Subject: [PATCH 272/304] daemon: Don't crash when a port could not be loaded + +Signed-off-by: Michael Tremer +--- + src/networkd/ports.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index f0a3ebb..65545e8 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -152,8 +152,20 @@ static int __nw_ports_enumerate(const char* path, const struct stat* s, void* da + + // Create a new port + r = nw_port_create_from_config(&port, ports->daemon, name, path); +- if (r) +- goto ERROR; ++ switch (r) { ++ // All okay ++ case 0: ++ break; ++ ++ // Invalid configuration ++ case 1: ++ ERROR("Could not open port %s\n", name); ++ r = 0; ++ goto ERROR; ++ ++ default: ++ goto ERROR; ++ } + + // Add the port to the list + r = nw_ports_add_port(ports, port); +-- +2.39.2 + diff --git a/network/patches/0273-string-Have-all-functions-return-negative-values-on-.patch b/network/patches/0273-string-Have-all-functions-return-negative-values-on-.patch new file mode 100644 index 000000000..ad88f04bf --- /dev/null +++ b/network/patches/0273-string-Have-all-functions-return-negative-values-on-.patch @@ -0,0 +1,33 @@ +From 45a3d5aaca4e1d64132d7b4190209bb743efaa68 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Thu, 8 Jun 2023 17:05:54 +0000 +Subject: [PATCH 273/304] string: Have all functions return negative values on + error + +Signed-off-by: Michael Tremer +--- + src/networkd/string.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/networkd/string.h b/src/networkd/string.h +index 270ed6b..a36b023 100644 +--- a/src/networkd/string.h ++++ b/src/networkd/string.h +@@ -37,12 +37,11 @@ static inline int __nw_string_vformat(char* s, const size_t length, + + // Catch any errors + if (required < 0) +- return 1; ++ return required; + + // Check if the entire string could be written + if ((size_t)required >= length) { +- errno = ENOMEM; +- return 1; ++ return -ENOMEM; + } + + // Success +-- +2.39.2 + diff --git a/network/patches/0274-networkd-Parse-command-line-arguments.patch b/network/patches/0274-networkd-Parse-command-line-arguments.patch new file mode 100644 index 000000000..de3674bec --- /dev/null +++ b/network/patches/0274-networkd-Parse-command-line-arguments.patch @@ -0,0 +1,132 @@ +From 3138451ba526d9ada4e74cffccd10c5807c9bc8e Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 04:58:39 +0000 +Subject: [PATCH 274/304] networkd: Parse command line arguments + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 45 ++++++++++++++++++++++++++++++++++++++++++- + src/networkd/daemon.h | 2 +- + src/networkd/main.c | 2 +- + 3 files changed, 46 insertions(+), 3 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 749a70b..31fda8e 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -19,6 +19,8 @@ + #############################################################################*/ + + #include ++#include ++#include + #include + + #include +@@ -36,6 +38,7 @@ + #include "logging.h" + #include "ports.h" + #include "stats-collector.h" ++#include "string.h" + #include "zone.h" + #include "zones.h" + +@@ -45,6 +48,7 @@ + struct nw_daemon { + int nrefs; + ++ char config_path[PATH_MAX]; + nw_config* config; + + // Event Loop +@@ -91,6 +95,40 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig + return 0; + } + ++static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { ++ enum { ++ ARG_CONFIG, ++ }; ++ int r; ++ ++ static const struct option options[] = { ++ { "config", required_argument, NULL, ARG_CONFIG }, ++ { NULL }, ++ }; ++ int c; ++ ++ for (;;) { ++ c = getopt_long(argc, argv, "", options, NULL); ++ if (c < 0) ++ break; ++ ++ switch (c) { ++ case ARG_CONFIG: ++ r = nw_string_set(daemon->config_path, optarg); ++ if (r < 0) ++ return r; ++ ++ break; ++ ++ // Abort on any unrecognised option ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ + static int nw_daemon_setup_loop(nw_daemon* daemon) { + int r; + +@@ -398,7 +436,7 @@ static int nw_daemon_setup(nw_daemon* daemon) { + return 0; + } + +-int nw_daemon_create(nw_daemon** daemon) { ++int nw_daemon_create(nw_daemon** daemon, int argc, char* argv[]) { + int r; + + nw_daemon* d = calloc(1, sizeof(*d)); +@@ -408,6 +446,11 @@ int nw_daemon_create(nw_daemon** daemon) { + // Initialize reference counter + d->nrefs = 1; + ++ // Parse command line arguments ++ r = nw_daemon_parse_argv(d, argc, argv); ++ if (r) ++ goto ERROR; ++ + // Setup the daemon + r = nw_daemon_setup(d); + if (r) +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 74e19e6..8653af3 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -33,7 +33,7 @@ typedef struct nw_daemon nw_daemon; + #include "zone.h" + #include "zones.h" + +-int nw_daemon_create(nw_daemon** daemon); ++int nw_daemon_create(nw_daemon** daemon, int argc, char* argv[]); + + nw_daemon* nw_daemon_ref(nw_daemon* daemon); + nw_daemon* nw_daemon_unref(nw_daemon* daemon); +diff --git a/src/networkd/main.c b/src/networkd/main.c +index c8b9a79..f5f09f5 100644 +--- a/src/networkd/main.c ++++ b/src/networkd/main.c +@@ -222,7 +222,7 @@ int main(int argc, char** argv) { + return r; + + // Create the daemon +- r = nw_daemon_create(&daemon); ++ r = nw_daemon_create(&daemon, argc, argv); + if (r) + return r; + +-- +2.39.2 + diff --git a/network/patches/0275-networkd-Open-config-directory-and-keep-a-handle-to-.patch b/network/patches/0275-networkd-Open-config-directory-and-keep-a-handle-to-.patch new file mode 100644 index 000000000..cef8539d8 --- /dev/null +++ b/network/patches/0275-networkd-Open-config-directory-and-keep-a-handle-to-.patch @@ -0,0 +1,163 @@ +From 5a925d5f91e32245446ba568da2549b08913c0c7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 05:28:51 +0000 +Subject: [PATCH 275/304] networkd: Open config directory and keep a handle to + it + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 2 +- + src/networkd/config.h | 1 + + src/networkd/daemon.c | 71 ++++++++++++++++++++++++++++++++++++++----- + 3 files changed, 66 insertions(+), 8 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index ee5e8b8..b7f3f72 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -229,7 +229,7 @@ int nw_config_flush(nw_config* config) { + return 0; + } + +-static int nw_config_readf(nw_config* config, FILE* f) { ++int nw_config_readf(nw_config* config, FILE* f) { + char* line = NULL; + size_t length = 0; + int r; +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 63e9d18..d532da3 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -40,6 +40,7 @@ const char* nw_config_path(nw_config* config); + + int nw_config_flush(nw_config* config); + ++int nw_config_readf(nw_config* config, FILE* f); + int nw_config_read(nw_config* config); + int nw_config_write(nw_config* config); + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index 31fda8e..e645bee 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -18,7 +18,9 @@ + # # + #############################################################################*/ + ++#include + #include ++#include + #include + #include + #include +@@ -48,7 +50,7 @@ + struct nw_daemon { + int nrefs; + +- char config_path[PATH_MAX]; ++ DIR* config_dir; + nw_config* config; + + // Event Loop +@@ -95,6 +97,43 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig + return 0; + } + ++/* ++ Configuration ++*/ ++ ++static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { ++ daemon->config_dir = opendir(path); ++ if (!daemon->config_dir) { ++ ERROR("Could not open %s: %m\n", path); ++ return -errno; ++ } ++ ++ return 0; ++} ++ ++static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { ++ int r; ++ ++ // If no configuration path has been opened yet, we will open something ++ if (!daemon->config_dir) { ++ r = nw_daemon_config_open(daemon, CONFIG_DIR); ++ if (r < 0) { ++ errno = -r; ++ return NULL; ++ } ++ } ++ ++ // Open the file ++ int fd = openat(dirfd(daemon->config_dir), path, 0); ++ if (fd < 0) { ++ ERROR("Could not open configuration file %s: %m\n", path); ++ return NULL; ++ } ++ ++ // Return a file handle ++ return fdopen(fd, mode); ++} ++ + static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { + enum { + ARG_CONFIG, +@@ -114,10 +153,9 @@ static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { + + switch (c) { + case ARG_CONFIG: +- r = nw_string_set(daemon->config_path, optarg); ++ r = nw_daemon_config_open(daemon, optarg); + if (r < 0) + return r; +- + break; + + // Abort on any unrecognised option +@@ -174,12 +212,29 @@ static int nw_daemon_setup_loop(nw_daemon* daemon) { + } + + static int nw_daemon_load_config(nw_daemon* daemon) { ++ FILE* f = NULL; + int r; + +- // Read configuration file +- r = nw_config_create(&daemon->config, CONFIG_DIR "/settings"); +- if (r) +- return r; ++ // Open the configuration file ++ f = nw_daemon_config_fopen(daemon, "settings", "r"); ++ if (!f) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Create configuration ++ r = nw_config_create(&daemon->config, NULL); ++ if (r < 0) ++ goto ERROR; ++ ++ // Parse configuration ++ r = nw_config_readf(daemon->config, f); ++ if (r < 0) ++ goto ERROR; ++ ++ERROR: ++ if (f) ++ fclose(f); + + return r; + } +@@ -482,6 +537,8 @@ static void nw_daemon_free(nw_daemon* daemon) { + // Cleanup common objects + nw_daemon_cleanup(daemon); + ++ if (daemon->config_dir) ++ closedir(daemon->config_dir); + if (daemon->stats_collector_event) + sd_event_source_unref(daemon->stats_collector_event); + if (daemon->bus) +-- +2.39.2 + diff --git a/network/patches/0276-networkd-Hold-a-file-descriptor-instead-of-DIR.patch b/network/patches/0276-networkd-Hold-a-file-descriptor-instead-of-DIR.patch new file mode 100644 index 000000000..f6e74eecd --- /dev/null +++ b/network/patches/0276-networkd-Hold-a-file-descriptor-instead-of-DIR.patch @@ -0,0 +1,99 @@ +From f6e3fd80ad4d86681ad2949567b6763c41530f16 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 05:37:57 +0000 +Subject: [PATCH 276/304] networkd: Hold a file descriptor instead of DIR* + +Signed-off-by: Michael Tremer +--- + src/networkd/daemon.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index e645bee..f0ef4aa 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -18,12 +18,12 @@ + # # + #############################################################################*/ + +-#include + #include + #include + #include + #include + #include ++#include + + #include + #include +@@ -50,7 +50,8 @@ + struct nw_daemon { + int nrefs; + +- DIR* config_dir; ++ // Configuration ++ int configfd; + nw_config* config; + + // Event Loop +@@ -102,8 +103,9 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig + */ + + static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { +- daemon->config_dir = opendir(path); +- if (!daemon->config_dir) { ++ // Open the directory ++ daemon->configfd = open(path, O_DIRECTORY); ++ if (daemon->configfd < 0) { + ERROR("Could not open %s: %m\n", path); + return -errno; + } +@@ -112,19 +114,8 @@ static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { + } + + static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { +- int r; +- +- // If no configuration path has been opened yet, we will open something +- if (!daemon->config_dir) { +- r = nw_daemon_config_open(daemon, CONFIG_DIR); +- if (r < 0) { +- errno = -r; +- return NULL; +- } +- } +- + // Open the file +- int fd = openat(dirfd(daemon->config_dir), path, 0); ++ int fd = openat(daemon->configfd, path, 0); + if (fd < 0) { + ERROR("Could not open configuration file %s: %m\n", path); + return NULL; +@@ -215,6 +206,13 @@ static int nw_daemon_load_config(nw_daemon* daemon) { + FILE* f = NULL; + int r; + ++ // If no configuration path has been opened yet, we will open something ++ if (!daemon->configfd) { ++ r = nw_daemon_config_open(daemon, CONFIG_DIR); ++ if (r < 0) ++ goto ERROR; ++ } ++ + // Open the configuration file + f = nw_daemon_config_fopen(daemon, "settings", "r"); + if (!f) { +@@ -537,8 +535,8 @@ static void nw_daemon_free(nw_daemon* daemon) { + // Cleanup common objects + nw_daemon_cleanup(daemon); + +- if (daemon->config_dir) +- closedir(daemon->config_dir); ++ if (daemon->configfd > 0) ++ close(daemon->configfd); + if (daemon->stats_collector_event) + sd_event_source_unref(daemon->stats_collector_event); + if (daemon->bus) +-- +2.39.2 + diff --git a/network/patches/0277-networkd-Add-a-simple-test-environment.patch b/network/patches/0277-networkd-Add-a-simple-test-environment.patch new file mode 100644 index 000000000..34754b7f2 --- /dev/null +++ b/network/patches/0277-networkd-Add-a-simple-test-environment.patch @@ -0,0 +1,197 @@ +From c920185ee99d0f143946925aba0668785225f6f4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 07:46:40 +0000 +Subject: [PATCH 277/304] networkd: Add a simple test environment + +Signed-off-by: Michael Tremer +--- + Makefile.am | 24 ++++- + test/networkd/00_launch.t/config/settings | 0 + test/networkd/00_launch.t/test.sh | 4 + + test/networkd/test.sh | 108 ++++++++++++++++++++++ + 4 files changed, 132 insertions(+), 4 deletions(-) + create mode 100644 test/networkd/00_launch.t/config/settings + create mode 100644 test/networkd/00_launch.t/test.sh + create mode 100644 test/networkd/test.sh + +diff --git a/Makefile.am b/Makefile.am +index f4c22b4..fe1e4d1 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -59,6 +59,7 @@ DISTCLEANFILES = + EXTRA_DIST = + INSTALL_DIRS = + INSTALL_EXEC_HOOKS = ++TESTS = + UNINSTALL_EXEC_HOOKS = + noinst_DATA = + network_PROGRAMS = +@@ -690,12 +691,10 @@ TESTS_ENVIRONMENT = \ + + dist_check_DATA = \ + test/constants.sh \ +- test/test-functions ++ test/test-functions \ ++ test/networkd/test.sh + + dist_check_SCRIPTS = \ +- $(TESTS) +- +-TESTS = \ + test/load-library \ + test/functions/ip/ip_detect_protocol \ + test/functions/ip/ip_get_prefix \ +@@ -706,6 +705,23 @@ TESTS = \ + test/functions/ip/ip_protocol_is_supported \ + test/functions/ip/ip_split_prefix + ++TESTS += $(dist_check_SCRIPTS) ++ ++TEST_EXTENSIONS = .t ++ ++NETWORKD_TESTS = \ ++ test/networkd/00_launch.t ++ ++TESTS += $(NETWORKD_TESTS) ++ ++EXTRA_DIST += \ ++ test/networkd/test.sh \ ++ $(NETWORKD_TESTS) ++ ++# Run all networkd tests in their own namespaces ++T_LOG_COMPILER = unshare --net --ipc --uts --user --cgroup --time --pid --fork \ ++ $(SHELL) test/networkd/test.sh ++ + # - NITSI tests ---------------------------------------------------------------- + + # Files for the virtual environment +diff --git a/test/networkd/00_launch.t/config/settings b/test/networkd/00_launch.t/config/settings +new file mode 100644 +index 0000000..e69de29 +diff --git a/test/networkd/00_launch.t/test.sh b/test/networkd/00_launch.t/test.sh +new file mode 100644 +index 0000000..f3d7bbc +--- /dev/null ++++ b/test/networkd/00_launch.t/test.sh +@@ -0,0 +1,4 @@ ++#!/bin/bash ++ ++# Simply run networkctl to check whether it works ++./networkctl --version +diff --git a/test/networkd/test.sh b/test/networkd/test.sh +new file mode 100644 +index 0000000..2af7479 +--- /dev/null ++++ b/test/networkd/test.sh +@@ -0,0 +1,108 @@ ++#!/bin/bash ++############################################################################### ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++############################################################################### ++ ++# Break if anything fails ++set -e ++ ++# Turn on job control ++set -o monitor ++ ++run_script() { ++ local script="${1}" ++ shift ++ ++ if [ -f "${script}" ]; then ++ echo "Launching ${script}..." ++ ++ # Launch the script in a separate shell and echo every command ++ if ! ${SHELL} -xe "${script}"; then ++ echo "${script} failed" >&2 ++ return 1 ++ fi ++ fi ++ ++ return 0 ++} ++ ++# Launches networkd in the background ++launch_networkd() { ++ echo "Launching networkd..." ++ ++ # Launch it! ++ coproc networkd { ./networkd "$@"; } ++ ++ echo "networkd launched as PID ${networkd_PID}" ++} ++ ++terminate_networkd() { ++ if [ -n "${networkd_PID}" ]; then ++ # Send SIGTERM ++ kill -TERM "${networkd_PID}" ++ ++ # Wait until networkd has finished ++ echo "Waiting for networkd to terminate..." ++ wait "${networkd_PID}" ++ ++ echo "networkd has terminated" ++ fi ++} ++ ++# Make sure networkd has been terminated when this script exits ++trap "terminate_networkd" EXIT ++ ++main() { ++ local test="${1}" ++ shift ++ ++ echo "Running ${test}..." ++ ++ # Check if the test exists ++ if [ ! -d "${test}" ]; then ++ echo "Test '${test}' does not exist" >&2 ++ return 2 ++ fi ++ ++ # Run prepare script ++ if ! run_script "${test}/prepare.sh"; then ++ return 1 ++ fi ++ ++ # Launch networkd ++ launch_networkd --config="${test}/config" ++ ++ # Run test script ++ if ! run_script "${test}/test.sh"; then ++ return 1 ++ fi ++ ++ # Terminate networkd ++ terminate_networkd ++ ++ # Run cleanup script ++ if ! run_script "${test}/cleanup.sh"; then ++ return 1 ++ fi ++ ++ return 0 ++} ++ ++# Call main() ++main "$@" || exit $? +-- +2.39.2 + diff --git a/network/patches/0278-test-Run-ip-d-link-to-show-the-status-of-the-environ.patch b/network/patches/0278-test-Run-ip-d-link-to-show-the-status-of-the-environ.patch new file mode 100644 index 000000000..c471daed9 --- /dev/null +++ b/network/patches/0278-test-Run-ip-d-link-to-show-the-status-of-the-environ.patch @@ -0,0 +1,48 @@ +From 9ddb7dad28a2122317b0551884640afdf14deadb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 07:49:54 +0000 +Subject: [PATCH 278/304] test: Run "ip -d link" to show the status of the + environment + +Signed-off-by: Michael Tremer +--- + test/networkd/test.sh | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/test/networkd/test.sh b/test/networkd/test.sh +index 2af7479..a22aeb3 100644 +--- a/test/networkd/test.sh ++++ b/test/networkd/test.sh +@@ -42,6 +42,19 @@ run_script() { + return 0 + } + ++dump_command() { ++ echo "Output of $@" ++ ++ # Run the command ++ $@ 2>&1 ++ ++ echo "EOF" ++} ++ ++dump_status() { ++ dump_command "ip -d link" ++} ++ + # Launches networkd in the background + launch_networkd() { + echo "Launching networkd..." +@@ -54,6 +67,9 @@ launch_networkd() { + + terminate_networkd() { + if [ -n "${networkd_PID}" ]; then ++ # Collect some status information ++ dump_status ++ + # Send SIGTERM + kill -TERM "${networkd_PID}" + +-- +2.39.2 + diff --git a/network/patches/0279-networkctl-Terminate-after-showing-help-or-version.patch b/network/patches/0279-networkctl-Terminate-after-showing-help-or-version.patch new file mode 100644 index 000000000..ea97f6077 --- /dev/null +++ b/network/patches/0279-networkctl-Terminate-after-showing-help-or-version.patch @@ -0,0 +1,64 @@ +From dc2a5320b848576772c261b76b23b87715d118a7 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 07:51:50 +0000 +Subject: [PATCH 279/304] networkctl: Terminate after showing help or version + +Signed-off-by: Michael Tremer +--- + src/networkctl/main.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/src/networkctl/main.c b/src/networkctl/main.c +index 0ba7284..fde77b8 100644 +--- a/src/networkctl/main.c ++++ b/src/networkctl/main.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -45,13 +46,13 @@ static int networkctl_main(sd_bus* bus, int argc, char* argv[]) { + return command_dispatch(bus, commands, argc, argv); + } + +-static int version(void) { ++static void version(void) { + printf("networkctl %s\n", PACKAGE_VERSION); + +- return 0; ++ exit(0); + } + +-static int help(void) { ++static void help(void) { + printf( + "%s [OPTIONS...] COMMAND\n\n" + "Options:\n" +@@ -60,7 +61,7 @@ static int help(void) { + program_invocation_short_name + ); + +- return 0; ++ exit(0); + } + + static int parse_argv(int argc, char* argv[]) { +@@ -82,10 +83,10 @@ static int parse_argv(int argc, char* argv[]) { + + switch (c) { + case 'h': +- return help(); ++ help(); + + case ARG_VERSION: +- return version(); ++ version(); + + case '?': + return -EINVAL; +-- +2.39.2 + diff --git a/network/patches/0280-test-Be-less-patient-if-networkd-does-not-want-to-te.patch b/network/patches/0280-test-Be-less-patient-if-networkd-does-not-want-to-te.patch new file mode 100644 index 000000000..33af11d9d --- /dev/null +++ b/network/patches/0280-test-Be-less-patient-if-networkd-does-not-want-to-te.patch @@ -0,0 +1,84 @@ +From f1e43a02719530f865fd7818b60b706c551d143c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 08:20:41 +0000 +Subject: [PATCH 280/304] test: Be less patient if networkd does not want to + terminate + +Signed-off-by: Michael Tremer +--- + test/networkd/test.sh | 43 +++++++++++++++++++++++++++++++------------ + 1 file changed, 31 insertions(+), 12 deletions(-) + +diff --git a/test/networkd/test.sh b/test/networkd/test.sh +index a22aeb3..7690978 100644 +--- a/test/networkd/test.sh ++++ b/test/networkd/test.sh +@@ -63,27 +63,43 @@ launch_networkd() { + coproc networkd { ./networkd "$@"; } + + echo "networkd launched as PID ${networkd_PID}" ++ ++ sleep 1 + } + + terminate_networkd() { +- if [ -n "${networkd_PID}" ]; then +- # Collect some status information +- dump_status +- +- # Send SIGTERM +- kill -TERM "${networkd_PID}" ++ local seconds=0 + +- # Wait until networkd has finished +- echo "Waiting for networkd to terminate..." +- wait "${networkd_PID}" ++ if [ -n "${networkd_PID}" ]; then ++ while [ -n "${networkd_PID}" ] && kill -0 "${networkd_PID}"; do ++ case "${seconds}" in ++ # Send SIGTERM in the beginning ++ 0) ++ echo "Sending SIGTERM to networkd" ++ kill -TERM "${networkd_PID}" ++ ;; ++ ++ # After 5 seconds, send SIGKILL ++ 5) ++ echo "Sending SIGKILL to networkd" ++ kill -KILL "${networkd_PID}" ++ ++ # It is an error, if we have to kill networkd ++ exit 1 ++ ;; ++ esac ++ ++ # Wait for a moment ++ sleep 1 ++ ++ # Increment seconds ++ (( seconds++ )) ++ done + + echo "networkd has terminated" + fi + } + +-# Make sure networkd has been terminated when this script exits +-trap "terminate_networkd" EXIT +- + main() { + local test="${1}" + shift +@@ -112,6 +128,9 @@ main() { + # Terminate networkd + terminate_networkd + ++ # Collect some status information ++ dump_status ++ + # Run cleanup script + if ! run_script "${test}/cleanup.sh"; then + return 1 +-- +2.39.2 + diff --git a/network/patches/0281-test-Run-networkd-as-root-in-its-own-namespace.patch b/network/patches/0281-test-Run-networkd-as-root-in-its-own-namespace.patch new file mode 100644 index 000000000..44e59411c --- /dev/null +++ b/network/patches/0281-test-Run-networkd-as-root-in-its-own-namespace.patch @@ -0,0 +1,26 @@ +From 119cc5be2dc054f619226a27ffd855e849330adf Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 09:27:51 +0000 +Subject: [PATCH 281/304] test: Run networkd as root in its own namespace + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index fe1e4d1..08e04a1 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -720,7 +720,7 @@ EXTRA_DIST += \ + + # Run all networkd tests in their own namespaces + T_LOG_COMPILER = unshare --net --ipc --uts --user --cgroup --time --pid --fork \ +- $(SHELL) test/networkd/test.sh ++ --map-root-user --keep-caps $(SHELL) test/networkd/test.sh + + # - NITSI tests ---------------------------------------------------------------- + +-- +2.39.2 + diff --git a/network/patches/0282-ports-Refactor-enumerating-ports.patch b/network/patches/0282-ports-Refactor-enumerating-ports.patch new file mode 100644 index 000000000..7295bf7bc --- /dev/null +++ b/network/patches/0282-ports-Refactor-enumerating-ports.patch @@ -0,0 +1,636 @@ +From 8edf3da1c28feb4e2af80786c5e41e52f07b0f73 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 09:29:01 +0000 +Subject: [PATCH 282/304] ports: Refactor enumerating ports + +This entails a little rewrite how we deal with where configuration files +are stored. + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 117 ++++++++++-------------------------------- + src/networkd/config.h | 11 ++-- + src/networkd/daemon.c | 23 ++++++--- + src/networkd/daemon.h | 9 ++++ + src/networkd/port.c | 64 +++++++++++++++++------ + src/networkd/port.h | 3 +- + src/networkd/ports.c | 80 +++++++++++++++++------------ + src/networkd/zone.c | 27 ++++++++-- + 8 files changed, 172 insertions(+), 162 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index b7f3f72..3d444c4 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -53,9 +53,6 @@ struct nw_config_option { + struct nw_config { + int nrefs; + +- // The path to the configuration file +- char path[PATH_MAX]; +- + STAILQ_HEAD(config_entries, nw_config_entry) entries; + + // Options +@@ -118,7 +115,7 @@ static void nw_config_free(nw_config* config) { + free(config); + } + +-int nw_config_create(nw_config** config, const char* path) { ++int nw_config_create(nw_config** config, FILE* f) { + int r; + + nw_config* c = calloc(1, sizeof(*c)); +@@ -134,15 +131,10 @@ int nw_config_create(nw_config** config, const char* path) { + // Initialise options + STAILQ_INIT(&c->options); + +- // Store the path +- if (path) { +- r = nw_string_set(c->path, path); +- if (r) +- goto ERROR; +- +- // Try to read the configuration from path +- r = nw_config_read(c); +- if (r) ++ // Read configuration ++ if (f) { ++ r = nw_config_read(c, f); ++ if (r < 0) + goto ERROR; + } + +@@ -156,6 +148,25 @@ ERROR: + return r; + } + ++int nw_config_open(nw_config** config, const char* path) { ++ FILE* f = NULL; ++ int r; ++ ++ // Open path ++ f = fopen(path, "r"); ++ if (!f) ++ return -errno; ++ ++ // Create a new configuration ++ r = nw_config_create(config, f); ++ ++ERROR: ++ if (f) ++ fclose(f); ++ ++ return r; ++} ++ + nw_config* nw_config_ref(nw_config* config) { + config->nrefs++; + +@@ -170,17 +181,6 @@ nw_config* nw_config_unref(nw_config* config) { + return NULL; + } + +-int nw_config_destroy(nw_config* config) { +- int r; +- +- // Drop all entries +- r = nw_config_flush(config); +- if (r) +- return r; +- +- return unlink(config->path); +-} +- + int nw_config_copy(nw_config* config, nw_config** copy) { + struct nw_config_entry* entry = NULL; + nw_config* c = NULL; +@@ -208,13 +208,6 @@ ERROR: + return r; + } + +-const char* nw_config_path(nw_config* config) { +- if (*config->path) +- return config->path; +- +- return NULL; +-} +- + int nw_config_flush(nw_config* config) { + struct nw_config_entry* entry = NULL; + +@@ -229,7 +222,7 @@ int nw_config_flush(nw_config* config) { + return 0; + } + +-int nw_config_readf(nw_config* config, FILE* f) { ++int nw_config_read(nw_config* config, FILE* f) { + char* line = NULL; + size_t length = 0; + int r; +@@ -275,39 +268,7 @@ int nw_config_readf(nw_config* config, FILE* f) { + return r; + } + +-int nw_config_read(nw_config* config) { +- FILE* f = NULL; +- int r; +- +- // We cannot read if path is not set +- if (!*config->path) { +- errno = ENOTSUP; +- return 1; +- } +- +- // Open the file +- f = fopen(config->path, "r"); +- if (!f) { +- // Silently ignore if the file does not exist +- if (errno == ENOENT) +- return 0; +- +- ERROR("Could not read configuration file %s: %m\n", config->path); +- r = 1; +- goto ERROR; +- } +- +- // Read from file +- r = nw_config_readf(config, f); +- +-ERROR: +- if (f) +- fclose(f); +- +- return r; +-} +- +-static int nw_config_writef(nw_config* config, FILE* f) { ++int nw_config_write(nw_config* config, FILE* f) { + struct nw_config_entry* entry = NULL; + int r; + +@@ -327,32 +288,6 @@ static int nw_config_writef(nw_config* config, FILE* f) { + return 0; + } + +-int nw_config_write(nw_config* config) { +- int r; +- +- // We cannot write if path is not set +- if (!*config->path) { +- errno = ENOTSUP; +- return 1; +- } +- +- FILE* f = fopen(config->path, "w"); +- if (!f) { +- ERROR("Failed to open %s for writing: %m\n", config->path); +- r = 1; +- goto ERROR; +- } +- +- // Write configuration +- r = nw_config_writef(config, f); +- +-ERROR: +- if (f) +- fclose(f); +- +- return r; +-} +- + static struct nw_config_entry* nw_config_find(nw_config* config, const char* key) { + struct nw_config_entry* entry = NULL; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index d532da3..b25d05e 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -28,21 +28,18 @@ + + typedef struct nw_config nw_config; + +-int nw_config_create(nw_config** config, const char* path); ++int nw_config_create(nw_config** config, FILE* f); ++int nw_config_open(nw_config** config, const char* path); + + nw_config* nw_config_ref(nw_config* config); + nw_config* nw_config_unref(nw_config* config); + +-int nw_config_destroy(nw_config* config); + int nw_config_copy(nw_config* config, nw_config** copy); + +-const char* nw_config_path(nw_config* config); +- + int nw_config_flush(nw_config* config); + +-int nw_config_readf(nw_config* config, FILE* f); +-int nw_config_read(nw_config* config); +-int nw_config_write(nw_config* config); ++int nw_config_read(nw_config* config, FILE* f); ++int nw_config_write(nw_config* config, FILE* f); + + int nw_config_del(nw_config* config, const char* key); + +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index f0ef4aa..a62e343 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -113,7 +113,7 @@ static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { + return 0; + } + +-static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { ++FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { + // Open the file + int fd = openat(daemon->configfd, path, 0); + if (fd < 0) { +@@ -125,6 +125,16 @@ static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const c + return fdopen(fd, mode); + } + ++DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path) { ++ int fd = openat(daemon->configfd, path, O_DIRECTORY); ++ if (fd < 0) { ++ ERROR("Could not open configuration directory %s: %m\n", path); ++ return NULL; ++ } ++ ++ return fdopendir(fd); ++} ++ + static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { + enum { + ARG_CONFIG, +@@ -221,12 +231,7 @@ static int nw_daemon_load_config(nw_daemon* daemon) { + } + + // Create configuration +- r = nw_config_create(&daemon->config, NULL); +- if (r < 0) +- goto ERROR; +- +- // Parse configuration +- r = nw_config_readf(daemon->config, f); ++ r = nw_config_create(&daemon->config, f); + if (r < 0) + goto ERROR; + +@@ -615,10 +620,12 @@ int nw_daemon_save(nw_daemon* daemon) { + + DEBUG("Saving configuration...\n"); + ++#if 0 + // Save settings +- r = nw_config_write(daemon->config); ++ r = nw_config_write(daemon->config, f); + if (r) + return r; ++#endif + + // Save ports + r = nw_ports_save(daemon->ports); +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index 8653af3..b03086c 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -21,6 +21,9 @@ + #ifndef NETWORKD_DAEMON_H + #define NETWORKD_DAEMON_H + ++#include ++#include ++ + #include + #include + +@@ -44,6 +47,12 @@ int nw_daemon_reload(nw_daemon* daemon); + + int nw_daemon_save(nw_daemon* daemon); + ++/* ++ Configuration ++*/ ++FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode); ++DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path); ++ + /* + Bus + */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index fb5d418..7d654e3 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -147,7 +147,7 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + // Allocate a new object + nw_port* p = calloc(1, sizeof(*p)); + if (!p) +- return 1; ++ return -errno; + + // Store a reference to the daemon + p->daemon = nw_daemon_ref(daemon); +@@ -172,17 +172,17 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + + // Store the name + r = nw_string_set(p->name, name); +- if (r) ++ if (r < 0) + goto ERROR; + + // Copy the configuration + r = nw_config_copy(config, &p->config); +- if (r) ++ if (r < 0) + goto ERROR; + + // Setup the port + r = nw_port_setup(p); +- if (r) ++ if (r < 0) + goto ERROR; + + // Validate the configuration +@@ -210,32 +210,47 @@ ERROR: + return r; + } + +-int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, +- const char* name, const char* path) { ++int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) { + nw_config* config = NULL; ++ FILE* f = NULL; ++ char path[PATH_MAX]; + int r; + ++ // Make path ++ r = nw_string_format(path, "ports/%s", name); ++ if (r < 0) ++ goto ERROR; ++ ++ // Open the configuration file ++ f = nw_daemon_config_fopen(daemon, path, "r"); ++ if (!f) { ++ r = -errno; ++ goto ERROR; ++ } ++ + // Initialize the configuration +- r = nw_config_create(&config, path); +- if (r) ++ r = nw_config_create(&config, f); ++ if (r < 0) + goto ERROR; + + // Fetch the type + const char* type = nw_config_get(config, "TYPE"); + if (!type) { + ERROR("Port configuration %s has no TYPE\n", path); +- r = 1; ++ r = -ENOTSUP; + goto ERROR; + } + + // Create a new port + r = nw_port_create(port, daemon, nw_port_type_id_from_string(type), name, config); +- if (r) ++ if (r < 0) + goto ERROR; + + ERROR: + if (config) + nw_config_unref(config); ++ if (f) ++ fclose(f); + + return r; + } +@@ -316,24 +331,39 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + } + + int nw_port_save(nw_port* port) { ++ char path[PATH_MAX]; ++ FILE* f = NULL; + int r; + ++ // Compose path ++ r = nw_string_format(path, "ports/%s", port->name); ++ if (r < 0) ++ return r; ++ ++ // Open file ++ f = nw_daemon_config_fopen(port->daemon, path, "w"); ++ if (!f) { ++ r = -errno; ++ goto ERROR; ++ } ++ + // Write out the configuration + r = nw_config_options_write(port->config); + if (r < 0) + goto ERROR; + + // Write the configuration +- r = nw_config_write(port->config); +- if (r) +- return r; +- +- return 0; ++ r = nw_config_write(port->config, f); ++ if (r < 0) ++ goto ERROR; + + ERROR: +- ERROR("Could not save configuration for port %s: %s\n", port->name, strerror(-r)); ++ if (f) ++ fclose(f); ++ if (r) ++ ERROR("Could not save configuration for port %s: %s\n", port->name, strerror(-r)); + +- return 1; ++ return r; + } + + const char* nw_port_name(nw_port* port) { +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 7c2e436..efa2fdb 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -95,8 +95,7 @@ struct nw_port { + + int nw_port_create(nw_port** port, nw_daemon* daemon, + const nw_port_type_id_t type, const char* name, nw_config* config); +-int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, +- const char* name, const char* path); ++int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name); + + nw_port* nw_port_ref(nw_port* port); + nw_port* nw_port_unref(nw_port* port); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 65545e8..761e564 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -18,6 +18,7 @@ + # # + #############################################################################*/ + ++#include + #include + #include + #include +@@ -129,43 +130,14 @@ static int nw_ports_add_port(nw_ports* ports, nw_port* port) { + return 0; + } + +-static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { ++static int nw_ports_enumerate_port(nw_ports* ports, const char* name) { + nw_port* port = NULL; + int r; + +- nw_ports* ports = (nw_ports*)data; +- +- // Skip anything that isn't a regular file +- if (!S_ISREG(s->st_mode)) +- return 0; +- +- // Find the basename of the file +- const char* name = nw_path_basename(path); +- +- // Break on invalid paths +- if (!name) +- return 0; +- +- // Skip any hidden files +- if (*name == '.') +- return 0; +- + // Create a new port +- r = nw_port_create_from_config(&port, ports->daemon, name, path); +- switch (r) { +- // All okay +- case 0: +- break; +- +- // Invalid configuration +- case 1: +- ERROR("Could not open port %s\n", name); +- r = 0; +- goto ERROR; +- +- default: +- goto ERROR; +- } ++ r = nw_port_open(&port, ports->daemon, name); ++ if (r < 0 || r == 1) ++ goto ERROR; + + // Add the port to the list + r = nw_ports_add_port(ports, port); +@@ -180,7 +152,47 @@ ERROR: + } + + int nw_ports_enumerate(nw_ports* ports) { +- return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); ++ DIR* d = NULL; ++ struct dirent* entry = NULL; ++ int r; ++ ++ // Open the ports directory ++ d = nw_daemon_config_opendir(ports->daemon, "ports"); ++ if (!d) { ++ switch (errno) { ++ case ENOENT: ++ return 0; ++ ++ default: ++ return -errno; ++ } ++ } ++ ++ for (;;) { ++ // Read the next entry ++ entry = readdir(d); ++ if (!entry) ++ break; ++ ++ // Skip anything that is not a regular file ++ if (entry->d_type != DT_REG) ++ continue; ++ ++ // Skip hidden files ++ if (entry->d_name[0] == '.') ++ continue; ++ ++ // Enumerate the port ++ r = nw_ports_enumerate_port(ports, entry->d_name); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ERROR: ++ if (d) ++ closedir(d); ++ ++ return r; + } + + nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name) { +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 9f5b7f8..cc5fdaf 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -120,6 +120,7 @@ static int nw_zone_setup(nw_zone* zone) { + goto ERROR; + } + ++#if 0 + // Compose the path to the main configuration file + r = nw_zone_path(zone, path, "%s", "settings"); + if (r) +@@ -129,6 +130,7 @@ static int nw_zone_setup(nw_zone* zone) { + r = nw_config_create(&zone->config, path); + if (r) + goto ERROR; ++#endif + + ERROR: + if (link) +@@ -193,13 +195,32 @@ int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data) { + } + + int nw_zone_save(nw_zone* zone) { ++ char path[PATH_MAX]; ++ FILE* f = NULL; + int r; + +- r = nw_config_write(zone->config); ++ // Compose path ++ r = nw_string_format(path, "zones/%s/settings", zone->name); ++ if (r < 0) ++ goto ERROR; ++ ++ // Open file ++ f = nw_daemon_config_fopen(zone->daemon, path, "w"); ++ if (!f) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Write the configuration ++ r = nw_config_write(zone->config, f); + if (r) +- return r; ++ goto ERROR; + +- return 0; ++ERROR: ++ if (f) ++ fclose(f); ++ ++ return r; + } + + const char* nw_zone_name(nw_zone* zone) { +-- +2.39.2 + diff --git a/network/patches/0283-tests-Add-new-test-that-creates-two-dummy-interfaces.patch b/network/patches/0283-tests-Add-new-test-that-creates-two-dummy-interfaces.patch new file mode 100644 index 000000000..17a4933da --- /dev/null +++ b/network/patches/0283-tests-Add-new-test-that-creates-two-dummy-interfaces.patch @@ -0,0 +1,67 @@ +From b2134e9ee25fe3aedddc9f6ef812881724122a81 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 09:38:00 +0000 +Subject: [PATCH 283/304] tests: Add new test that creates two dummy interfaces + +Signed-off-by: Michael Tremer +--- + Makefile.am | 3 ++- + test/networkd/01_dummy.t/config/ports/d0 | 2 ++ + test/networkd/01_dummy.t/config/ports/d1 | 2 ++ + test/networkd/01_dummy.t/config/settings | 0 + test/networkd/01_dummy.t/test.sh | 7 +++++++ + 5 files changed, 13 insertions(+), 1 deletion(-) + create mode 100644 test/networkd/01_dummy.t/config/ports/d0 + create mode 100644 test/networkd/01_dummy.t/config/ports/d1 + create mode 100644 test/networkd/01_dummy.t/config/settings + create mode 100644 test/networkd/01_dummy.t/test.sh + +diff --git a/Makefile.am b/Makefile.am +index 08e04a1..2df9185 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -710,7 +710,8 @@ TESTS += $(dist_check_SCRIPTS) + TEST_EXTENSIONS = .t + + NETWORKD_TESTS = \ +- test/networkd/00_launch.t ++ test/networkd/00_launch.t \ ++ test/networkd/01_dummy.t + + TESTS += $(NETWORKD_TESTS) + +diff --git a/test/networkd/01_dummy.t/config/ports/d0 b/test/networkd/01_dummy.t/config/ports/d0 +new file mode 100644 +index 0000000..36a350b +--- /dev/null ++++ b/test/networkd/01_dummy.t/config/ports/d0 +@@ -0,0 +1,2 @@ ++TYPE=dummy ++ADDRESS=00:11:22:33:44:55 +diff --git a/test/networkd/01_dummy.t/config/ports/d1 b/test/networkd/01_dummy.t/config/ports/d1 +new file mode 100644 +index 0000000..d040863 +--- /dev/null ++++ b/test/networkd/01_dummy.t/config/ports/d1 +@@ -0,0 +1,2 @@ ++TYPE=dummy ++ADDRESS=00:55:44:33:22:11 +diff --git a/test/networkd/01_dummy.t/config/settings b/test/networkd/01_dummy.t/config/settings +new file mode 100644 +index 0000000..e69de29 +diff --git a/test/networkd/01_dummy.t/test.sh b/test/networkd/01_dummy.t/test.sh +new file mode 100644 +index 0000000..fff0d69 +--- /dev/null ++++ b/test/networkd/01_dummy.t/test.sh +@@ -0,0 +1,7 @@ ++#!/bin/bash ++ ++# Dump status of d0 ++./networkctl port dump d0 ++ ++# Dump status of d1 ++./networkctl port dump d1 +-- +2.39.2 + diff --git a/network/patches/0284-tests-Always-dump-the-environment.patch b/network/patches/0284-tests-Always-dump-the-environment.patch new file mode 100644 index 000000000..20711f981 --- /dev/null +++ b/network/patches/0284-tests-Always-dump-the-environment.patch @@ -0,0 +1,47 @@ +From 5d4157c6655aea0673a60894420a9d5a0fa63dd6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 09:38:35 +0000 +Subject: [PATCH 284/304] tests: Always dump the environment + +Signed-off-by: Michael Tremer +--- + test/networkd/test.sh | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/test/networkd/test.sh b/test/networkd/test.sh +index 7690978..9cecf0a 100644 +--- a/test/networkd/test.sh ++++ b/test/networkd/test.sh +@@ -64,6 +64,9 @@ launch_networkd() { + + echo "networkd launched as PID ${networkd_PID}" + ++ # Wait until networkd is initialized ++ # XXX Calling sleep(8) is very racy and should be replaced by something that ++ # waits until networkd has connected to dbus + sleep 1 + } + +@@ -100,6 +103,9 @@ terminate_networkd() { + fi + } + ++# Collect some status information ++trap dump_status EXIT ++ + main() { + local test="${1}" + shift +@@ -128,9 +134,6 @@ main() { + # Terminate networkd + terminate_networkd + +- # Collect some status information +- dump_status +- + # Run cleanup script + if ! run_script "${test}/cleanup.sh"; then + return 1 +-- +2.39.2 + diff --git a/network/patches/0285-test-Collect-more-information-from-test-environment.patch b/network/patches/0285-test-Collect-more-information-from-test-environment.patch new file mode 100644 index 000000000..186fbe731 --- /dev/null +++ b/network/patches/0285-test-Collect-more-information-from-test-environment.patch @@ -0,0 +1,26 @@ +From fcc334a2e325a5d08b7abecb0eb67d7c944b4f35 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 10:00:06 +0000 +Subject: [PATCH 285/304] test: Collect more information from test environment + +Signed-off-by: Michael Tremer +--- + test/networkd/test.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/networkd/test.sh b/test/networkd/test.sh +index 9cecf0a..3eda034 100644 +--- a/test/networkd/test.sh ++++ b/test/networkd/test.sh +@@ -52,6 +52,8 @@ dump_command() { + } + + dump_status() { ++ dump_command "printenv" ++ dump_command "ps aux" + dump_command "ip -d link" + } + +-- +2.39.2 + diff --git a/network/patches/0286-ports-bonding-Use-correct-enum-for-mode.patch b/network/patches/0286-ports-bonding-Use-correct-enum-for-mode.patch new file mode 100644 index 000000000..79e10b021 --- /dev/null +++ b/network/patches/0286-ports-bonding-Use-correct-enum-for-mode.patch @@ -0,0 +1,38 @@ +From 5f9c43922b2b9e52ad61e5b8203854881da793a4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 10:17:58 +0000 +Subject: [PATCH 286/304] ports: bonding: Use correct enum for mode + +Signed-off-by: Michael Tremer +--- + src/networkd/port-bonding.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/networkd/port-bonding.c b/src/networkd/port-bonding.c +index ad02b5d..6064957 100644 +--- a/src/networkd/port-bonding.c ++++ b/src/networkd/port-bonding.c +@@ -97,13 +97,13 @@ int nw_port_bonding_set_mode(nw_port* port, const char* mode) { + const int m = nw_port_bonding_mode_from_string(mode); + + switch (m) { +- case BOND_MODE_ROUNDROBIN: +- case BOND_MODE_ACTIVEBACKUP: +- case BOND_MODE_XOR: +- case BOND_MODE_BROADCAST: +- case BOND_MODE_8023AD: +- case BOND_MODE_TLB: +- case BOND_MODE_ALB: ++ case NW_BONDING_MODE_ROUNDROBIN: ++ case NW_BONDING_MODE_ACTIVEBACKUP: ++ case NW_BONDING_MODE_XOR: ++ case NW_BONDING_MODE_BROADCAST: ++ case NW_BONDING_MODE_8023AD: ++ case NW_BONDING_MODE_TLB: ++ case NW_BONDING_MODE_ALB: + port->bonding.mode = m; + break; + +-- +2.39.2 + diff --git a/network/patches/0287-networkd-json-Include-string.h.patch b/network/patches/0287-networkd-json-Include-string.h.patch new file mode 100644 index 000000000..f0774c47f --- /dev/null +++ b/network/patches/0287-networkd-json-Include-string.h.patch @@ -0,0 +1,25 @@ +From e5c50dd3c189c96bead686cc728121d6f22dcd49 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 10:37:00 +0000 +Subject: [PATCH 287/304] networkd: json: Include string.h + +Signed-off-by: Michael Tremer +--- + src/networkd/json.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/networkd/json.h b/src/networkd/json.h +index 33e237a..19ced9a 100644 +--- a/src/networkd/json.h ++++ b/src/networkd/json.h +@@ -22,6 +22,7 @@ + #define NETWORKD_JSON_H + + #include ++#include + + #include + +-- +2.39.2 + diff --git a/network/patches/0288-ports-Add-support-for-VETH.patch b/network/patches/0288-ports-Add-support-for-VETH.patch new file mode 100644 index 000000000..b818eac50 --- /dev/null +++ b/network/patches/0288-ports-Add-support-for-VETH.patch @@ -0,0 +1,228 @@ +From 67d3fef1d79e933b8af64a39f89fef4b1f8b31cb Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 10:37:47 +0000 +Subject: [PATCH 288/304] ports: Add support for VETH + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkd/port-veth.c | 81 ++++++++++++++++++++++++++++++++++++++++ + src/networkd/port-veth.h | 35 +++++++++++++++++ + src/networkd/port.c | 6 +++ + src/networkd/port.h | 5 +++ + 5 files changed, 129 insertions(+) + create mode 100644 src/networkd/port-veth.c + create mode 100644 src/networkd/port-veth.h + +diff --git a/Makefile.am b/Makefile.am +index 2df9185..caab99e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -338,6 +338,8 @@ dist_networkd_SOURCES = \ + src/networkd/port-bus.h \ + src/networkd/port-dummy.c \ + src/networkd/port-dummy.h \ ++ src/networkd/port-veth.c \ ++ src/networkd/port-veth.h \ + src/networkd/port-vlan.c \ + src/networkd/port-vlan.h \ + src/networkd/stats-collector.c \ +diff --git a/src/networkd/port-veth.c b/src/networkd/port-veth.c +new file mode 100644 +index 0000000..44b1a0d +--- /dev/null ++++ b/src/networkd/port-veth.c +@@ -0,0 +1,81 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++ ++#include "json.h" ++#include "port.h" ++#include "port-veth.h" ++ ++static int nw_port_veth_setup(nw_port* port) { ++ int r; ++ ++ // Peer ++ r = NW_CONFIG_OPTION_STRING(port->config, "VETH_PEER", &port->veth.peer); ++ if (r < 0) ++ return 1; ++ ++ return 0; ++} ++ ++static int nw_port_veth_create_link(nw_port* port, sd_netlink_message* m) { ++ int r; ++ ++ // Open the container ++ r = sd_netlink_message_open_container(m, VETH_INFO_PEER); ++ if (r < 0) ++ return r; ++ ++ // Set VETH Peer ++ r = sd_netlink_message_append_string(m, IFLA_VLAN_ID, port->veth.peer); ++ if (r < 0) ++ return r; ++ ++ // Close the container ++ r = sd_netlink_message_close_container(m); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++static int nw_port_veth_to_json(nw_port* port, struct json_object* o) { ++ int r; ++ ++ // Add the VETH Peer ++ r = json_object_add_string(o, "VETHPeer", port->veth.peer); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++const nw_port_type_t nw_port_type_veth = { ++ .kind = "veth", ++ ++ // Configuration ++ .setup = nw_port_veth_setup, ++ ++ // Link ++ .create_link = nw_port_veth_create_link, ++ ++ // JSON ++ .to_json = nw_port_veth_to_json, ++}; +diff --git a/src/networkd/port-veth.h b/src/networkd/port-veth.h +new file mode 100644 +index 0000000..aa4a03b +--- /dev/null ++++ b/src/networkd/port-veth.h +@@ -0,0 +1,35 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_VETH_H ++#define NETWORKD_PORT_VETH_H ++ ++#include "port.h" ++ ++// Maximum length of the peer name ++#define NW_VETH_PEER_MAX 64 ++ ++struct nw_port_veth { ++ char peer[NW_VETH_PEER_MAX]; ++}; ++ ++extern const nw_port_type_t nw_port_type_veth; ++ ++#endif /* NETWORKD_PORT_VETH_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 7d654e3..fb62520 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -33,6 +33,7 @@ + #include "port.h" + #include "port-bonding.h" + #include "port-dummy.h" ++#include "port-veth.h" + #include "port-vlan.h" + #include "stats-collector.h" + #include "string.h" +@@ -40,6 +41,7 @@ + static const nw_string_table_t nw_port_type_id[] = { + { NW_PORT_BONDING, "bonding" }, + { NW_PORT_DUMMY, "dummy" }, ++ { NW_PORT_VETH, "veth", }, + { NW_PORT_VLAN, "vlan" }, + { -1, NULL }, + }; +@@ -165,6 +167,9 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + p->type = &nw_port_type_dummy; + break; + ++ case NW_PORT_VETH: ++ p->type = &nw_port_type_veth; ++ + case NW_PORT_VLAN: + p->type = &nw_port_type_vlan; + break; +@@ -324,6 +329,7 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + + case NW_PORT_BONDING: + case NW_PORT_DUMMY: ++ case NW_PORT_VETH: + break; + } + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index efa2fdb..5c0a2a1 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -36,6 +36,7 @@ typedef struct nw_port nw_port; + typedef enum nw_port_type_id { + NW_PORT_BONDING, + NW_PORT_DUMMY, ++ NW_PORT_VETH, + NW_PORT_VLAN, + } nw_port_type_id_t; + +@@ -66,6 +67,7 @@ typedef struct nw_port_type { + #include "daemon.h" + #include "json.h" + #include "port-bonding.h" ++#include "port-veth.h" + #include "port-vlan.h" + + #define NW_PORT_TYPE(port) (port->type) +@@ -89,6 +91,9 @@ struct nw_port { + // Bonding Settings + struct nw_port_bonding bonding; + ++ // VETH Settings ++ struct nw_port_veth veth; ++ + // VLAN settings + struct nw_port_vlan vlan; + }; +-- +2.39.2 + diff --git a/network/patches/0289-config-Add-string-buffer-type.patch b/network/patches/0289-config-Add-string-buffer-type.patch new file mode 100644 index 000000000..1bf877080 --- /dev/null +++ b/network/patches/0289-config-Add-string-buffer-type.patch @@ -0,0 +1,264 @@ +From e633147dcf3bc46e0686e106cb013dfccf30b1c6 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 11:19:30 +0000 +Subject: [PATCH 289/304] config: Add string buffer type + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 45 +++++++++++++++++++++++++++--------- + src/networkd/config.h | 49 +++++++++++++++++++++++++++------------- + src/networkd/port-veth.c | 2 +- + src/networkd/port-vlan.c | 3 ++- + 4 files changed, 70 insertions(+), 29 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index 3d444c4..c6281cb 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -43,6 +43,7 @@ struct nw_config_option { + + const char* key; + void* value; ++ size_t length; + + // Callbacks + nw_config_option_read_callback_t read_callback; +@@ -427,7 +428,8 @@ int nw_config_options_read(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->read_callback(config, option->key, option->value, option->data); ++ r = option->read_callback(config, ++ option->key, option->value, option->length, option->data); + if (r < 0) + return r; + } +@@ -440,7 +442,8 @@ int nw_config_options_write(nw_config* config) { + int r; + + STAILQ_FOREACH(option, &config->options, nodes) { +- r = option->write_callback(config, option->key, option->value, option->data); ++ r = option->write_callback(config, ++ option->key, option->value, option->length, option->data); + if (r < 0) + return r; + } +@@ -448,7 +451,8 @@ int nw_config_options_write(nw_config* config) { + return 0; + } + +-int nw_config_option_add(nw_config* config, const char* key, void* value, ++int nw_config_option_add(nw_config* config, ++ const char* key, void* value, const size_t length, + nw_config_option_read_callback_t read_callback, + nw_config_option_write_callback_t write_callback, void* data) { + // Check input +@@ -465,6 +469,7 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + + // Set value + option->value = value; ++ option->length = length; + + // Set callbacks + option->read_callback = read_callback; +@@ -477,7 +482,8 @@ int nw_config_option_add(nw_config* config, const char* key, void* value, + return 0; + } + +-int nw_config_read_int(nw_config* config, const char* key, void* value, void* data) { ++int nw_config_read_int(nw_config* config, ++ const char* key, void* value, const size_t length, void* data) { + // Fetch the value + *(int*)value = nw_config_get_int(config, key, -1); + +@@ -485,13 +491,14 @@ int nw_config_read_int(nw_config* config, const char* key, void* value, void* da + } + + int nw_config_write_int(nw_config* config, +- const char* key, const void* value, void* data) { ++ const char* key, const void* value, const size_t length, void* data) { + return 0; + } + + // String + +-int nw_config_read_string(nw_config* config, const char* key, void* value, void* data) { ++int nw_config_read_string(nw_config* config, ++ const char* key, void* value, const size_t length, void* data) { + // Fetch the value + const char* p = nw_config_get(config, key); + if (p) +@@ -501,13 +508,28 @@ int nw_config_read_string(nw_config* config, const char* key, void* value, void* + } + + int nw_config_write_string(nw_config* config, +- const char* key, const void* value, void* data) { ++ const char* key, const void* value, const size_t length, void* data) { + return nw_config_set(config, key, *(const char**)value); + } + ++// String Buffer ++ ++int nw_config_read_string_buffer(nw_config* config, ++ const char* key, void* value, const size_t length, void* data) { ++ char* string = (char*)value; ++ ++ // Fetch the value ++ const char* p = nw_config_get(config, key); ++ if (p) ++ return __nw_string_set(string, length, p); ++ ++ return 0; ++} ++ + // String Table + +-int nw_config_read_string_table(nw_config* config, const char* key, void* value, void* data) { ++int nw_config_read_string_table(nw_config* config, ++ const char* key, void* value, const size_t length, void* data) { + const char* s = NULL; + int* v = (int*)value; + +@@ -529,7 +551,7 @@ int nw_config_read_string_table(nw_config* config, const char* key, void* value, + } + + int nw_config_write_string_table(nw_config* config, +- const char* key, const void* value, void* data) { ++ const char* key, const void* value, const size_t length, void* data) { + int* v = (int*)value; + + const nw_string_table_t* table = (nw_string_table_t*)data; +@@ -544,7 +566,8 @@ int nw_config_write_string_table(nw_config* config, + + // Address + +-int nw_config_read_address(nw_config* config, const char* key, void* value, void* data) { ++int nw_config_read_address(nw_config* config, ++ const char* key, void* value, const size_t length, void* data) { + nw_address_t* address = (nw_address_t*)value; + int r; + +@@ -561,7 +584,7 @@ int nw_config_read_address(nw_config* config, const char* key, void* value, void + } + + int nw_config_write_address(nw_config* config, +- const char* key, const void* value, void* data) { ++ const char* key, const void* value, const size_t length, void* data) { + const nw_address_t* address = (nw_address_t*)value; + int r; + +diff --git a/src/networkd/config.h b/src/networkd/config.h +index b25d05e..4b8bc01 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -60,47 +60,64 @@ int nw_config_options_read(nw_config* config); + int nw_config_options_write(nw_config* config); + + typedef int (*nw_config_option_read_callback_t) +- (nw_config* config, const char* key, void* value, void* data); ++ (nw_config* config, const char* key, void* value, const size_t length, void* data); + typedef int (*nw_config_option_write_callback_t) +- (nw_config* config, const char* key, const void* value, void* data); ++ (nw_config* config, const char* key, const void* value, const size_t length, void* data); + +-int nw_config_option_add(nw_config* config, const char* key, void* value, ++int nw_config_option_add(nw_config* config, const char* key, void* value, const size_t length, + nw_config_option_read_callback_t read_callback, + nw_config_option_write_callback_t write_callback, void* data); + +-#define NW_CONFIG_OPTION(config, key, value, read_callback, write_callback, data) \ +- nw_config_option_add(config, key, value, read_callback, write_callback, data) ++#define NW_CONFIG_OPTION(config, key, value, length, read_callback, write_callback, data) \ ++ nw_config_option_add(config, key, value, length, read_callback, write_callback, data) + + // String + + #define NW_CONFIG_OPTION_STRING(config, key, value) \ + nw_config_option_add(config, key, value, nw_config_read_string, nw_config_write_string, NULL) + +-int nw_config_read_string(nw_config* config, const char* key, void* value, void* data); +-int nw_config_write_string(nw_config* config, const char* key, const void* value, void* data); ++int nw_config_read_string(nw_config* config, ++ const char* key, void* value, const size_t length, void* data); ++int nw_config_write_string(nw_config* config, ++ const char* key, const void* value, const size_t length, void* data); ++ ++#define NW_CONFIG_OPTION_STRING_BUFFER(config, key, value) \ ++ nw_config_option_add(config, key, value, sizeof(value), \ ++ nw_config_read_string_buffer, nw_config_write_string_buffer, NULL) ++ ++int nw_config_read_string_buffer(nw_config* config, ++ const char* key, void* value, const size_t length, void* data); ++#define nw_config_write_string_buffer nw_config_write_string + + // String Table + + #define NW_CONFIG_OPTION_STRING_TABLE(config, key, value, table) \ +- nw_config_option_add(config, key, value, nw_config_read_string_table, nw_config_write_string_table, (void*)table) ++ nw_config_option_add(config, key, value, 0, \ ++ nw_config_read_string_table, nw_config_write_string_table, (void*)table) + +-int nw_config_read_string_table(nw_config* config, const char* key, void* value, void* data); +-int nw_config_write_string_table(nw_config* config, const char* key, const void* value, void* data); ++int nw_config_read_string_table(nw_config* config, ++ const char* key, void* value, const size_t length, void* data); ++int nw_config_write_string_table(nw_config* config, ++ const char* key, const void* value, const size_t length, void* data); + + // Integer + + #define NW_CONFIG_OPTION_INT(config, key, value) \ +- nw_config_option_add(config, key, value, nw_config_read_int, nw_config_write_int, NULL) ++ nw_config_option_add(config, key, value, 0, nw_config_read_int, nw_config_write_int, NULL) + +-int nw_config_read_int(nw_config* config, const char* key, void* value, void* data); +-int nw_config_write_int(nw_config* config, const char* key, const void* value, void* data); ++int nw_config_read_int(nw_config* config, ++ const char* key, void* value, const size_t length, void* data); ++int nw_config_write_int(nw_config* config, ++ const char* key, const void* value, const size_t length, void* data); + + // Address + + #define NW_CONFIG_OPTION_ADDRESS(config, key, value) \ +- nw_config_option_add(config, key, value, nw_config_read_address, nw_config_write_address, NULL) ++ nw_config_option_add(config, key, value, 0, nw_config_read_address, nw_config_write_address, NULL) + +-int nw_config_read_address(nw_config* config, const char* key, void* value, void* data); +-int nw_config_write_address(nw_config* config, const char* key, const void* value, void* data); ++int nw_config_read_address(nw_config* config, ++ const char* key, void* value, const size_t length, void* data); ++int nw_config_write_address(nw_config* config, ++ const char* key, const void* value, const size_t length, void* data); + + #endif /* NETWORKD_CONFIG_H */ +diff --git a/src/networkd/port-veth.c b/src/networkd/port-veth.c +index 44b1a0d..029ef50 100644 +--- a/src/networkd/port-veth.c ++++ b/src/networkd/port-veth.c +@@ -28,7 +28,7 @@ static int nw_port_veth_setup(nw_port* port) { + int r; + + // Peer +- r = NW_CONFIG_OPTION_STRING(port->config, "VETH_PEER", &port->veth.peer); ++ r = NW_CONFIG_OPTION_STRING_BUFFER(port->config, "VETH_PEER", port->veth.peer); + if (r < 0) + return 1; + +diff --git a/src/networkd/port-vlan.c b/src/networkd/port-vlan.c +index 25a59ee..c759f71 100644 +--- a/src/networkd/port-vlan.c ++++ b/src/networkd/port-vlan.c +@@ -53,7 +53,8 @@ static int nw_port_vlan_setup(nw_port* port) { + return r; + + // Parent Port +- r = NW_CONFIG_OPTION_STRING(port->config, "VLAN_PARENT", &port->vlan.__parent_name); ++ r = NW_CONFIG_OPTION_STRING_BUFFER(port->config, ++ "VLAN_PARENT", port->vlan.__parent_name); + if (r < 0) + return r; + +-- +2.39.2 + diff --git a/network/patches/0290-networkctl-Add-color-functions.patch b/network/patches/0290-networkctl-Add-color-functions.patch new file mode 100644 index 000000000..9dd6aae4f --- /dev/null +++ b/network/patches/0290-networkctl-Add-color-functions.patch @@ -0,0 +1,176 @@ +From aa7cc0927e2ea5cde54685e01290be8c0afdc31c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 12:30:33 +0000 +Subject: [PATCH 290/304] networkctl: Add color functions + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 + + src/networkctl/terminal.c | 51 ++++++++++++++++++++++++ + src/networkctl/terminal.h | 83 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 136 insertions(+) + create mode 100644 src/networkctl/terminal.c + create mode 100644 src/networkctl/terminal.h + +diff --git a/Makefile.am b/Makefile.am +index caab99e..95fff11 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -402,6 +402,8 @@ dist_networkctl_SOURCES = \ + src/networkctl/main.c \ + src/networkctl/port.c \ + src/networkctl/port.h \ ++ src/networkctl/terminal.c \ ++ src/networkctl/terminal.h \ + src/networkctl/zone.c \ + src/networkctl/zone.h + +diff --git a/src/networkctl/terminal.c b/src/networkctl/terminal.c +new file mode 100644 +index 0000000..de7cd8d +--- /dev/null ++++ b/src/networkctl/terminal.c +@@ -0,0 +1,51 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include ++#include ++ ++#include "terminal.h" ++ ++// Cache the color mode ++static color_mode_t __color_mode = COLORS_UNKNOWN; ++ ++static color_mode_t detect_color_mode(void) { ++ const char* s = NULL; ++ ++ // Check for NO_COLOR and if found turn off colours ++ s = secure_getenv("NO_COLOR"); ++ if (s) ++ return COLORS_OFF; ++ ++ // Disable colours if this isn't an interactive terminal ++ if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) ++ return COLORS_OFF; ++ ++ // Otherwise we enable colours ++ return COLORS_ON; ++} ++ ++color_mode_t color_mode() { ++ if (__color_mode == COLORS_UNKNOWN) { ++ __color_mode = detect_color_mode(); ++ } ++ ++ return __color_mode; ++} +diff --git a/src/networkctl/terminal.h b/src/networkctl/terminal.h +new file mode 100644 +index 0000000..b7bffec +--- /dev/null ++++ b/src/networkctl/terminal.h +@@ -0,0 +1,83 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKCTL_TERMINAL_H ++#define NETWORKCTL_TERMINAL_H ++ ++typedef enum color_mode { ++ COLORS_UNKNOWN = 0, ++ COLORS_OFF, ++ COLORS_ON, ++} color_mode_t; ++ ++// Reset ++#define COLOR_RESET "\x1B[0m" ++ ++// Highlight ++#define COLOR_HIGHLIGHT "\x1B[0;1;39m" ++ ++// Regular Colors ++#define COLOR_BLACK "\x1B[0;30m" ++#define COLOR_RED "\x1B[0;31m" ++#define COLOR_GREEN "\x1B[0;32m" ++#define COLOR_YELLOW "\x1B[0;33m" ++#define COLOR_BLUE "\x1B[0;34m" ++#define COLOR_MAGENTA "\x1B[0;35m" ++#define COLOR_CYAN "\x1B[0;36m" ++#define COLOR_WHITE "\x1B[0;37m" ++ ++#define COLOR_BRIGHT_BLACK "\x1B[0;90m" ++#define COLOR_BRIGHT_RED "\x1B[0;91m" ++#define COLOR_BRIGHT_GREEN "\x1B[0;92m" ++#define COLOR_BRIGHT_YELLOW "\x1B[0;93m" ++#define COLOR_BRIGHT_BLUE "\x1B[0;94m" ++#define COLOR_BRIGHT_MAGENTA "\x1B[0;95m" ++#define COLOR_BRIGHT_CYAN "\x1B[0;96m" ++#define COLOR_BRIGHT_WHITE "\x1B[0;97m" ++ ++#define COLOR_HIGHLIGHT_BLACK "\x1B[0;1;30m" ++#define COLOR_HIGHLIGHT_RED "\x1B[0;1;31m" ++#define COLOR_HIGHLIGHT_GREEN "\x1B[0;1;32m" ++#define COLOR_HIGHLIGHT_YELLOW "\x1B[0;1;33m" ++#define COLOR_HIGHLIGHT_BLUE "\x1B[0;1;34m" ++#define COLOR_HIGHLIGHT_MAGENTA "\x1B[0;1;35m" ++#define COLOR_HIGHLIGHT_CYAN "\x1B[0;1;36m" ++#define COLOR_HIGHLIGHT_WHITE "\x1B[0;1;37m" ++ ++// Returns the color mode ++color_mode_t color_mode(void); ++ ++#define COLOR_FUNC(name, color) \ ++ static inline const char* color_##name(void) { \ ++ return (color_mode() == COLORS_ON) ? COLOR_ ## color : ""; \ ++ } ++ ++COLOR_FUNC(reset, RESET) ++COLOR_FUNC(highlight, HIGHLIGHT) ++COLOR_FUNC(black, BLACK) ++COLOR_FUNC(red, RED) ++COLOR_FUNC(green, GREEN) ++COLOR_FUNC(yellow, YELLOW) ++COLOR_FUNC(blue, BLUE) ++COLOR_FUNC(magenta, MAGENTA) ++COLOR_FUNC(cyan, CYAN) ++COLOR_FUNC(white, WHITE) ++ ++#endif /* NETWORKCTL_TERMINAL_H */ +-- +2.39.2 + diff --git a/network/patches/0291-networkctl-Move-describe-into-an-own-function.patch b/network/patches/0291-networkctl-Move-describe-into-an-own-function.patch new file mode 100644 index 000000000..99aa22bd3 --- /dev/null +++ b/network/patches/0291-networkctl-Move-describe-into-an-own-function.patch @@ -0,0 +1,106 @@ +From 8dc40ed861b5ee93f176caf792fc818f681fd9b4 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 12:40:55 +0000 +Subject: [PATCH 291/304] networkctl: Move describe into an own function + +Signed-off-by: Michael Tremer +--- + src/networkctl/port.c | 48 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 36 insertions(+), 12 deletions(-) + +diff --git a/src/networkctl/port.c b/src/networkctl/port.c +index 67bc003..b6a95c5 100644 +--- a/src/networkctl/port.c ++++ b/src/networkctl/port.c +@@ -19,6 +19,7 @@ + #############################################################################*/ + + #include ++#include + + #include + +@@ -80,22 +81,19 @@ ERROR: + return r; + } + +-// Dump +- +-static int networkctl_port_dump(sd_bus* bus, int argc, char* argv[]) { ++static int networkctl_port_describe(sd_bus* bus, const char* name, char** text) { + sd_bus_message* reply = NULL; + sd_bus_error error = SD_BUS_ERROR_NULL; + char path[PATH_MAX]; +- const char* text = NULL; ++ const char* t = NULL; + int r; + +- if (argc < 1) { +- fprintf(stderr, "Port required\n"); ++ // Check input ++ if (!name || !text) + return -EINVAL; +- } + + // Make port path +- r = nw_string_format(path, "/org/ipfire/network1/port/%s", argv[0]); ++ r = nw_string_format(path, "/org/ipfire/network1/port/%s", name); + if (r < 0) + goto ERROR; + +@@ -108,15 +106,16 @@ static int networkctl_port_dump(sd_bus* bus, int argc, char* argv[]) { + } + + // Read the text +- r = sd_bus_message_read(reply, "s", &text); ++ r = sd_bus_message_read(reply, "s", &t); + if (r < 0) { + fprintf(stderr, "Could not parse bus message: %s\n", strerror(-r)); + goto ERROR; + } + +- // Print the text +- if (text) +- printf("%s\n", text); ++ // Copy text to heap ++ *text = strdup(t); ++ if (!*text) ++ r = -errno; + + ERROR: + if (reply) +@@ -125,6 +124,31 @@ ERROR: + return r; + } + ++// Dump ++ ++static int networkctl_port_dump(sd_bus* bus, int argc, char* argv[]) { ++ char* text = NULL; ++ int r; ++ ++ if (argc < 1) { ++ fprintf(stderr, "Port required\n"); ++ return -EINVAL; ++ } ++ ++ // Describe the port ++ r = networkctl_port_describe(bus, argv[0], &text); ++ if (r < 0) ++ return r; ++ ++ // Print the text ++ printf("%s\n", text); ++ ++ if (text) ++ free(text); ++ ++ return 0; ++} ++ + // List + + static int __networkctl_port_list(sd_bus* bus, const char* path, const char* name, void* data) { +-- +2.39.2 + diff --git a/network/patches/0292-networkctl-Implement-scaffolding-to-show-ports.patch b/network/patches/0292-networkctl-Implement-scaffolding-to-show-ports.patch new file mode 100644 index 000000000..df434b0af --- /dev/null +++ b/network/patches/0292-networkctl-Implement-scaffolding-to-show-ports.patch @@ -0,0 +1,145 @@ +From 3363ba36e33d5fc9c455825aeeabf4b615cde3c1 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 14:14:42 +0000 +Subject: [PATCH 292/304] networkctl: Implement scaffolding to show ports + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkctl/port.c | 68 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/json.h | 9 ++++++ + 3 files changed, 79 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 95fff11..2632ca7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -409,12 +409,14 @@ dist_networkctl_SOURCES = \ + + networkctl_CFLAGS = \ + $(AM_CFLAGS) \ ++ $(JSON_C_CFLAGS) \ + $(SYSTEMD_CFLAGS) + + networkctl_LDFLAGS = \ + $(AM_LDFLAGS) + + networkctl_LDADD = \ ++ $(JSON_C_LIBS) \ + $(SYSTEMD_LIBS) + + # ------------------------------------------------------------------------------ +diff --git a/src/networkctl/port.c b/src/networkctl/port.c +index b6a95c5..439177d 100644 +--- a/src/networkctl/port.c ++++ b/src/networkctl/port.c +@@ -23,9 +23,11 @@ + + #include + ++#include "../networkd/json.h" + #include "../networkd/string.h" + #include "command.h" + #include "port.h" ++#include "terminal.h" + + typedef int (*networkctl_port_walk_callback) + (sd_bus* bus, const char* path, const char* name, void* data); +@@ -161,10 +163,76 @@ static int networkctl_port_list(sd_bus* bus, int argc, char* argv[]) { + return networkctl_port_walk(bus, __networkctl_port_list, NULL); + } + ++// Show ++ ++#define SHOW_LINE " %-12s : %s\n" ++ ++static int __networkctl_port_show(sd_bus* bus, const char* path, const char* name, void* data) { ++ struct json_object* object = NULL; ++ enum json_tokener_error json_error; ++ char* describe = NULL; ++ int r; ++ ++ // Describe this port ++ r = networkctl_port_describe(bus, name, &describe); ++ if (r < 0) ++ goto ERROR; ++ ++ // Parse JSON ++ object = json_tokener_parse_verbose(describe, &json_error); ++ if (!object) { ++ fprintf(stderr, "Could not parse port %s: %s\n", ++ name, json_tokener_error_desc(json_error)); ++ return -EINVAL; ++ } ++ ++ // Show headline ++ printf("Port %s%s%s\n", color_highlight(), name, color_reset()); ++ ++ // Show type ++ const char* type = json_object_fetch_string(object, "Type"); ++ if (type) ++ printf(SHOW_LINE, "Type", type); ++ ++ // Show address ++ const char* address = json_object_fetch_string(object, "Address"); ++ if (address) ++ printf(SHOW_LINE, "Address", address); ++ ++ // Show an empty line at the end ++ printf("\n"); ++ ++ // Success! ++ r = 0; ++ ++ERROR: ++ if (describe) ++ free(describe); ++ if (object) ++ json_object_unref(object); ++ ++ return r; ++} ++ ++static int networkctl_port_show(sd_bus* bus, int argc, char* argv[]) { ++ switch (argc) { ++ case 0: ++ return networkctl_port_walk(bus, __networkctl_port_show, NULL); ++ ++ case 1: ++ return __networkctl_port_show(bus, NULL, argv[0], NULL); ++ ++ default: ++ fprintf(stderr, "Too many arguments\n"); ++ return 1; ++ } ++} ++ + int networkctl_port(sd_bus* bus, int argc, char* argv[]) { + static const struct command commands[] = { + { "dump", 0, networkctl_port_dump }, + { "list", 0, networkctl_port_list }, ++ { "show", 0, networkctl_port_show }, + { NULL }, + }; + +diff --git a/src/networkd/json.h b/src/networkd/json.h +index 19ced9a..6c2f66f 100644 +--- a/src/networkd/json.h ++++ b/src/networkd/json.h +@@ -87,4 +87,13 @@ static inline int json_to_string(struct json_object* o, char** s, size_t* l) { + return 0; + } + ++static inline const char* json_object_fetch_string( ++ struct json_object* o, const char* key) { ++ struct json_object* e = json_object_object_get(o, key); ++ if (!e) ++ return NULL; ++ ++ return json_object_get_string(e); ++} ++ + #endif /* NETWORKD_JSON_H */ +-- +2.39.2 + diff --git a/network/patches/0293-ports-Add-link-stuff-to-JSON-output.patch b/network/patches/0293-ports-Add-link-stuff-to-JSON-output.patch new file mode 100644 index 000000000..6b3a79ef0 --- /dev/null +++ b/network/patches/0293-ports-Add-link-stuff-to-JSON-output.patch @@ -0,0 +1,82 @@ +From 69467266f8b3d8a925604b3ffdeda060c5d409cd Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 14:19:04 +0000 +Subject: [PATCH 293/304] ports: Add link stuff to JSON output + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 14 ++++++++++++++ + src/networkd/link.h | 4 ++++ + src/networkd/port.c | 7 +++++++ + 3 files changed, 25 insertions(+) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 603aabe..60abd46 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -27,6 +27,7 @@ + #include + + #include "daemon.h" ++#include "json.h" + #include "link.h" + #include "links.h" + #include "logging.h" +@@ -529,3 +530,16 @@ ERROR: + + return r; + } ++ ++// JSON ++ ++int nw_link_to_json(nw_link* link, struct json_object* o) { ++ int r; ++ ++ // Add ifindex ++ r = json_object_add_int64(o, "LinkIndex", link->ifindex); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 2bab47c..36c7d9d 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -26,6 +26,7 @@ + typedef struct nw_link nw_link; + + #include "daemon.h" ++#include "json.h" + + int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex); + +@@ -45,4 +46,7 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + + int nw_link_destroy(nw_link* link); + ++// JSON ++int nw_link_to_json(nw_link* link, struct json_object* o); ++ + #endif /* NETWORKD_LINK_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index fb62520..84fceee 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -682,6 +682,13 @@ int nw_port_to_json(nw_port* port, struct json_object** object) { + goto ERROR; + } + ++ // Add link stuff ++ if (port->link) { ++ r = nw_link_to_json(port->link, o); ++ if (r < 0) ++ goto ERROR; ++ } ++ + // Call custom stuff + if (NW_PORT_TYPE(port)->to_json) { + r = NW_PORT_TYPE(port)->to_json(port, o); +-- +2.39.2 + diff --git a/network/patches/0294-link-Add-device-stuff-to-JSON-output.patch b/network/patches/0294-link-Add-device-stuff-to-JSON-output.patch new file mode 100644 index 000000000..95e39543b --- /dev/null +++ b/network/patches/0294-link-Add-device-stuff-to-JSON-output.patch @@ -0,0 +1,185 @@ +From cf75e1dbc997b8a785e5f4d75e6a3d0efd594cf5 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 14:44:06 +0000 +Subject: [PATCH 294/304] link: Add device stuff to JSON output + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 113 ++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 105 insertions(+), 8 deletions(-) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 60abd46..23918cb 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -24,6 +24,7 @@ + #include + #include + ++#include + #include + + #include "daemon.h" +@@ -48,6 +49,9 @@ struct nw_link { + NW_LINK_DESTROYED, + } state; + ++ // Device ++ struct sd_device* device; ++ + // Stats + struct rtnl_link_stats64 stats64; + +@@ -61,11 +65,35 @@ struct nw_link { + uint8_t operstate; + }; + ++static int nw_link_setup_device(nw_link* link) { ++ int r; ++ ++ // Fetch sd-device ++ r = sd_device_new_from_ifindex(&link->device, link->ifindex); ++ if (r < 0) { ++ ERROR("Could not fetch sd-device for link %d: %s\n", link->ifindex, strerror(-r)); ++ return r; ++ } ++ ++ return 0; ++} ++ ++static void nw_link_free(nw_link* link) { ++ DEBUG("Freeing link (ifindex = %d)\n", link->ifindex); ++ ++ if (link->device) ++ sd_device_unref(link->device); ++ if (link->daemon) ++ nw_daemon_unref(link->daemon); ++} ++ + int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex) { ++ int r; ++ + // Allocate a new object + nw_link* l = calloc(1, sizeof(*l)); + if (!l) +- return 1; ++ return -errno; + + // Store a reference to the daemon + l->daemon = nw_daemon_ref(daemon); +@@ -78,16 +106,16 @@ int nw_link_create(nw_link** link, nw_daemon* daemon, int ifindex) { + + DEBUG("New link allocated (ifindex = %d)\n", l->ifindex); + +- *link = l; ++ r = nw_link_setup_device(l); ++ if (r < 0) ++ goto ERROR; + ++ *link = l; + return 0; +-} +- +-static void nw_link_free(nw_link* link) { +- DEBUG("Freeing link (ifindex = %d)\n", link->ifindex); + +- if (link->daemon) +- nw_daemon_unref(link->daemon); ++ERROR: ++ nw_link_free(l); ++ return r; + } + + nw_link* nw_link_ref(nw_link* link) { +@@ -126,6 +154,19 @@ const char* nw_link_ifname(nw_link* link) { + return link->ifname; + } + ++static int nw_link_get_sd_device(nw_link* link, struct sd_device** device) { ++ int r; ++ ++ // Fetch sd-device ++ r = sd_device_new_from_ifindex(device, link->ifindex); ++ if (r < 0) { ++ ERROR("Could not fetch sd-device for link %d: %s\n", link->ifindex, strerror(-r)); ++ return r; ++ } ++ ++ return 0; ++} ++ + // Stats + + const struct rtnl_link_stats64* nw_link_get_stats64(nw_link* link) { +@@ -533,6 +574,57 @@ ERROR: + + // JSON + ++static int nw_link_device_to_json(nw_link* link, struct json_object* o) { ++ const char* driver = NULL; ++ const char* vendor = NULL; ++ const char* model = NULL; ++ int r; ++ ++ // Fetch driver ++ r = sd_device_get_driver(link->device, &driver); ++ if (r < 0 && r != -ENOENT) ++ return r; ++ ++ // Add driver ++ if (driver) { ++ r = json_object_add_string(o, "Driver", driver); ++ if (r < 0) ++ return r; ++ } ++ ++ // Fetch vendor ++ r = sd_device_get_property_value(link->device, "ID_VENDOR_FROM_DATABASE", &vendor); ++ if (r < 0) { ++ r = sd_device_get_property_value(link->device, "ID_VENDOR", &vendor); ++ if (r < 0 && r != -ENOENT) ++ return r; ++ } ++ ++ // Add vendor ++ if (vendor) { ++ r = json_object_add_string(o, "Vendor", vendor); ++ if (r < 0) ++ return r; ++ } ++ ++ // Fetch model ++ r = sd_device_get_property_value(link->device, "ID_MODEL_FROM_DATABASE", &model); ++ if (r < 0) { ++ r = sd_device_get_property_value(link->device, "ID_MODEL", &model); ++ if (r < 0 && r != -ENOENT) ++ return r; ++ } ++ ++ // Add model ++ if (model) { ++ r = json_object_add_string(o, "Model", model); ++ if (r < 0) ++ return r; ++ } ++ ++ return 0; ++} ++ + int nw_link_to_json(nw_link* link, struct json_object* o) { + int r; + +@@ -541,5 +633,10 @@ int nw_link_to_json(nw_link* link, struct json_object* o) { + if (r < 0) + return r; + ++ // Add sd-device stuff ++ r = nw_link_device_to_json(link, o); ++ if (r < 0) ++ return r; ++ + return 0; + } +-- +2.39.2 + diff --git a/network/patches/0295-ports-Add-scaffolding-for-physical-Ethernet-interfac.patch b/network/patches/0295-ports-Add-scaffolding-for-physical-Ethernet-interfac.patch new file mode 100644 index 000000000..ec87e49e8 --- /dev/null +++ b/network/patches/0295-ports-Add-scaffolding-for-physical-Ethernet-interfac.patch @@ -0,0 +1,246 @@ +From f4f98a384fd5cb95b04be989ec488b2ecfc1960f Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Fri, 9 Jun 2023 14:59:54 +0000 +Subject: [PATCH 295/304] ports: Add scaffolding for physical Ethernet + interfaces + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 ++ + src/networkd/link.c | 13 -------- + src/networkd/port-ethernet.c | 63 ++++++++++++++++++++++++++++++++++++ + src/networkd/port-ethernet.h | 34 +++++++++++++++++++ + src/networkd/port.c | 16 ++++++--- + src/networkd/port.h | 5 +++ + 6 files changed, 116 insertions(+), 17 deletions(-) + create mode 100644 src/networkd/port-ethernet.c + create mode 100644 src/networkd/port-ethernet.h + +diff --git a/Makefile.am b/Makefile.am +index 2632ca7..8c0d0c0 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -338,6 +338,8 @@ dist_networkd_SOURCES = \ + src/networkd/port-bus.h \ + src/networkd/port-dummy.c \ + src/networkd/port-dummy.h \ ++ src/networkd/port-ethernet.c \ ++ src/networkd/port-ethernet.h \ + src/networkd/port-veth.c \ + src/networkd/port-veth.h \ + src/networkd/port-vlan.c \ +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 23918cb..f172208 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -154,19 +154,6 @@ const char* nw_link_ifname(nw_link* link) { + return link->ifname; + } + +-static int nw_link_get_sd_device(nw_link* link, struct sd_device** device) { +- int r; +- +- // Fetch sd-device +- r = sd_device_new_from_ifindex(device, link->ifindex); +- if (r < 0) { +- ERROR("Could not fetch sd-device for link %d: %s\n", link->ifindex, strerror(-r)); +- return r; +- } +- +- return 0; +-} +- + // Stats + + const struct rtnl_link_stats64* nw_link_get_stats64(nw_link* link) { +diff --git a/src/networkd/port-ethernet.c b/src/networkd/port-ethernet.c +new file mode 100644 +index 0000000..a48b45e +--- /dev/null ++++ b/src/networkd/port-ethernet.c +@@ -0,0 +1,63 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#include "config.h" ++#include "json.h" ++#include "port.h" ++#include "port-ethernet.h" ++ ++static int nw_port_ethernet_setup(nw_port* port) { ++ int r; ++ ++ // Permanent Address ++ r = NW_CONFIG_OPTION_ADDRESS(port->config, ++ "PERMANENT_ADDRESS", &port->ethernet.permanent_address); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ ++static int nw_port_ethernet_to_json(nw_port* port, struct json_object* o) { ++ char* address = NULL; ++ int r = 0; ++ ++ // Permanent Address ++ address = nw_address_to_string(&port->ethernet.permanent_address); ++ if (address) { ++ r = json_object_add_string(o, "PermanentAddress", address); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ERROR: ++ if (address) ++ free(address); ++ ++ return r; ++} ++ ++const nw_port_type_t nw_port_type_ethernet = { ++ // Configuration ++ .setup = nw_port_ethernet_setup, ++ ++ // JSON ++ .to_json = nw_port_ethernet_to_json, ++}; +diff --git a/src/networkd/port-ethernet.h b/src/networkd/port-ethernet.h +new file mode 100644 +index 0000000..50dade2 +--- /dev/null ++++ b/src/networkd/port-ethernet.h +@@ -0,0 +1,34 @@ ++/*############################################################################# ++# # ++# IPFire.org - A linux based firewall # ++# Copyright (C) 2023 IPFire Network Development Team # ++# # ++# This program is free software: you can redistribute it and/or modify # ++# it under the terms of the GNU General Public License as published by # ++# the Free Software Foundation, either version 3 of the License, or # ++# (at your option) any later version. # ++# # ++# This program 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 General Public License for more details. # ++# # ++# You should have received a copy of the GNU General Public License # ++# along with this program. If not, see . # ++# # ++#############################################################################*/ ++ ++#ifndef NETWORKD_PORT_ETHERNET_H ++#define NETWORKD_PORT_ETHERNET_H ++ ++#include "address.h" ++#include "port.h" ++ ++struct nw_port_ethernet { ++ // Permanent Address ++ nw_address_t permanent_address; ++}; ++ ++extern const nw_port_type_t nw_port_type_ethernet; ++ ++#endif /* NETWORKD_PORT_ETHERNET_H */ +diff --git a/src/networkd/port.c b/src/networkd/port.c +index 84fceee..f547956 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -33,16 +33,18 @@ + #include "port.h" + #include "port-bonding.h" + #include "port-dummy.h" ++#include "port-ethernet.h" + #include "port-veth.h" + #include "port-vlan.h" + #include "stats-collector.h" + #include "string.h" + + static const nw_string_table_t nw_port_type_id[] = { +- { NW_PORT_BONDING, "bonding" }, +- { NW_PORT_DUMMY, "dummy" }, +- { NW_PORT_VETH, "veth", }, +- { NW_PORT_VLAN, "vlan" }, ++ { NW_PORT_BONDING, "bonding" }, ++ { NW_PORT_DUMMY, "dummy" }, ++ { NW_PORT_ETHERNET, "ethernet" }, ++ { NW_PORT_VETH, "veth", }, ++ { NW_PORT_VLAN, "vlan" }, + { -1, NULL }, + }; + +@@ -167,8 +169,13 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, + p->type = &nw_port_type_dummy; + break; + ++ case NW_PORT_ETHERNET: ++ p->type = &nw_port_type_ethernet; ++ break; ++ + case NW_PORT_VETH: + p->type = &nw_port_type_veth; ++ break; + + case NW_PORT_VLAN: + p->type = &nw_port_type_vlan; +@@ -329,6 +336,7 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + + case NW_PORT_BONDING: + case NW_PORT_DUMMY: ++ case NW_PORT_ETHERNET: + case NW_PORT_VETH: + break; + } +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 5c0a2a1..f1cb3d2 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -36,6 +36,7 @@ typedef struct nw_port nw_port; + typedef enum nw_port_type_id { + NW_PORT_BONDING, + NW_PORT_DUMMY, ++ NW_PORT_ETHERNET, + NW_PORT_VETH, + NW_PORT_VLAN, + } nw_port_type_id_t; +@@ -67,6 +68,7 @@ typedef struct nw_port_type { + #include "daemon.h" + #include "json.h" + #include "port-bonding.h" ++#include "port-ethernet.h" + #include "port-veth.h" + #include "port-vlan.h" + +@@ -91,6 +93,9 @@ struct nw_port { + // Bonding Settings + struct nw_port_bonding bonding; + ++ // Ethernet Settings ++ struct nw_port_ethernet ethernet; ++ + // VETH Settings + struct nw_port_veth veth; + +-- +2.39.2 + diff --git a/network/patches/0296-logging-Add-WARNING-log-level.patch b/network/patches/0296-logging-Add-WARNING-log-level.patch new file mode 100644 index 000000000..8e81e26ba --- /dev/null +++ b/network/patches/0296-logging-Add-WARNING-log-level.patch @@ -0,0 +1,25 @@ +From 008488e0f95c140f7df74cadd238db16321a7737 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 10 Jun 2023 11:22:46 +0000 +Subject: [PATCH 296/304] logging: Add WARNING log level + +Signed-off-by: Michael Tremer +--- + src/networkd/logging.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/networkd/logging.h b/src/networkd/logging.h +index ea75ba0..e835064 100644 +--- a/src/networkd/logging.h ++++ b/src/networkd/logging.h +@@ -30,6 +30,7 @@ void nw_log(int priority, const char *file, int line, const char* fn, + This is just something simple which will work for now... + */ + #define INFO(args...) nw_log(LOG_INFO, __FILE__, __LINE__, __FUNCTION__, ## args) ++#define WARNING(args...) nw_log(LOG_WARNING, __FILE__, __LINE__, __FUNCTION__, ## args) + #define ERROR(args...) nw_log(LOG_ERR, __FILE__, __LINE__, __FUNCTION__, ## args) + #define DEBUG(args...) nw_log(LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, ## args) + +-- +2.39.2 + diff --git a/network/patches/0297-networkd-Handle-any-uevents-for-links.patch b/network/patches/0297-networkd-Handle-any-uevents-for-links.patch new file mode 100644 index 000000000..89c6dcce5 --- /dev/null +++ b/network/patches/0297-networkd-Handle-any-uevents-for-links.patch @@ -0,0 +1,148 @@ +From 40e2c8ca02fae3d175e8d49498a3b3b443b1c6ef Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 10 Jun 2023 11:29:22 +0000 +Subject: [PATCH 297/304] networkd: Handle any uevents for links + +Signed-off-by: Michael Tremer +--- + src/networkd/devmon.c | 67 +++++++++++++++++++++++++++++++++++++++++++ + src/networkd/link.c | 19 ++++++++++++ + src/networkd/link.h | 5 ++++ + 3 files changed, 91 insertions(+) + +diff --git a/src/networkd/devmon.c b/src/networkd/devmon.c +index 0a8c26d..c751985 100644 +--- a/src/networkd/devmon.c ++++ b/src/networkd/devmon.c +@@ -20,8 +20,75 @@ + + #include + ++#include "daemon.h" + #include "devmon.h" ++#include "logging.h" ++ ++static int nw_daemon_handle_uevent_net(nw_daemon* daemon, ++ sd_device* device, sd_device_action_t action) { ++ nw_link* link = NULL; ++ int ifindex; ++ int r; ++ ++ // Fetch ifindex ++ r = sd_device_get_ifindex(device, &ifindex); ++ if (r < 0) { ++ ERROR("Could not get ifindex from uevent: %s\n", strerror(-r)); ++ goto ERROR; ++ } ++ ++ // Fetch the link ++ link = nw_daemon_get_link_by_ifindex(daemon, ifindex); ++ if (!link) { ++ DEBUG("Could not fetch link %d, ignoring\n", ifindex); ++ r = 0; ++ goto ERROR; ++ } ++ ++ // Let the link handle its uevent ++ r = nw_link_handle_uevent(link, device, action); ++ ++ERROR: ++ if (link) ++ nw_link_unref(link); ++ ++ return r; ++} + + int nw_devmon_handle_uevent(sd_device_monitor* monitor, sd_device* device, void* data) { ++ sd_device_action_t action; ++ const char* subsystem = NULL; ++ int r; ++ ++ // Fetch daemon ++ nw_daemon* daemon = (nw_daemon*)data; ++ ++ // Fetch action ++ r = sd_device_get_action(device, &action); ++ if (r < 0) { ++ WARNING("Could not get uevent action, ignoring: %s\n", strerror(-r)); ++ return r; ++ } ++ ++ // Fetch subsystem ++ r = sd_device_get_subsystem(device, &subsystem); ++ if (r < 0) { ++ ERROR("Could not get uevent subsystem, ignoring: %s\n", strerror(-r)); ++ return r; ++ } ++ ++ // Handle any links ++ if (strcmp(subsystem, "net") == 0) { ++ r = nw_daemon_handle_uevent_net(daemon, device, action); ++ ++ } else { ++ DEBUG("Received an uevent for an unhandled subsystem '%s', ignoring\n", subsystem); ++ return 0; ++ } ++ ++ // Log if something went wrong ++ if (r < 0) ++ ERROR("Failed processing uevent: %s\n", strerror(-r)); ++ + return 0; + } +diff --git a/src/networkd/link.c b/src/networkd/link.c +index f172208..b0d9e86 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -559,6 +559,25 @@ ERROR: + return r; + } + ++// uevent ++ ++int nw_link_handle_uevent(nw_link* link, sd_device* device, sd_device_action_t action) { ++ // We need to remove or replace the stored device as it is now outdated ++ if (link->device) { ++ sd_device_unref(link->device); ++ ++ // If the device has been removed, we remove its reference ++ if (action == SD_DEVICE_REMOVE) ++ link->device = NULL; ++ ++ // Otherwise we just store the new one ++ else ++ link->device = sd_device_ref(device); ++ } ++ ++ return 0; ++} ++ + // JSON + + static int nw_link_device_to_json(nw_link* link, struct json_object* o) { +diff --git a/src/networkd/link.h b/src/networkd/link.h +index 36c7d9d..c2f7b7e 100644 +--- a/src/networkd/link.h ++++ b/src/networkd/link.h +@@ -23,6 +23,8 @@ + + #include + ++#include ++ + typedef struct nw_link nw_link; + + #include "daemon.h" +@@ -46,6 +48,9 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data); + + int nw_link_destroy(nw_link* link); + ++// uevent ++int nw_link_handle_uevent(nw_link* link, sd_device* device, sd_device_action_t action); ++ + // JSON + int nw_link_to_json(nw_link* link, struct json_object* o); + +-- +2.39.2 + diff --git a/network/patches/0298-links-Initialize-udev-device-when-links-are-created.patch b/network/patches/0298-links-Initialize-udev-device-when-links-are-created.patch new file mode 100644 index 000000000..997073bf7 --- /dev/null +++ b/network/patches/0298-links-Initialize-udev-device-when-links-are-created.patch @@ -0,0 +1,83 @@ +From 4d7437ddbcb56da5d64ae9189bdb2c8c161e4a9b Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sat, 10 Jun 2023 12:04:18 +0000 +Subject: [PATCH 298/304] links: Initialize udev device when links are created + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index b0d9e86..8ba5da5 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -245,6 +245,53 @@ static int nw_link_carrier_lost(nw_link* link) { + return 0; // XXX TODO + } + ++static int nw_link_initialize(nw_link* link) { ++ sd_device *device = NULL; ++ int r; ++ ++ // Fetch device ++ r = sd_device_new_from_ifindex(&device, link->ifindex); ++ if (r < 0) { ++ WARNING("Could not find device for link %d: %s\n", link->ifindex, strerror(-r)); ++ r = 0; ++ goto ERROR; ++ } ++ ++ // Check if device is initialized ++ r = sd_device_get_is_initialized(device); ++ switch (r) { ++ // Initialized - fallthrough ++ case 0: ++ break; ++ ++ case 1: ++ DEBUG("The device has not been initialized, yet\n"); ++ r = 0; ++ goto ERROR; ++ ++ default: ++ WARNING("Could not check whether device is initialized, ignoring: %s\n", ++ strerror(-r)); ++ goto ERROR; ++ } ++ ++ // XXX Check renaming?! ++ ++ if (link->device) ++ sd_device_unref(link->device); ++ ++ // Store the device ++ link->device = sd_device_ref(device); ++ ++ DEBUG("Link %d has been initialized\n", link->ifindex); ++ ++ERROR: ++ if (device) ++ sd_device_unref(device); ++ ++ return r; ++} ++ + static int nw_link_update_ifname(nw_link* link, sd_netlink_message* message) { + const char* ifname = NULL; + int r; +@@ -476,6 +523,11 @@ int nw_link_process(sd_netlink* rtnl, sd_netlink_message* message, void* data) { + goto ERROR; + } + ++ // Initialize the link ++ r = nw_link_initialize(link); ++ if (r < 0) ++ goto ERROR; ++ + // Add it to the list + r = nw_links_add_link(links, link); + if (r) +-- +2.39.2 + diff --git a/network/patches/0299-link-Skip-uevent-when-the-device-is-renaming.patch b/network/patches/0299-link-Skip-uevent-when-the-device-is-renaming.patch new file mode 100644 index 000000000..8870dd155 --- /dev/null +++ b/network/patches/0299-link-Skip-uevent-when-the-device-is-renaming.patch @@ -0,0 +1,60 @@ +From 7d01b16d6ae3502e48bf99b572be627a2d8a2eac Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 11 Jun 2023 11:07:25 +0000 +Subject: [PATCH 299/304] link: Skip uevent when the device is renaming + +Signed-off-by: Michael Tremer +--- + src/networkd/link.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/src/networkd/link.c b/src/networkd/link.c +index 8ba5da5..cb79dd2 100644 +--- a/src/networkd/link.c ++++ b/src/networkd/link.c +@@ -613,7 +613,42 @@ ERROR: + + // uevent + ++static int nw_link_uevent_device_is_renaming(sd_device* device) { ++ int r; ++ ++ r = sd_device_get_property_value(device, "ID_RENAMING", NULL); ++ switch (r) { ++ case -ENOENT: ++ return 0; ++ ++ case 0: ++ return 1; ++ ++ default: ++ return r; ++ } ++} ++ + int nw_link_handle_uevent(nw_link* link, sd_device* device, sd_device_action_t action) { ++ int r; ++ ++ // Check if the device is renaming ++ r = nw_link_uevent_device_is_renaming(device); ++ switch (r) { ++ // Not renaming - Fallthrough ++ case 0: ++ break; ++ ++ case 1: ++ DEBUG("Device is renaming, skipping initialization\n"); ++ return 0; ++ ++ default: ++ ERROR("Could not determine whether the device is being renamed: %s\n", ++ strerror(-r)); ++ return r; ++ } ++ + // We need to remove or replace the stored device as it is now outdated + if (link->device) { + sd_device_unref(link->device); +-- +2.39.2 + diff --git a/network/patches/0300-networkd-Implement-smarter-handling-of-the-configura.patch b/network/patches/0300-networkd-Implement-smarter-handling-of-the-configura.patch new file mode 100644 index 000000000..dfc0ac3a0 --- /dev/null +++ b/network/patches/0300-networkd-Implement-smarter-handling-of-the-configura.patch @@ -0,0 +1,951 @@ +From 25808f650e39dbcdf3e2d0ba42d079a9d5e43079 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 11 Jun 2023 13:02:35 +0000 +Subject: [PATCH 300/304] networkd: Implement smarter handling of the + configuration file hierarchy + +Signed-off-by: Michael Tremer +--- + src/networkd/config.c | 207 +++++++++++++++++++++++++++++++++++++++++- + src/networkd/config.h | 22 +++++ + src/networkd/daemon.c | 72 +++++---------- + src/networkd/daemon.h | 7 +- + src/networkd/port.c | 66 +++++++------- + src/networkd/port.h | 2 +- + src/networkd/ports.c | 50 +++------- + src/networkd/zone.c | 112 +++++++++++++---------- + src/networkd/zone.h | 9 +- + src/networkd/zones.c | 37 ++++---- + 10 files changed, 386 insertions(+), 198 deletions(-) + +diff --git a/src/networkd/config.c b/src/networkd/config.c +index c6281cb..53fd8e3 100644 +--- a/src/networkd/config.c ++++ b/src/networkd/config.c +@@ -18,12 +18,16 @@ + # # + #############################################################################*/ + ++#include + #include ++#include + #include + #include + #include + #include + #include ++#include ++#include + #include + + #include "address.h" +@@ -161,7 +165,6 @@ int nw_config_open(nw_config** config, const char* path) { + // Create a new configuration + r = nw_config_create(config, f); + +-ERROR: + if (f) + fclose(f); + +@@ -419,6 +422,208 @@ int nw_config_set_bool(nw_config* config, const char* key, const int value) { + return nw_config_set(config, key, value ? "true" : "false"); + } + ++/* ++ Directory ++*/ ++ ++struct nw_configd { ++ int nrefs; ++ ++ char path[PATH_MAX]; ++ int fd; ++}; ++ ++static void nw_configd_free(nw_configd* dir) { ++ if (dir->fd >= 0) ++ close(dir->fd); ++ ++ free(dir); ++} ++ ++static int __nw_configd_create(nw_configd** dir, int fd, const char* path) { ++ nw_configd* d = NULL; ++ int r; ++ ++ // Allocate a new object ++ d = calloc(1, sizeof(*d)); ++ if (!d) ++ return -errno; ++ ++ // Initialize the reference counter ++ d->nrefs = 1; ++ ++ // Store the file descriptor ++ d->fd = dup(fd); ++ if (d->fd < 0) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Store path ++ if (path) { ++ r = nw_string_set(d->path, path); ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ *dir = d; ++ return 0; ++ ++ERROR: ++ nw_configd_free(d); ++ return r; ++} ++ ++int nw_configd_create(nw_configd** dir, const char* path) { ++ int fd; ++ ++ // Open the directory ++ fd = open(path, O_DIRECTORY); ++ if (fd < 0) { ++ ERROR("Could not open %s: %m\n", path); ++ return -errno; ++ } ++ ++ return __nw_configd_create(dir, fd, path); ++} ++ ++nw_configd* nw_configd_ref(nw_configd* dir) { ++ dir->nrefs++; ++ ++ return dir; ++} ++ ++nw_configd* nw_configd_unref(nw_configd* dir) { ++ if (--dir->nrefs > 0) ++ return dir; ++ ++ nw_configd_free(dir); ++ return NULL; ++} ++ ++static int nw_configd_open(nw_configd* dir, const char* path, int flags) { ++ return openat(dir->fd, path, flags); ++} ++ ++FILE* nw_configd_fopen(nw_configd* dir, const char* path, const char* mode) { ++ int fd; ++ ++ // Open file ++ fd = nw_configd_open(dir, path, 0); ++ if (fd < 0) ++ return NULL; ++ ++ // Return a file handle ++ return fdopen(fd, mode); ++} ++ ++int nw_configd_open_config(nw_config** config, nw_configd* dir, const char* path) { ++ FILE* f = NULL; ++ int r; ++ ++ // Open the file ++ f = nw_configd_fopen(dir, path, "r"); ++ if (!f) ++ return -errno; ++ ++ // Create configuration ++ r = nw_config_create(config, f); ++ if (r < 0) ++ goto ERROR; ++ ++ERROR: ++ if (f) ++ fclose(f); ++ ++ return r; ++} ++ ++int nw_configd_unlink(nw_configd* dir, const char* path, int flags) { ++ return unlinkat(dir->fd, path, flags); ++} ++ ++nw_configd* nw_configd_descend(nw_configd* dir, const char* path) { ++ nw_configd* d = NULL; ++ char p[PATH_MAX]; ++ int fd = -1; ++ int r; ++ ++ // Join paths ++ r = nw_path_join(p, dir->path, path); ++ if (r < 0) ++ goto ERROR; ++ ++ // Open directory ++ fd = nw_configd_open(dir, path, O_DIRECTORY); ++ if (fd < 0) { ++ ERROR("Could not open %s: %m\n", p); ++ goto ERROR; ++ } ++ ++ // Create a new config directory object ++ r = __nw_configd_create(&d, fd, p); ++ if (r < 0) ++ goto ERROR; ++ ++ERROR: ++ if (fd >= 0) ++ close(fd); ++ ++ return d; ++} ++ ++int nw_configd_walk(nw_configd* dir, nw_configd_walk_callback callback, void* data) { ++ FILE* f = NULL; ++ DIR* d = NULL; ++ struct dirent* e = NULL; ++ int r; ++ ++ // Re-open the directory ++ d = fdopendir(dir->fd); ++ if (!d) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Walk trough everything ++ for (;;) { ++ // Read the next entry ++ e = readdir(d); ++ if (!e) ++ break; ++ ++ // Skip anything that is not a regular file ++ if (e->d_type != DT_REG) ++ continue; ++ ++ // Skip hidden files ++ if (e->d_name[0] == '.') ++ continue; ++ ++ // Open the file ++ f = nw_configd_fopen(dir, e->d_name, "r"); ++ if (!f) { ++ r = -errno; ++ goto ERROR; ++ } ++ ++ // Call the callback ++ r = callback(e, f, data); ++ fclose(f); ++ ++ if (r < 0) ++ goto ERROR; ++ } ++ ++ r = 0; ++ ++ERROR: ++ if (d) ++ closedir(d); ++ ++ return r; ++} ++ + /* + Options + */ +diff --git a/src/networkd/config.h b/src/networkd/config.h +index 4b8bc01..3e7c097 100644 +--- a/src/networkd/config.h ++++ b/src/networkd/config.h +@@ -21,6 +21,7 @@ + #ifndef NETWORKD_CONFIG_H + #define NETWORKD_CONFIG_H + ++#include + #include + + #define NETWORK_CONFIG_KEY_MAX_LENGTH 128 +@@ -52,6 +53,27 @@ int nw_config_set_int(nw_config* config, const char* key, const int value); + int nw_config_get_bool(nw_config* config, const char* key); + int nw_config_set_bool(nw_config* config, const char* key, const int value); + ++/* ++ Directory ++*/ ++ ++typedef struct nw_configd nw_configd; ++ ++int nw_configd_create(nw_configd** dir, const char* path); ++ ++nw_configd* nw_configd_ref(nw_configd* dir); ++nw_configd* nw_configd_unref(nw_configd* dir); ++ ++FILE* nw_configd_fopen(nw_configd* dir, const char* path, const char* mode); ++int nw_configd_open_config(nw_config** config, nw_configd* dir, const char* path); ++int nw_configd_unlink(nw_configd* dir, const char* path, int flags); ++ ++nw_configd* nw_configd_descend(nw_configd* dir, const char* path); ++ ++typedef int (*nw_configd_walk_callback)(struct dirent* entry, FILE* f, void* data); ++ ++int nw_configd_walk(nw_configd* dir, nw_configd_walk_callback callback, void* data); ++ + /* + Options + */ +diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c +index a62e343..dfbcc15 100644 +--- a/src/networkd/daemon.c ++++ b/src/networkd/daemon.c +@@ -51,7 +51,7 @@ struct nw_daemon { + int nrefs; + + // Configuration +- int configfd; ++ nw_configd* configd; + nw_config* config; + + // Event Loop +@@ -103,36 +103,14 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig + */ + + static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { +- // Open the directory +- daemon->configfd = open(path, O_DIRECTORY); +- if (daemon->configfd < 0) { +- ERROR("Could not open %s: %m\n", path); +- return -errno; +- } +- +- return 0; +-} +- +-FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { +- // Open the file +- int fd = openat(daemon->configfd, path, 0); +- if (fd < 0) { +- ERROR("Could not open configuration file %s: %m\n", path); +- return NULL; +- } +- +- // Return a file handle +- return fdopen(fd, mode); +-} ++ int r; + +-DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path) { +- int fd = openat(daemon->configfd, path, O_DIRECTORY); +- if (fd < 0) { +- ERROR("Could not open configuration directory %s: %m\n", path); +- return NULL; +- } ++ // Open the configuration directory ++ r = nw_configd_create(&daemon->configd, path); ++ if (r < 0) ++ return r; + +- return fdopendir(fd); ++ return 0; + } + + static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { +@@ -213,33 +191,17 @@ static int nw_daemon_setup_loop(nw_daemon* daemon) { + } + + static int nw_daemon_load_config(nw_daemon* daemon) { +- FILE* f = NULL; + int r; + + // If no configuration path has been opened yet, we will open something +- if (!daemon->configfd) { ++ if (!daemon->configd) { + r = nw_daemon_config_open(daemon, CONFIG_DIR); + if (r < 0) +- goto ERROR; ++ return r; + } + + // Open the configuration file +- f = nw_daemon_config_fopen(daemon, "settings", "r"); +- if (!f) { +- r = -errno; +- goto ERROR; +- } +- +- // Create configuration +- r = nw_config_create(&daemon->config, f); +- if (r < 0) +- goto ERROR; +- +-ERROR: +- if (f) +- fclose(f); +- +- return r; ++ return nw_configd_open_config(&daemon->config, daemon->configd, "settings"); + } + + static int nw_start_device_monitor(nw_daemon* daemon) { +@@ -540,8 +502,8 @@ static void nw_daemon_free(nw_daemon* daemon) { + // Cleanup common objects + nw_daemon_cleanup(daemon); + +- if (daemon->configfd > 0) +- close(daemon->configfd); ++ if (daemon->configd) ++ nw_configd_unref(daemon->configd); + if (daemon->stats_collector_event) + sd_event_source_unref(daemon->stats_collector_event); + if (daemon->bus) +@@ -640,6 +602,16 @@ int nw_daemon_save(nw_daemon* daemon) { + return 0; + } + ++nw_configd* nw_daemon_configd(nw_daemon* daemon, const char* path) { ++ if (!daemon->configd) ++ return NULL; ++ ++ if (path) ++ return nw_configd_descend(daemon->configd, path); ++ ++ return nw_configd_ref(daemon->configd); ++} ++ + /* + Bus + */ +diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h +index b03086c..2d56d79 100644 +--- a/src/networkd/daemon.h ++++ b/src/networkd/daemon.h +@@ -29,6 +29,7 @@ + + typedef struct nw_daemon nw_daemon; + ++#include "config.h" + #include "link.h" + #include "links.h" + #include "port.h" +@@ -47,11 +48,7 @@ int nw_daemon_reload(nw_daemon* daemon); + + int nw_daemon_save(nw_daemon* daemon); + +-/* +- Configuration +-*/ +-FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode); +-DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path); ++nw_configd* nw_daemon_configd(nw_daemon* daemon, const char* path); + + /* + Bus +diff --git a/src/networkd/port.c b/src/networkd/port.c +index f547956..141bba5 100644 +--- a/src/networkd/port.c ++++ b/src/networkd/port.c +@@ -222,24 +222,10 @@ ERROR: + return r; + } + +-int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) { ++int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name, FILE* f) { + nw_config* config = NULL; +- FILE* f = NULL; +- char path[PATH_MAX]; + int r; + +- // Make path +- r = nw_string_format(path, "ports/%s", name); +- if (r < 0) +- goto ERROR; +- +- // Open the configuration file +- f = nw_daemon_config_fopen(daemon, path, "r"); +- if (!f) { +- r = -errno; +- goto ERROR; +- } +- + // Initialize the configuration + r = nw_config_create(&config, f); + if (r < 0) +@@ -248,7 +234,7 @@ int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) { + // Fetch the type + const char* type = nw_config_get(config, "TYPE"); + if (!type) { +- ERROR("Port configuration %s has no TYPE\n", path); ++ ERROR("Port %s has no TYPE\n", name); + r = -ENOTSUP; + goto ERROR; + } +@@ -261,8 +247,6 @@ int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) { + ERROR: + if (config) + nw_config_unref(config); +- if (f) +- fclose(f); + + return r; + } +@@ -292,6 +276,7 @@ static void __nw_port_unref(void* data) { + } + + int nw_port_destroy(nw_port* port) { ++ nw_configd* configd = NULL; + int r; + + DEBUG("Destroying port %s\n", port->name); +@@ -299,26 +284,33 @@ int nw_port_destroy(nw_port* port) { + // Destroy the physical link (if exists) + if (port->link) { + r = nw_link_destroy(port->link); +- if (r) +- return r; ++ if (r < 0) ++ goto ERROR; + } + + // Dereference the port from other ports + r = nw_daemon_ports_walk(port->daemon, __nw_port_drop_port, port); +- if (r) +- return r; ++ if (r < 0) ++ goto ERROR; + + // Dereference the port from other zones + r = nw_daemon_zones_walk(port->daemon, __nw_zone_drop_port, port); +- if (r) +- return r; ++ if (r < 0) ++ goto ERROR; + +- // Destroy the configuration +- r = nw_config_destroy(port->config); +- if (r) +- return r; ++ // Fetch the configuration directory ++ configd = nw_daemon_configd(port->daemon, "ports"); ++ if (configd) { ++ r = nw_configd_unlink(configd, port->name, 0); ++ if (r < 0) ++ goto ERROR; ++ } + +- return 0; ++ERROR: ++ if (configd) ++ nw_configd_unref(configd); ++ ++ return r; + } + + int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { +@@ -345,17 +337,19 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { + } + + int nw_port_save(nw_port* port) { +- char path[PATH_MAX]; ++ nw_configd* configd = NULL; + FILE* f = NULL; + int r; + +- // Compose path +- r = nw_string_format(path, "ports/%s", port->name); +- if (r < 0) +- return r; ++ // Fetch configuration directory ++ configd = nw_daemon_configd(port->daemon, "ports"); ++ if (!configd) { ++ r = -errno; ++ goto ERROR; ++ } + + // Open file +- f = nw_daemon_config_fopen(port->daemon, path, "w"); ++ f = nw_configd_fopen(configd, port->name, "w"); + if (!f) { + r = -errno; + goto ERROR; +@@ -372,6 +366,8 @@ int nw_port_save(nw_port* port) { + goto ERROR; + + ERROR: ++ if (configd) ++ nw_configd_unref(configd); + if (f) + fclose(f); + if (r) +diff --git a/src/networkd/port.h b/src/networkd/port.h +index f1cb3d2..3cbe4b0 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -105,7 +105,7 @@ struct nw_port { + + int nw_port_create(nw_port** port, nw_daemon* daemon, + const nw_port_type_id_t type, const char* name, nw_config* config); +-int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name); ++int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name, FILE* f); + + nw_port* nw_port_ref(nw_port* port); + nw_port* nw_port_unref(nw_port* port); +diff --git a/src/networkd/ports.c b/src/networkd/ports.c +index 761e564..95a13e3 100644 +--- a/src/networkd/ports.c ++++ b/src/networkd/ports.c +@@ -130,12 +130,14 @@ static int nw_ports_add_port(nw_ports* ports, nw_port* port) { + return 0; + } + +-static int nw_ports_enumerate_port(nw_ports* ports, const char* name) { ++static int __nw_ports_enumerate(struct dirent* entry, FILE* f, void* data) { + nw_port* port = NULL; + int r; + ++ nw_ports* ports = (nw_ports*)data; ++ + // Create a new port +- r = nw_port_open(&port, ports->daemon, name); ++ r = nw_port_open(&port, ports->daemon, entry->d_name, f); + if (r < 0 || r == 1) + goto ERROR; + +@@ -152,45 +154,19 @@ ERROR: + } + + int nw_ports_enumerate(nw_ports* ports) { +- DIR* d = NULL; +- struct dirent* entry = NULL; ++ nw_configd* configd = NULL; + int r; + +- // Open the ports directory +- d = nw_daemon_config_opendir(ports->daemon, "ports"); +- if (!d) { +- switch (errno) { +- case ENOENT: +- return 0; +- +- default: +- return -errno; +- } +- } +- +- for (;;) { +- // Read the next entry +- entry = readdir(d); +- if (!entry) +- break; +- +- // Skip anything that is not a regular file +- if (entry->d_type != DT_REG) +- continue; ++ // Fetch ports configuration directory ++ configd = nw_daemon_configd(ports->daemon, "ports"); ++ if (!configd) ++ return 0; + +- // Skip hidden files +- if (entry->d_name[0] == '.') +- continue; ++ // Walk through all files ++ r = nw_configd_walk(configd, __nw_ports_enumerate, ports); + +- // Enumerate the port +- r = nw_ports_enumerate_port(ports, entry->d_name); +- if (r < 0) +- goto ERROR; +- } +- +-ERROR: +- if (d) +- closedir(d); ++ // Cleanup ++ nw_configd_unref(configd); + + return r; + } +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index cc5fdaf..19d221f 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -32,6 +32,12 @@ + #include "string.h" + #include "zone.h" + ++static const nw_string_table_t nw_zone_type_id[] = { ++ { -1, NULL }, ++}; ++ ++NW_STRING_TABLE_LOOKUP(nw_zone_type_id_t, nw_zone_type_id) ++ + struct nw_zone { + nw_daemon* daemon; + int nrefs; +@@ -45,32 +51,6 @@ struct nw_zone { + nw_config *config; + }; + +-#define nw_zone_path(zone, path, format, ...) \ +- __nw_zone_path(zone, path, sizeof(path), format, __VA_ARGS__) +- +-static int __nw_zone_path(nw_zone* zone, char* p, const size_t length, +- const char* format, ...) { +- char prefix[NAME_MAX]; +- char suffix[NAME_MAX]; +- va_list args; +- int r; +- +- // Format the prefix +- r = nw_string_format(prefix, "%s/zones/%s", CONFIG_DIR, zone->name); +- if (r) +- return r; +- +- // Format the suffix +- va_start(args, format); +- r = nw_string_vformat(suffix, format, args); +- va_end(args); +- if (r) +- return r; +- +- // Join the two parts together +- return __nw_path_join(p, length, prefix, suffix); +-} +- + static void nw_zone_free(nw_zone* zone) { + if (zone->link) + nw_link_unref(zone->link); +@@ -109,8 +89,7 @@ static int nw_zone_set_link(nw_zone* zone, nw_link* link) { + + static int nw_zone_setup(nw_zone* zone) { + nw_link* link = NULL; +- char path[PATH_MAX]; +- int r; ++ int r = 0; + + // Find the link + link = nw_daemon_get_link_by_name(zone->daemon, zone->name); +@@ -120,18 +99,6 @@ static int nw_zone_setup(nw_zone* zone) { + goto ERROR; + } + +-#if 0 +- // Compose the path to the main configuration file +- r = nw_zone_path(zone, path, "%s", "settings"); +- if (r) +- goto ERROR; +- +- // Initialize the configuration +- r = nw_config_create(&zone->config, path); +- if (r) +- goto ERROR; +-#endif +- + ERROR: + if (link) + nw_link_unref(link); +@@ -139,13 +106,15 @@ ERROR: + return r; + } + +-int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) { ++int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const nw_zone_type_id_t type, ++ const char* name, nw_config* config) { ++ nw_zone* z = NULL; + int r; + + // Allocate a new object +- nw_zone* z = calloc(1, sizeof(*z)); ++ z = calloc(1, sizeof(*z)); + if (!z) +- return 1; ++ return -errno; + + // Store a reference to the daemon + z->daemon = nw_daemon_ref(daemon); +@@ -158,6 +127,11 @@ int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) { + if (r) + goto ERROR; + ++ // Copy the configuration ++ r = nw_config_copy(config, &z->config); ++ if (r < 0) ++ goto ERROR; ++ + // Setup the zone + r = nw_zone_setup(z); + if (r) +@@ -171,6 +145,35 @@ ERROR: + return r; + } + ++int nw_zone_open(nw_zone** zone, nw_daemon* daemon, const char* name, FILE* f) { ++ nw_config* config = NULL; ++ int r; ++ ++ // Initialize the configuration ++ r = nw_config_create(&config, f); ++ if (r < 0) ++ goto ERROR; ++ ++ // Fetch the type ++ const char* type = nw_config_get(config, "TYPE"); ++ if (!type) { ++ ERROR("Zone %s has no TYPE\n", name); ++ r = -ENOTSUP; ++ goto ERROR; ++ } ++ ++ // Create a new zone ++ r = nw_zone_create(zone, daemon, nw_zone_type_id_from_string(type), name, config); ++ if (r < 0) ++ goto ERROR; ++ ++ERROR: ++ if (config) ++ nw_config_unref(config); ++ ++ return r; ++} ++ + nw_zone* nw_zone_ref(nw_zone* zone) { + zone->nrefs++; + +@@ -195,30 +198,41 @@ int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data) { + } + + int nw_zone_save(nw_zone* zone) { +- char path[PATH_MAX]; ++ nw_configd* configd = NULL; + FILE* f = NULL; + int r; + +- // Compose path +- r = nw_string_format(path, "zones/%s/settings", zone->name); +- if (r < 0) ++ // Fetch configuration directory ++ configd = nw_daemon_configd(zone->daemon, "zones"); ++ if (!configd) { ++ r = -errno; + goto ERROR; ++ } + + // Open file +- f = nw_daemon_config_fopen(zone->daemon, path, "w"); ++ f = nw_configd_fopen(configd, zone->name, "w"); + if (!f) { + r = -errno; + goto ERROR; + } + ++ // Write out the configuration ++ r = nw_config_options_write(zone->config); ++ if (r < 0) ++ goto ERROR; ++ + // Write the configuration + r = nw_config_write(zone->config, f); +- if (r) ++ if (r < 0) + goto ERROR; + + ERROR: ++ if (configd) ++ nw_configd_unref(configd); + if (f) + fclose(f); ++ if (r) ++ ERROR("Could not save configuration for zone %s: %s\n", zone->name, strerror(-r)); + + return r; + } +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 480440f..6ab951b 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -28,11 +28,18 @@ + + typedef struct nw_zone nw_zone; + ++typedef enum nw_zone_type_id { ++ __EMPTY ++} nw_zone_type_id_t; ++ + #include + ++#include "config.h" + #include "daemon.h" + +-int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name); ++int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const nw_zone_type_id_t type, ++ const char* name, nw_config* config); ++int nw_zone_open(nw_zone** zone, nw_daemon* daemon, const char* name, FILE* f); + + nw_zone* nw_zone_ref(nw_zone* zone); + nw_zone* nw_zone_unref(nw_zone* zone); +diff --git a/src/networkd/zones.c b/src/networkd/zones.c +index 84a6673..654e637 100644 +--- a/src/networkd/zones.c ++++ b/src/networkd/zones.c +@@ -135,30 +135,15 @@ static int nw_zones_add_zone(nw_zones* zones, nw_zone* zone) { + return 0; + } + +-static int __nw_zones_enumerate(const char* path, const struct stat* s, void* data) { ++static int __nw_zones_enumerate(struct dirent* entry, FILE* f, void* data) { + nw_zone* zone = NULL; + int r; + + nw_zones* zones = (nw_zones*)data; + +- // Skip anything that isn't a directory +- if (!S_ISDIR(s->st_mode)) +- return 0; +- +- // Find the basename of the file +- const char* name = nw_path_basename(path); +- +- // Break on invalid paths +- if (!name) +- return 0; +- +- // Skip any hidden files +- if (*name == '.') +- return 0; +- + // Create a new zone +- r = nw_zone_create(&zone, zones->daemon, name); +- if (r) ++ r = nw_zone_open(&zone, zones->daemon, entry->d_name, f); ++ if (r < 0 || r == 1) + goto ERROR; + + // Add the zone to the list +@@ -174,7 +159,21 @@ ERROR: + } + + int nw_zones_enumerate(nw_zones* zones) { +- return nw_ftw(ZONE_CONFIG_DIR, ZONE_CONFIG_DIR "/*", __nw_zones_enumerate, zones); ++ nw_configd* configd = NULL; ++ int r; ++ ++ // Fetch zones configuration directory ++ configd = nw_daemon_configd(zones->daemon, "zones"); ++ if (!configd) ++ return 0; ++ ++ // Walk through all files ++ r = nw_configd_walk(configd, __nw_zones_enumerate, zones); ++ ++ // Cleanup ++ nw_configd_unref(configd); ++ ++ return r; + } + + size_t nw_zones_num(nw_zones* zones) { +-- +2.39.2 + diff --git a/network/patches/0301-zones-Move-struct-nw_zone-into-header.patch b/network/patches/0301-zones-Move-struct-nw_zone-into-header.patch new file mode 100644 index 000000000..84f8b72ec --- /dev/null +++ b/network/patches/0301-zones-Move-struct-nw_zone-into-header.patch @@ -0,0 +1,115 @@ +From 416ba6cd142bc5006b1c977bec86fc12dfffc80c Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 11 Jun 2023 13:09:41 +0000 +Subject: [PATCH 301/304] zones: Move "struct nw_zone" into header + +Signed-off-by: Michael Tremer +--- + src/networkd/port-vlan.h | 2 +- + src/networkd/port.h | 6 +----- + src/networkd/zone.c | 13 ------------- + src/networkd/zone.h | 16 +++++++++++++++- + 4 files changed, 17 insertions(+), 20 deletions(-) + +diff --git a/src/networkd/port-vlan.h b/src/networkd/port-vlan.h +index e17f7e7..c807238 100644 +--- a/src/networkd/port-vlan.h ++++ b/src/networkd/port-vlan.h +@@ -47,7 +47,7 @@ struct nw_port_vlan { + + // If the parent has not been read from the configuration we will + // save the name and try to find it later. +- char __parent_name[IF_NAMESIZE]; ++ char __parent_name[IFNAMSIZ]; + }; + + extern const nw_port_type_t nw_port_type_vlan; +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 3cbe4b0..422a65f 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -25,10 +25,6 @@ + + #include + +-#ifndef IF_NAMESIZE +-#define IF_NAMESIZE 16 +-#endif +- + #define PORT_CONFIG_DIR CONFIG_DIR "/ports" + + typedef struct nw_port nw_port; +@@ -82,7 +78,7 @@ struct nw_port { + nw_link* link; + + const nw_port_type_t* type; +- char name[IF_NAMESIZE]; ++ char name[IFNAMSIZ]; + + // Configuration + nw_config *config; +diff --git a/src/networkd/zone.c b/src/networkd/zone.c +index 19d221f..1610dc0 100644 +--- a/src/networkd/zone.c ++++ b/src/networkd/zone.c +@@ -38,19 +38,6 @@ static const nw_string_table_t nw_zone_type_id[] = { + + NW_STRING_TABLE_LOOKUP(nw_zone_type_id_t, nw_zone_type_id) + +-struct nw_zone { +- nw_daemon* daemon; +- int nrefs; +- +- // Link +- nw_link* link; +- +- char name[NETWORK_ZONE_NAME_MAX_LENGTH]; +- +- // Configuration +- nw_config *config; +-}; +- + static void nw_zone_free(nw_zone* zone) { + if (zone->link) + nw_link_unref(zone->link); +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 6ab951b..2d1e1dc 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -23,7 +23,6 @@ + + #define ZONE_CONFIG_DIR CONFIG_DIR "/zones" + +-#define NETWORK_ZONE_NAME_MAX_LENGTH 16 + #define NETWORK_ZONE_DEFAULT_MTU 1500 + + typedef struct nw_zone nw_zone; +@@ -32,10 +31,25 @@ typedef enum nw_zone_type_id { + __EMPTY + } nw_zone_type_id_t; + ++#include + #include + + #include "config.h" + #include "daemon.h" ++#include "link.h" ++ ++struct nw_zone { ++ nw_daemon* daemon; ++ int nrefs; ++ ++ // Link ++ nw_link* link; ++ ++ char name[IFNAMSIZ]; ++ ++ // Configuration ++ nw_config *config; ++}; + + int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const nw_zone_type_id_t type, + const char* name, nw_config* config); +-- +2.39.2 + diff --git a/network/patches/0302-Drop-unused-configuration-file-paths.patch b/network/patches/0302-Drop-unused-configuration-file-paths.patch new file mode 100644 index 000000000..a390a86f4 --- /dev/null +++ b/network/patches/0302-Drop-unused-configuration-file-paths.patch @@ -0,0 +1,40 @@ +From 5548c63c9425f39472e75fef86ad2b8877657997 Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 11 Jun 2023 13:10:31 +0000 +Subject: [PATCH 302/304] Drop unused configuration file paths + +Signed-off-by: Michael Tremer +--- + src/networkd/port.h | 2 -- + src/networkd/zone.h | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/src/networkd/port.h b/src/networkd/port.h +index 422a65f..9770079 100644 +--- a/src/networkd/port.h ++++ b/src/networkd/port.h +@@ -25,8 +25,6 @@ + + #include + +-#define PORT_CONFIG_DIR CONFIG_DIR "/ports" +- + typedef struct nw_port nw_port; + + typedef enum nw_port_type_id { +diff --git a/src/networkd/zone.h b/src/networkd/zone.h +index 2d1e1dc..2ece268 100644 +--- a/src/networkd/zone.h ++++ b/src/networkd/zone.h +@@ -21,8 +21,6 @@ + #ifndef NETWORKD_ZONE_H + #define NETWORKD_ZONE_H + +-#define ZONE_CONFIG_DIR CONFIG_DIR "/zones" +- + #define NETWORK_ZONE_DEFAULT_MTU 1500 + + typedef struct nw_zone nw_zone; +-- +2.39.2 + diff --git a/network/patches/0303-util-Drop-nw_ftw.patch b/network/patches/0303-util-Drop-nw_ftw.patch new file mode 100644 index 000000000..dbd75ba6d --- /dev/null +++ b/network/patches/0303-util-Drop-nw_ftw.patch @@ -0,0 +1,77 @@ +From 10edad249159db9d6ef1e2b6e7a8fac78f183fce Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Sun, 11 Jun 2023 13:11:11 +0000 +Subject: [PATCH 303/304] util: Drop nw_ftw + +Signed-off-by: Michael Tremer +--- + src/networkd/util.c | 40 ---------------------------------------- + src/networkd/util.h | 5 ----- + 2 files changed, 45 deletions(-) + +diff --git a/src/networkd/util.c b/src/networkd/util.c +index 0381ea8..e2f5cf1 100644 +--- a/src/networkd/util.c ++++ b/src/networkd/util.c +@@ -18,44 +18,4 @@ + # # + #############################################################################*/ + +-#include +-#include +-#include +-#include +-#include +- + #include "util.h" +- +-int nw_ftw(const char* path, const char* filter, +- int (*callback)(const char* path, const struct stat* s, void* data), void* data) { +- /* +- This is a nested function which allows us to pass some custom pointer to +- the callback function as that isn't possible with nftw(). +- */ +- int __callback(const char* p, const struct stat* s, int type, struct FTW* ftw) { +- int r; +- +- // Filter out anything we don't want +- if (filter) { +- r = fnmatch(filter, p, FNM_PATHNAME); +- +- switch (r) { +- // Pattern didn't match +- case FNM_NOMATCH: +- return 0; +- +- // Pattern matched +- case 0: +- break; +- +- // Error +- default: +- return 1; +- } +- } +- +- return callback(p, s, data); +- } +- +- return nftw(path, __callback, 0, 0); +-} +diff --git a/src/networkd/util.h b/src/networkd/util.h +index 950afda..11317ff 100644 +--- a/src/networkd/util.h ++++ b/src/networkd/util.h +@@ -21,9 +21,4 @@ + #ifndef NETWORKD_UTIL_H + #define NETWORKD_UTIL_H + +-#include +- +-int nw_ftw(const char* path, const char* filter, +- int (*callback)(const char* path, const struct stat* s, void* data), void* data); +- + #endif /* NETWORKD_UTIL_H */ +-- +2.39.2 + diff --git a/network/patches/0304-Makefile-Fix-typo-in-localstatedir.patch b/network/patches/0304-Makefile-Fix-typo-in-localstatedir.patch new file mode 100644 index 000000000..9f4bdd45b --- /dev/null +++ b/network/patches/0304-Makefile-Fix-typo-in-localstatedir.patch @@ -0,0 +1,26 @@ +From b9ac9712ab5dadf45ddc3749d7c9e393bc3eddaf Mon Sep 17 00:00:00 2001 +From: Michael Tremer +Date: Tue, 19 Sep 2023 12:54:53 +0000 +Subject: [PATCH 304/304] Makefile: Fix typo in localstatedir + +Signed-off-by: Michael Tremer +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index 8c0d0c0..7ca1229 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -51,7 +51,7 @@ hooks_zonesdir = $(hooksdir)/zones + + triggersdir = $(networkdir)/triggers + +-logdir = $(localestatedir)/log/network ++logdir = $(localstatedir)/log/network + utildir = $(networkdir) + + CLEANFILES = +-- +2.39.2 + diff --git a/network/patches/network-fix-logdir-path.patch b/network/patches/network-fix-logdir-path.patch deleted file mode 100644 index f708c030a..000000000 --- a/network/patches/network-fix-logdir-path.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 88e5f32944b8dc1c4b1c74028c7d46c37b2aad34 -Author: Stefan Schantl -Date: Sun Mar 19 15:58:11 2023 +0100 - - Makefile.am: Fix typo defining the logdir - - The correct value name should be "localstatedir" - - Signed-off-by: Stefan Schantl - -diff --git a/Makefile.am b/Makefile.am -index 893f1b8..5dc4629 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -51,7 +51,7 @@ hooks_zonesdir = $(hooksdir)/zones - - triggersdir = $(networkdir)/triggers - --logdir = $(localestatedir)/log/network -+logdir = $(localstatedir)/log/network - utildir = $(networkdir) - - CLEANFILES =