[Dnsmasq-discuss] [PATCH v2] Change dhcp_release to use default address when no IP subnet matches

Simon Kelley simon at thekelleys.org.uk
Fri Aug 30 21:22:53 BST 2019


That looks fine. Patch applied.


Cheers,

Simon.



On 28/08/2019 21:13, haleyb.dev at gmail.com wrote:
> From: Brian Haley <haleyb.dev at gmail.com>
> 
> Currently, dhcp_release will only send a 'fake' release
> when the address given is in the same subnet as an IP
> on the interface that was given.
> 
> This doesn't work in an environment where dnsmasq is
> managing leases for remote subnets via a DHCP relay, as
> running dhcp_release locally will just cause it to
> silently exit without doing anything, leaving the lease
> in the database.
> 
> Change it to use the default IP on the interface, as the
> dnsmasq source code at src/dhcp.c does, if no matching subnet
> IP is found, as a fall-back.  This fixes an issue we are
> seeing in certain Openstack deployments where we are using
> dnsmasq to provision baremetal systems in a datacenter.
> 
> While using Dbus might have seemed like an obvious solution,
> because of our extensive use of network namespaces (which
> Dbus doesn't support), this seemed like a better solution
> than creating system.d policy files for each dnsmasq we
> might spawn and using --enable-dbus=$id in order to isolate
> messages to specific dnsmasq instances.
> 
> Signed-off-by: Brian Haley <haleyb.dev at gmail.com>
> ---
>  contrib/lease-tools/dhcp_release.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/contrib/lease-tools/dhcp_release.c b/contrib/lease-tools/dhcp_release.c
> index 59883d4..c866cd9 100644
> --- a/contrib/lease-tools/dhcp_release.c
> +++ b/contrib/lease-tools/dhcp_release.c
> @@ -178,7 +178,7 @@ static int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
>    return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
>  }
>  
> -static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index)
> +static struct in_addr find_interface(struct in_addr client, int fd, unsigned int index, int ifrfd, struct ifreq *ifr)
>  {
>    struct sockaddr_nl addr;
>    struct nlmsghdr *h;
> @@ -218,7 +218,13 @@ static struct in_addr find_interface(struct in_addr client, int fd, unsigned int
>  
>        for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
>  	if (h->nlmsg_type == NLMSG_DONE)
> -	  exit(0);
> +          {
> +	    /* No match found, return first address as src/dhcp.c code does */
> +	    ifr->ifr_addr.sa_family = AF_INET;
> +	    if (ioctl(ifrfd, SIOCGIFADDR, ifr) != -1)
> +	      return ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
> +	    exit(0);
> +          }
>  	else if (h->nlmsg_type == RTM_NEWADDR)
>            {
>              struct ifaddrmsg *ifa = NLMSG_DATA(h);  
> @@ -285,7 +291,7 @@ int main(int argc, char **argv)
>      }
>    
>    lease.s_addr = inet_addr(argv[2]);
> -  server = find_interface(lease, nl, if_nametoindex(argv[1]));
> +  server = find_interface(lease, nl, if_nametoindex(argv[1]), fd, &ifr);
>    
>    memset(&packet, 0, sizeof(packet));
>   
> 




More information about the Dnsmasq-discuss mailing list