odhcpd: make ubus optional at runtime
authorDavid Härdeman <[email protected]>
Sun, 16 Nov 2025 17:55:59 +0000 (18:55 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Mon, 17 Nov 2025 09:07:48 +0000 (10:07 +0100)
This is mostly for developer convenience, allowing ubus to be built in, but
disabled at will when launching odhcpd.

Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/312
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/config.c
src/odhcpd.c
src/odhcpd.h
src/ubus.c

index a84021e46d7fbfc0f29ca132abeb68486a13a250..84e2f73f980cebb5670796dd018b5c1848a7cc97 100644 (file)
@@ -37,6 +37,11 @@ struct config config = {
        .enable_tz = true,
        .main_dhcpv4 = false,
        .dhcp_cb = NULL,
+#ifdef WITH_UBUS
+       .use_ubus = true,
+#else
+       .use_ubus = false,
+#endif /* WITH_UBUS */
        .dhcp_statefile = NULL,
        .dhcp_statedir_fd = -1,
        .dhcp_hostsdir = NULL,
@@ -1119,10 +1124,9 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
                        ifname = blobmsg_get_string(c);
        }
 
-#ifdef WITH_UBUS
        if (overwrite || !iface->ifname)
-               ifname = ubus_get_ifname(name);
-#endif
+               if (config.use_ubus)
+                       ifname = ubus_get_ifname(name);
 
        if (!iface->ifname && !ifname)
                goto err;
@@ -2381,10 +2385,9 @@ void odhcpd_reload(void)
                        continue;
 
                enum odhcpd_mode hybrid_mode = MODE_DISABLED;
-#ifdef WITH_UBUS
-               if (!ubus_has_prefix(i->name, i->ifname))
+
+               if (config.use_ubus && !ubus_has_prefix(i->name, i->ifname))
                        hybrid_mode = MODE_RELAY;
-#endif
 
                if (i->dhcpv6 == MODE_HYBRID)
                        i->dhcpv6 = hybrid_mode;
@@ -2441,10 +2444,12 @@ int odhcpd_run(void)
 {
        static struct uloop_signal sighup = { .signo = SIGHUP, .cb = signal_reload };
 
-       while (ubus_init()) {
-               if (uloop_cancelled)
-                       return EXIT_FAILURE;
-               sleep(1);
+       if (config.use_ubus) {
+               while (ubus_init()) {
+                       if (uloop_cancelled)
+                               return EXIT_FAILURE;
+                       sleep(1);
+               }
        }
 
        odhcpd_reload();
index bc0a833641443d549760fa7302e6ea0539e70fad..f67e4192cc7bcce07fd6056779cf61d347dd32d6 100644 (file)
@@ -67,7 +67,7 @@ void __iflog(int lvl, const char *fmt, ...)
        va_end(ap);
 }
 
-static void print_usage(const char *app)
+_o_noreturn static void print_usage(const char *app, int exit_status)
 {
        printf("== %s Usage ==\n"
               "Features: ra ndp dhcpv6"
@@ -86,8 +86,13 @@ static void print_usage(const char *app)
               "        -c <dir>        Read UCI configuration files from <dir>\n"
               "        -l <int>        Specify log level 0..7 (default %d)\n"
               "        -f              Log to stderr instead of syslog\n"
+#ifdef WITH_UBUS
+              "        -u              Disable ubus support\n"
+#endif /* WITH_UBUS */
               "        -h              Print this help text and exit\n",
               app, config.log_level);
+
+       exit(exit_status);
 }
 
 static bool ipv6_enabled(void)
@@ -106,7 +111,7 @@ int main(int argc, char **argv)
 {
        int opt;
 
-       while ((opt = getopt(argc, argv, "c:l:fh")) != -1) {
+       while ((opt = getopt(argc, argv, "c:l:fuh")) != -1) {
                switch (opt) {
                case 'c':
                        struct stat sb;
@@ -135,9 +140,15 @@ int main(int argc, char **argv)
                        config.log_syslog = false;
                        fprintf(stderr, "Logging to stderr\n");
                        break;
+               case 'u':
+                       config.use_ubus = false;
+                       fprintf(stderr, "Ubus support disabled\n");
+                       break;
                case 'h':
-                       print_usage(argv[0]);
-                       return 0;
+                       print_usage(argv[0], EXIT_SUCCESS);
+               case '?':
+               default:
+                       print_usage(argv[0], EXIT_FAILURE);
                }
        }
 
index f41aaa16d45e3e4d990bc1d22d0b54859ee7cac5..06cc332ec5ba57bbdd1d79cdcf2d97bc7d543b9b 100644 (file)
 #define _o_unused __attribute__((unused))
 #endif /* _o_unused */
 
+#ifndef _o_noreturn
+#define _o_noreturn __attribute__((__noreturn__))
+#endif /* _o_noreturn */
+
 #define ALL_IPV6_NODES "ff02::1"
 #define ALL_IPV6_ROUTERS "ff02::2"
 
@@ -202,10 +206,10 @@ enum duid_type {
 };
 
 struct config {
-       bool legacy;
        bool enable_tz;
        bool main_dhcpv4;
        char *dhcp_cb;
+       bool use_ubus;
 
        char *dhcp_statefile;
        int dhcp_statedir_fd;
@@ -580,11 +584,21 @@ static inline int ubus_init(void)
        return 0;
 }
 
+static inline const char *ubus_get_ifname(const char *name)
+{
+       return NULL;
+}
+
 static inline void ubus_apply_network(void)
 {
        return;
 }
 
+static inline bool ubus_has_prefix(const char *name, const char *ifname)
+{
+       return false;
+}
+
 static inline
 void ubus_bcast_dhcpv4_event(const char *type, const char *iface,
                             const struct dhcpv4_lease *lease)
index 9e516225282de4e54fa898cf8238948b51f6c664..426c1a26c24e31f8e21db042b4be216a2bf6c7e3 100644 (file)
@@ -473,7 +473,7 @@ bool ubus_has_prefix(const char *name, const char *ifname)
        unsigned rem;
 
        if (!dump)
-               return NULL;
+               return false;
 
        blobmsg_for_each_attr(c, dump, rem) {
                struct blob_attr *tb[IFACE_ATTR_MAX];