dhcpv4: simplify dhcpv4_setup_interface()
authorDavid Härdeman <[email protected]>
Thu, 25 Sep 2025 13:45:07 +0000 (15:45 +0200)
committerÁlvaro Fernández Rojas <[email protected]>
Tue, 7 Oct 2025 09:04:01 +0000 (11:04 +0200)
In the disable case, the function would close the interface uloop fd, free
assignments, check if the interface uloop fd should be closed, and return 0.

Simplify the function by bailing early in the disable case, which also removes
one level of indentation for the gist of the function body.

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

index 4304d94bdad0232e89719af3df1c80bbc78fa39c..9caf35ec16745158954e641afedff9e57bbf0196 100644 (file)
@@ -1032,8 +1032,12 @@ static int dhcpv4_setup_addresses(struct interface *iface)
 int dhcpv4_setup_interface(struct interface *iface, bool enable)
 {
        int ret = 0;
-
-       enable = enable && (iface->dhcpv4 != MODE_DISABLED);
+       struct sockaddr_in bind_addr = {
+               .sin_family = AF_INET,
+               .sin_port = htons(DHCPV4_SERVER_PORT),
+               .sin_addr = { INADDR_ANY },
+       };
+       int val = 1;
 
        if (iface->dhcpv4_event.uloop.fd >= 0) {
                uloop_fd_delete(&iface->dhcpv4_event.uloop);
@@ -1041,83 +1045,80 @@ int dhcpv4_setup_interface(struct interface *iface, bool enable)
                iface->dhcpv4_event.uloop.fd = -1;
        }
 
-       if (enable) {
-               struct sockaddr_in bind_addr = {AF_INET, htons(DHCPV4_SERVER_PORT),
-                                       {INADDR_ANY}, {0}};
-               int val = 1;
-
-               iface->dhcpv4_event.uloop.fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
-               if (iface->dhcpv4_event.uloop.fd < 0) {
-                       syslog(LOG_ERR, "socket(AF_INET): %m");
-                       ret = -1;
-                       goto out;
-               }
+       if (!enable || iface->dhcpv4 == MODE_DISABLED) {
+               while (!list_empty(&iface->dhcpv4_assignments))
+                       free_assignment(list_first_entry(&iface->dhcpv4_assignments,
+                                                        struct dhcp_assignment, head));
+               return 0;
+       }
 
-               /* Basic IPv4 configuration */
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_REUSEADDR,
-                                       &val, sizeof(val)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
-                       ret = -1;
-                       goto out;
-               }
+       iface->dhcpv4_event.uloop.fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
+       if (iface->dhcpv4_event.uloop.fd < 0) {
+               syslog(LOG_ERR, "socket(AF_INET): %m");
+               ret = -1;
+               goto out;
+       }
 
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BROADCAST,
-                                       &val, sizeof(val)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
-                       ret = -1;
-                       goto out;
-               }
+       /* Basic IPv4 configuration */
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_REUSEADDR,
+                      &val, sizeof(val)) < 0) {
+               syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
+               ret = -1;
+               goto out;
+       }
 
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_PKTINFO,
-                                       &val, sizeof(val)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(IP_PKTINFO): %m");
-                       ret = -1;
-                       goto out;
-               }
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BROADCAST,
+                      &val, sizeof(val)) < 0) {
+               syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
+               ret = -1;
+               goto out;
+       }
 
-               val = IPTOS_PREC_INTERNETCONTROL;
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_TOS,
-                                       &val, sizeof(val)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(IP_TOS): %m");
-                       ret = -1;
-                       goto out;
-               }
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_PKTINFO,
+                      &val, sizeof(val)) < 0) {
+               syslog(LOG_ERR, "setsockopt(IP_PKTINFO): %m");
+               ret = -1;
+               goto out;
+       }
 
-               val = IP_PMTUDISC_DONT;
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_MTU_DISCOVER,
-                                       &val, sizeof(val)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(IP_MTU_DISCOVER): %m");
-                       ret = -1;
-                       goto out;
-               }
+       val = IPTOS_PREC_INTERNETCONTROL;
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_TOS, &val,
+                      sizeof(val)) < 0) {
+               syslog(LOG_ERR, "setsockopt(IP_TOS): %m");
+               ret = -1;
+               goto out;
+       }
 
-               if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BINDTODEVICE,
-                                       iface->ifname, strlen(iface->ifname)) < 0) {
-                       syslog(LOG_ERR, "setsockopt(SO_BINDTODEVICE): %m");
-                       ret = -1;
-                       goto out;
-               }
+       val = IP_PMTUDISC_DONT;
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, IPPROTO_IP, IP_MTU_DISCOVER,
+                      &val, sizeof(val)) < 0) {
+               syslog(LOG_ERR, "setsockopt(IP_MTU_DISCOVER): %m");
+               ret = -1;
+               goto out;
+       }
 
-               if (bind(iface->dhcpv4_event.uloop.fd, (struct sockaddr*)&bind_addr,
-                                       sizeof(bind_addr)) < 0) {
-                       syslog(LOG_ERR, "bind(): %m");
-                       ret = -1;
-                       goto out;
-               }
+       if (setsockopt(iface->dhcpv4_event.uloop.fd, SOL_SOCKET, SO_BINDTODEVICE,
+                      iface->ifname, strlen(iface->ifname)) < 0) {
+               syslog(LOG_ERR, "setsockopt(SO_BINDTODEVICE): %m");
+               ret = -1;
+               goto out;
+       }
 
-               if (dhcpv4_setup_addresses(iface) < 0) {
-                       ret = -1;
-                       goto out;
-               }
+       if (bind(iface->dhcpv4_event.uloop.fd, (struct sockaddr *)&bind_addr,
+                sizeof(bind_addr)) < 0) {
+               syslog(LOG_ERR, "bind(): %m");
+               ret = -1;
+               goto out;
+       }
 
-               iface->dhcpv4_event.handle_dgram = dhcpv4_handle_dgram;
-               odhcpd_register(&iface->dhcpv4_event);
-       } else {
-               while (!list_empty(&iface->dhcpv4_assignments))
-                       free_assignment(list_first_entry(&iface->dhcpv4_assignments,
-                                                       struct dhcp_assignment, head));
+       if (dhcpv4_setup_addresses(iface) < 0) {
+               ret = -1;
+               goto out;
        }
 
+       iface->dhcpv4_event.handle_dgram = dhcpv4_handle_dgram;
+       odhcpd_register(&iface->dhcpv4_event);
+
 out:
        if (ret < 0 && iface->dhcpv4_event.uloop.fd >= 0) {
                close(iface->dhcpv4_event.uloop.fd);