Thanks for filing this bug, and the excellent analysis.

So it looks like the dnsmasq change was introduced here:
https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=744231d99505cdead314d13506b5ff8c44a13088

That was in response to this mailing list discussion:
https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2023q4/017333.html

I think we need to report this issue upstream, perhaps we can revert
that commit in the meantime.

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to dnsmasq in Ubuntu.
https://bugs.launchpad.net/bugs/2055776

Title:
  After updating ubuntu, the network to which the subnet address is
  assigned does not become active in KVM.

Status in dnsmasq package in Ubuntu:
  New

Bug description:
  phenomenon:
    After updating ubuntu, the network to which the subnet address is assigned 
does not become active in KVM.

  Cause:
    This is because the following dnsmasq update operation performed by apt's 
automatic update causes an error. It worked properly with dnsmasq 2.80, but 
does not work properly with 2.90.

  $ cat /var/log/apt/history.log
  (snip)
  Start-Date: 2024-02-27  06:17:31
  Commandline: /usr/bin/unattended-upgrade
  Upgrade: dnsmasq-base:amd64 (2.80-1.1ubuntu1.7, 2.90-0ubuntu0.20.04.1)
  End-Date: 2024-02-27  06:17:44
  (snip)
  $

  Cause details:
    As a premise, bind-dynamic is set in the dnsmasq config file for KVM. Below 
is an example.

  $ cat default.conf 
  ##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
  ##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
  ##    virsh net-edit default
  ## or other application using the libvirt API.
  ##
  ## dnsmasq conf file created by libvirt
  strict-order
  user=libvirt-dnsmasq
  pid-file=/run/libvirt/network/default.pid
  except-interface=lo
  bind-dynamic
  interface=virbr0
  dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0
  dhcp-no-override
  dhcp-authoritative
  dhcp-lease-max=253
  dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
  addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
  $ 

  
  When starting the network with KVM (virsh net-start), dnsmasq started from 
KVM executes the make_sock function twice as shown below.

     $ cat network.c
     (snip)
     1087 static struct listener *create_listeners(union mysockaddr *addr, int 
do_
     1087 tftp, int dienow)
     1088 {
     1089   struct listener *l = NULL;
     1090   int fd = -1, tcpfd = -1, tftpfd = -1;
     1091 
     1092   (void)do_tftp;
     1093 
     1094   if (daemon->port != 0)
     1095     {
     1096       fd = make_sock(addr, SOCK_DGRAM, dienow);
     1097       tcpfd = make_sock(addr, SOCK_STREAM, dienow);
     1098     }
     (snip)

  The following code causes an issue with the update made in dnsmasq
  2.90.

     $ cat network.c
     (snip)
      895 static int make_sock(union mysockaddr *addr, int type, int dienow)
      896 {
      (snip)
      934       if (!option_bool(OPT_CLEVERBIND) || errno != EADDRNOTAVAIL)
      935         {
      936           if (dienow)
      937             die(s, daemon->addrbuff, EC_BADNET);
      938           else
      939             my_syslog(LOG_WARNING, s, daemon->addrbuff, 
strerror(errno))    939 ;
      940         }
      (snip)

  
  function "make_sock" in network.c:1096 binds the socket to 192.168.122.1/24, 
and then make_sock in network.c:1097 tries to bind to the same address. 
However, in network.c:934, when errno==98 occurs, network.c:937 is executed, so 
dnsmasq does not cause a startup error. As a result, virsh net-start fails.

  As a temporary workaround, it will work if you try not to die.

  $ diff -u  network_c_back  network.c 
  --- network_c_back  2024-02-29 15:36:05.156467935 +0000
  +++ network.c 2024-02-29 15:36:38.733324350 +0000
  @@ -934,7 +934,8 @@
         if (!option_bool(OPT_CLEVERBIND) || errno != EADDRNOTAVAIL)
    {
      if (dienow)
  -     die(s, daemon->addrbuff, EC_BADNET);
  +     my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
  +     //die(s, daemon->addrbuff, EC_BADNET);
      else
        my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
    }
  $ 

  If bind-dynamic is set, it should be modified so that it works even if
  errno==98.

  For reference, in the case of dnsmasq 2.80, the code is as follows, so
  no error occurs.

      network.c
      699 static int make_sock(union mysockaddr *addr, int type, int dienow)
      700 {
      701   int family = addr->sa.sa_family;
      702   int fd, rc, opt = 1;
      (snip)
          715     err:
      716       errsave = errno;
      717       port = prettyprint_addr(addr, daemon->addrbuff);
      718       if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
      719         sprintf(daemon->addrbuff, "port %d", port);
      720       s = _("failed to create listening socket for %s: %s");
      721       
      722       if (fd != -1)
      723         close (fd);
      724         
      725       errno = errsave;
      726 
      727       if (dienow)
      728         {
      729           /* failure to bind addresses given by --listen-address at 
this
      729  point
      730              is OK if we're doing bind-dynamic */
      731           if (!option_bool(OPT_CLEVERBIND))
      732             die(s, daemon->addrbuff, EC_BADNET);
      733         }
      734       else
      735         my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
      736       
      737       return -1;
      738     }  

  If bind-dynamic is set (option_bool(OPT_CLEVERBIND)==true), it will
  not die.

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


-- 
Mailing list: https://launchpad.net/~touch-packages
Post to     : touch-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~touch-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to