odhcpd: support stderr logging
authorDavid Härdeman <[email protected]>
Wed, 8 Oct 2025 05:44:56 +0000 (07:44 +0200)
committerÁlvaro Fernández Rojas <[email protected]>
Sat, 18 Oct 2025 15:40:37 +0000 (17:40 +0200)
This is just for debugging purposes. Also, make sure that a cmdline loglevel
doesn't get overwritten by what's in the cfg file (it's customary that
command-line options take precedence over configuration file settings).

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

index 0bcae10f2158c7e3c0412bba6fbf0ff071bb4c16..d6573e2dc932e64fd20b7b1a08bb31c3022e86d4 100644 (file)
@@ -41,6 +41,8 @@ struct config config = {
        .ra_piofolder_fd = -1,
        .uci_cfgfile = "dhcp",
        .log_level = LOG_WARNING,
+       .log_level_cmdline = false,
+       .log_syslog = true,
 };
 
 #define START_DEFAULT  100
@@ -423,9 +425,11 @@ static void set_config(struct uci_section *s)
        if ((c = tb[ODHCPD_ATTR_LOGLEVEL])) {
                int log_level = (blobmsg_get_u32(c) & LOG_PRIMASK);
 
-               if (config.log_level != log_level) {
+               if (config.log_level != log_level && config.log_level_cmdline) {
                        config.log_level = log_level;
-                       setlogmask(LOG_UPTO(config.log_level));
+                       if (config.log_syslog)
+                               setlogmask(LOG_UPTO(config.log_level));
+                       notice("Log level set to %d\n", config.log_level);
                }
        }
 }
index 6b07f0eb111ab0f9684dc2047800118af8fd95f2..1f3cd1b2d7ffadeb0f16a68d99faf282d1fe5f8c 100644 (file)
@@ -74,6 +74,7 @@ static void print_usage(const char *app)
               "\n"
               "        -c <path>       Use an alternative configuration file\n"
               "        -l <int>        Specify log level 0..7 (default %d)\n"
+              "        -f              Log to stderr instead of syslog\n"
               "        -h              Print this help text and exit\n",
               app, config.log_level);
 }
@@ -92,10 +93,9 @@ static bool ipv6_enabled(void)
 
 int main(int argc, char **argv)
 {
-       openlog("odhcpd", LOG_PERROR | LOG_PID, LOG_DAEMON);
        int opt;
 
-       while ((opt = getopt(argc, argv, "c:l:h")) != -1) {
+       while ((opt = getopt(argc, argv, "c:l:fh")) != -1) {
                switch (opt) {
                case 'c':
                        config.uci_cfgfile = realpath(optarg, NULL);
@@ -103,14 +103,24 @@ int main(int argc, char **argv)
                        break;
                case 'l':
                        config.log_level = (atoi(optarg) & LOG_PRIMASK);
+                       config.log_level_cmdline = true;
                        fprintf(stderr, "Log level set to %d\n", config.log_level);
                        break;
+               case 'f':
+                       config.log_syslog = false;
+                       fprintf(stderr, "Logging to stderr\n");
+                       break;
                case 'h':
                        print_usage(argv[0]);
                        return 0;
                }
        }
-       setlogmask(LOG_UPTO(config.log_level));
+
+       if (config.log_syslog) {
+               openlog("odhcpd", LOG_PERROR | LOG_PID, LOG_DAEMON);
+               setlogmask(LOG_UPTO(config.log_level));
+       }
+
        uloop_init();
 
        if (getuid() != 0) {
index 0cda0565a56d28e0d898cb2cb858241bf4e1f438..9a41a59eaa9174236223d0edc8f026a2370cc61d 100644 (file)
@@ -69,10 +69,14 @@ struct nl_sock;
 extern struct vlist_tree leases;
 extern struct config config;
 
-#define __iflog(lvl, fmt, ...)                                         \
-       do {                                                            \
-               if (lvl <= config.log_level)                            \
-                       syslog(lvl, fmt __VA_OPT__(, ) __VA_ARGS__);    \
+#define __iflog(lvl, fmt, ...)                                                 \
+       do {                                                                    \
+               if (lvl > config.log_level)                                     \
+                       break;                                                  \
+               if (config.log_syslog)                                          \
+                       syslog(lvl, fmt __VA_OPT__(, ) __VA_ARGS__);            \
+               else                                                            \
+                       fprintf(stderr, fmt "\n" __VA_OPT__(, ) __VA_ARGS__);   \
        } while(0)
 
 #define debug(fmt, ...)     __iflog(LOG_DEBUG, fmt __VA_OPT__(, ) __VA_ARGS__)
@@ -194,6 +198,8 @@ struct config {
 
        char *uci_cfgfile;
        int log_level;
+       bool log_level_cmdline;
+       bool log_syslog;
 };
 
 /* 2-byte type + 128-byte DUID, RFC8415, §11.1 */