I'm not very familiar with the dnsmasq codebase, but I think I can
understand the issue now. Here's the dnsmasq configuration that
reproduces the issue

port=0
log-dhcp
enable-tftp
tftp-root=/srv/tftp
interface=eth0
dhcp-range=set:proxy,10.10.10.0,proxy,255.255.255.0
pxe-service=x86PC,"ltsp.ipxe",ltsp/ltsp.ipxe

In 7199531ff155c76cc323002967de35cea28e727a, one of the hunks is

@@ -955,13 +958,10 @@ size_t dhcp_reply(struct dhcp_context *context, char 
*iface_name, int int_index,
                {
                  struct dhcp_boot *boot;
                  int redirect4011 = 0;
+                 struct dhcp_opt *option;

-                 if (tmp->netid.net)
-                   {
-                     tmp->netid.next = netid;
-                     tagif_netid = run_tag_if(&tmp->netid);
-                   }
-
+                 /* OK only dhcp-option-pxe options. */
+                 tagif_netid = option_filter(netid, tmp->netid.net ? 
&tmp->netid : NULL, daemon->dhcp_opts, 2);
                  boot = find_boot(tagif_netid);

                  mess->yiaddr.s_addr = 0;

There are two relevant things happening here:

1. tmp->netid.next is no longer written to;
2. option_filter is now used;

Somehow (and I'm not exactly sure why this happens), tmp->netid.next is
!= NULL on the second request. Since option_filter internally loops over
the context tags (tmp->netid in this scenario), this results in an
infinite loop. Setting it to NULL explicitly seems to work.

diff --git a/src/rfc2131.c b/src/rfc2131.c
index f494a55..4a61820 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -961,6 +961,7 @@ size_t dhcp_reply(struct dhcp_context *context, char 
*iface_name, int int_index,
                  struct dhcp_opt *option;
 
                  /* OK only dhcp-option-pxe options. */
+                 tmp->netid.next = NULL;
                  tagif_netid = option_filter(netid, tmp->netid.net ? 
&tmp->netid : NULL, daemon->dhcp_opts, 2);
                  boot = find_boot(tagif_netid);
                  
This whole "setting netid.next to NULL" idea is already present in the same 
file, in the do_options function. I'm not 100% confident that this is the 
correct fix though, but it at least makes the problem go away.

This seems like the same problem reported in the upstream mailing list
back in October: https://www.mail-archive.com/dnsmasq-
[email protected]/msg18159.html

Do note that (AFAICT) this only manifests when using "set:proxy" in the
dhcp-range option. Without it, the infinite loop does not happen. I'm
also not sure why this is the case. The LTSP configuration does ship
with this set:proxy option.

I'm going to send this upstream for some feedback. Unsure how to proceed
in the Ubuntu side, though.

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2166430

Title:
  dnsmasq 2.91-0ubuntu0.24.04.1 update broke ProxyDHCP mode; please stop
  the phased update

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/dnsmasq/+bug/2166430/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to