[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