From: Nicolas BESNARD Date: Wed, 20 Nov 2024 13:20:49 +0000 (+0000) Subject: ubus: connect to UBus backend X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=33b972bc526a52dc73c6b58e8637d46d27a49481;p=project%2Fodhcp6c.git ubus: connect to UBus backend Problem: odhcp6c is not connected to UBus making communication with other processes more difficult. Solution: Connect odhcp6c to UBus back-end when the WITH_UBUS build time configuration option is set. Signed-off-by: Nicolas BESNARD Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcp6c/pull/106 Signed-off-by: Álvaro Fernández Rojas --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a464658..006cfd3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,10 +25,14 @@ jobs: gcc: /usr/bin/x86_64-linux-gnu-gcc packages: gcc-x86-64-linux-gnu outputs: - size-aarch64: ${{ steps.build.outputs.size_aarch64 }} - size-arm: ${{ steps.build.outputs.size_arm }} - size-mips: ${{ steps.build.outputs.size_mips }} - size-x86_64: ${{ steps.build.outputs.size_x86_64 }} + size-aarch64-without-ubus: ${{ steps.without_ubus.outputs.size_aarch64 }} + size-aarch64-with-ubus: ${{ steps.with_ubus.outputs.size_aarch64 }} + size-arm-without-ubus: ${{ steps.without_ubus.outputs.size_arm }} + size-arm-with-ubus: ${{ steps.with_ubus.outputs.size_arm }} + size-mips-without-ubus: ${{ steps.without_ubus.outputs.size_mips }} + size-mips-with-ubus: ${{ steps.with_ubus.outputs.size_mips }} + size-x86_64-without-ubus: ${{ steps.without_ubus.outputs.size_x86_64 }} + size-x86_64-with-ubus: ${{ steps.with_ubus.outputs.size_x86_64 }} steps: - name: Checkout odhcp6c uses: actions/checkout@v5 @@ -45,6 +49,12 @@ jobs: repository: openwrt/libubox path: depends/libubox + - name: Checkout ubus + uses: actions/checkout@v5 + with: + repository: openwrt/ubus + path: depends/ubus + - name: Install dependencies run: | sudo apt update @@ -76,14 +86,38 @@ jobs: make make install - - id: build - name: Build odhcp6c + - name: Build ubus + working-directory: depends/ubus + run: | + cmake \ + -DCMAKE_C_COMPILER=${{ matrix.gcc }} \ + -DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build \ + -DBUILD_LUA=OFF -DBUILD_EXAMPLES=OFF \ + --install-prefix ${GITHUB_WORKSPACE}/build + make + make install + + - id: without_ubus + name: Build odhcp6c (w/o ubus) + env: + BUILD_DIR: build/odhcp6c-without-ubus + run: | + cmake \ + -DCMAKE_C_COMPILER=${{ matrix.gcc }} \ + -DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build \ + -B $BUILD_DIR + make -C $BUILD_DIR + echo "size_${{ matrix.arch }}=$( find $BUILD_DIR -type f -name odhcp6c -printf '%s' )" >> $GITHUB_OUTPUT + + - id: with_ubus + name: Build odhcp6c (with ubus) env: - BUILD_DIR: build/odhcp6c + BUILD_DIR: build/odhcp6c-with-ubus run: | cmake \ -DCMAKE_C_COMPILER=${{ matrix.gcc }} \ -DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/build \ + -DUBUS=ON \ -B $BUILD_DIR make -C $BUILD_DIR echo "size_${{ matrix.arch }}=$( find $BUILD_DIR -type f -name odhcp6c -printf '%s' )" >> $GITHUB_OUTPUT @@ -93,7 +127,7 @@ jobs: with: name: odhcp6c-${{ matrix.arch }}-binaries path: | - build/odhcp6c/odhcp6c + build/odhcp6c-*/odhcp6c if-no-files-found: error summary: @@ -103,12 +137,17 @@ jobs: steps: - name: Sizes summary env: - size_aarch64: ${{needs.build.outputs.size-aarch64}} - size_arm: ${{needs.build.outputs.size-arm}} - size_mips: ${{needs.build.outputs.size-mips}} - size_x86_64: ${{needs.build.outputs.size-x86_64}} + size_aarch64_without_ubus: ${{needs.build.outputs.size-aarch64-without-ubus}} + size_aarch64_with_ubus: ${{needs.build.outputs.size-aarch64-with-ubus}} + size_arm_without_ubus: ${{needs.build.outputs.size-arm-without-ubus}} + size_arm_with_ubus: ${{needs.build.outputs.size-arm-with-ubus}} + size_mips_without_ubus: ${{needs.build.outputs.size-mips-without-ubus}} + size_mips_with_ubus: ${{needs.build.outputs.size-mips-with-ubus}} + size_x86_64_without_ubus: ${{needs.build.outputs.size-x86_64-without-ubus}} + size_x86_64_with_ubus: ${{needs.build.outputs.size-x86_64-with-ubus}} run: | echo "### ${GITHUB_WORKFLOW} sizes :floppy_disk:" >> $GITHUB_STEP_SUMMARY echo "| Variant | aarch64 | arm | mips | x86_64 |" >> $GITHUB_STEP_SUMMARY echo "| :---: | :---: | :---: | :---: | :---: |" >> $GITHUB_STEP_SUMMARY - echo "| odhcp6c | ${size_aarch64} | ${size_arm} | ${size_mips} | ${size_x86_64} |" >> $GITHUB_STEP_SUMMARY + echo "| w/o ubus | ${size_aarch64_without_ubus} | ${size_arm_without_ubus} | ${size_mips_without_ubus} | ${size_x86_64_without_ubus} |" >> $GITHUB_STEP_SUMMARY + echo "| with ubus | ${size_aarch64_with_ubus} | ${size_arm_with_ubus} | ${size_mips_with_ubus} | ${size_x86_64_with_ubus} |" >> $GITHUB_STEP_SUMMARY diff --git a/CMakeLists.txt b/CMakeLists.txt index 02d44be..0c3d1be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,15 @@ if (${EXT_CER_ID}) target_compile_definitions(${PROJECT_NAME} PRIVATE EXT_CER_ID=${EXT_CER_ID}) endif(${EXT_CER_ID}) +if(${UBUS}) + target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_UBUS) + target_sources(${PROJECT_NAME} PRIVATE src/ubus.c) + find_path(ubus_include_dir libubus.h) + target_include_directories(${PROJECT_NAME} PRIVATE ${ubus_include_dir}) + find_library(libubus ubus) + target_link_libraries(${PROJECT_NAME} PRIVATE ${libubus}) +endif(${UBUS}) + # Installation install(TARGETS ${PROJECT_NAME} DESTINATION sbin/) diff --git a/scripts/devel-build.sh b/scripts/devel-build.sh index 807f2a4..a100c00 100755 --- a/scripts/devel-build.sh +++ b/scripts/devel-build.sh @@ -27,6 +27,7 @@ DEPSDIR="${BUILDDIR}/depends" cd "${DEPSDIR}" [ -e "json-c" ] || git clone https://github.com/json-c/json-c.git [ -e "libubox" ] || git clone https://github.com/openwrt/libubox.git +[ -e "ubus" ] || git clone https://github.com/openwrt/ubus.git # Build json-c cd "${DEPSDIR}/json-c" @@ -52,12 +53,25 @@ cmake \ make make install +# Build ubus +cd "${DEPSDIR}/ubus" +cmake \ + -S . \ + -B . \ + -DCMAKE_PREFIX_PATH="${BUILDDIR}" \ + -DBUILD_LUA=OFF \ + -DBUILD_EXAMPLES=OFF \ + --install-prefix "${BUILDDIR}" +make +make install + # Build odhcp6c cd "${ODHCP6CDIR}" cmake \ -S . \ -B "${BUILDDIR}" \ -DCMAKE_PREFIX_PATH="${BUILDDIR}" \ + -DUBUS=ON \ ${BUILD_ARGS} make -C "${BUILDDIR}" diff --git a/src/odhcp6c.c b/src/odhcp6c.c index ee8d96a..8ffae84 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -37,6 +37,7 @@ #include "odhcp6c.h" #include "ra.h" +#include "ubus.h" #ifndef IN6_IS_ADDR_UNIQUELOCAL #define IN6_IS_ADDR_UNIQUELOCAL(a) \ @@ -489,6 +490,24 @@ int main(_unused int argc, char* const argv[]) fds[nfds].events = POLLIN; nfds++; +#ifdef WITH_UBUS + char *err = ubus_init(ifname); + if (err) { + syslog(LOG_ERR, "ubus error: %s", err); + return 1; + } + + struct ubus_context *ubus = ubus_get_ctx(); + int ubus_socket = ubus->sock.fd; + if (ubus_socket < 0) { + syslog(LOG_ERR, "Invalid ubus file descriptor"); + return 1; + } + fds[nfds].fd = ubus_socket; + fds[nfds].events = POLLIN; + nfds++; +#endif /* WITH_UBUS */ + script_call("started", 0, false); while (!terminate) { // Main logic @@ -715,9 +734,18 @@ int main(_unused int argc, char* const argv[]) if (fds[0].revents & POLLIN) dhcpv6_receive_response(msg_type); +#ifdef WITH_UBUS + if (fds[1].revents & POLLIN) + ubus_handle_event(ubus); +#endif /* WITH_UBUS */ } + script_call("stopped", 0, true); +#ifdef WITH_UBUS + ubus_destroy(ubus); +#endif /* WITH_UBUS */ + return 0; } diff --git a/src/ubus.c b/src/ubus.c new file mode 100644 index 0000000..b380aa2 --- /dev/null +++ b/src/ubus.c @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** SPDX-License-Identifier: BSD-2-Clause-Patent +** +** SPDX-FileCopyrightText: Copyright (c) 2024 SoftAtHome +** +** Redistribution and use in source and binary forms, with or +** without modification, are permitted provided that the following +** conditions are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. Redistributions in binary form must reproduce the above +** copyright notice, this list of conditions and the following +** disclaimer in the documentation and/or other materials provided +** with the distribution. +** +** Subject to the terms and conditions of this license, each +** copyright holder and contributor hereby grants to those receiving +** rights under this license a perpetual, worldwide, non-exclusive, +** no-charge, royalty-free, irrevocable (except for failure to +** satisfy the conditions of this license) patent license to make, +** have made, use, offer to sell, sell, import, and otherwise +** transfer this software, where such license applies only to those +** patent claims, already acquired or hereafter acquired, licensable +** by such copyright holder or contributor that are necessarily +** infringed by: +** +** (a) their Contribution(s) (the licensed copyrights of copyright +** holders and non-copyrightable additions of contributors, in +** source or binary form) alone; or +** +** (b) combination of their Contribution(s) with the work of +** authorship to which such Contribution(s) was added by such +** copyright holder or contributor, if, at the time the Contribution +** is added, such addition causes such combination to be necessarily +** infringed. The patent license shall not apply to any other +** combinations which include the Contribution. +** +** Except as expressly stated above, no rights or licenses from any +** copyright holder or contributor is granted under this license, +** whether expressly, by implication, estoppel or otherwise. +** +** DISCLAIMER +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +** CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +** AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ +#include "odhcp6c.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include "ubus.h" + +struct ubus_context *ubus = NULL; +static char ubus_name[24]; + +static int ubus_handle_get_state(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, struct blob_attr *msg); + +static struct ubus_object_type odhcp6c_object_type = { + .name = "odhcp6c" +}; + +static struct ubus_object odhcp6c_object = { + .name = NULL, + .type = &odhcp6c_object_type, + .methods = odhcp6c_object_methods, + .n_methods = ARRAY_SIZE(odhcp6c_object_methods), +}; + +static void ubus_disconnect_cb(struct ubus_context *ubus) +{ + int ret; + + ret = ubus_reconnect(ubus, NULL); + if (ret) { + syslog(LOG_ERR, "Cannot reconnect to ubus: %s", ubus_strerror(ret)); + ubus_destroy(ubus); + } +} + +char *ubus_init(const char* interface) +{ + int ret = 0; + + if (!(ubus = ubus_connect(NULL))) + return NULL; + + snprintf(ubus_name, 24, "odhcp6c.%s", interface); + odhcp6c_object.name = ubus_name; + + ret = ubus_add_object(ubus, &odhcp6c_object); + if (ret) { + ubus_destroy(ubus); + return (char *)ubus_strerror(ret); + } + + ubus->connection_lost = ubus_disconnect_cb; + return NULL; +} + +struct ubus_context *ubus_get_ctx(void) +{ + return ubus; +} + +void ubus_destroy(struct ubus_context *ubus) +{ + syslog(LOG_NOTICE, "Disconnecting from ubus"); + + if (ubus != NULL) + ubus_free(ubus); + ubus = NULL; + + /* Forces re-initialization when we're reusing the same definitions later on. */ + odhcp6c_object.id = 0; + odhcp6c_object.id = 0; +} diff --git a/src/ubus.h b/src/ubus.h new file mode 100644 index 0000000..855770e --- /dev/null +++ b/src/ubus.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** SPDX-License-Identifier: BSD-2-Clause-Patent +** +** SPDX-FileCopyrightText: Copyright (c) 2024 SoftAtHome +** +** Redistribution and use in source and binary forms, with or +** without modification, are permitted provided that the following +** conditions are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** +** 2. Redistributions in binary form must reproduce the above +** copyright notice, this list of conditions and the following +** disclaimer in the documentation and/or other materials provided +** with the distribution. +** +** Subject to the terms and conditions of this license, each +** copyright holder and contributor hereby grants to those receiving +** rights under this license a perpetual, worldwide, non-exclusive, +** no-charge, royalty-free, irrevocable (except for failure to +** satisfy the conditions of this license) patent license to make, +** have made, use, offer to sell, sell, import, and otherwise +** transfer this software, where such license applies only to those +** patent claims, already acquired or hereafter acquired, licensable +** by such copyright holder or contributor that are necessarily +** infringed by: +** +** (a) their Contribution(s) (the licensed copyrights of copyright +** holders and non-copyrightable additions of contributors, in +** source or binary form) alone; or +** +** (b) combination of their Contribution(s) with the work of +** authorship to which such Contribution(s) was added by such +** copyright holder or contributor, if, at the time the Contribution +** is added, such addition causes such combination to be necessarily +** infringed. The patent license shall not apply to any other +** combinations which include the Contribution. +** +** Except as expressly stated above, no rights or licenses from any +** copyright holder or contributor is granted under this license, +** whether expressly, by implication, estoppel or otherwise. +** +** DISCLAIMER +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +** CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +** AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +** POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef _UBUS_H_ +#define _UBUS_H_ + +#ifdef WITH_UBUS +#include +#endif /* WITH_UBUS */ + +char *ubus_init(const char* interface); +struct ubus_context *ubus_get_ctx(void); +void ubus_destroy(struct ubus_context *ubus); + +#endif /* _UBUS_H_ */