On Mon, Nov 15, 2021 at 12:19:48PM +0000, Klemens Nanni wrote:
> On Mon, Nov 15, 2021 at 02:08:33PM +1000, David Gwynne wrote:
> > The subject line only tells half the story. The other half is that
> > instead of hoping it only identifies Ethernet interfaces it now actually
> > checks and restricts itself to Ethernet interfaces. I couldn't help
> > myself.
> >
> > If it helps my case for this code, I've been using this semantic for a
> > few years in a home grown dhcp-relay we run on our firewalls at
> > work. We used to run the dhcp-relay on a bunch of vlan(4) interfaces,
> > but we currently run them on carp(4). There's no significant difference
> > between using an Ethernet or carp interface from a dhcpd or relay point
> > of view, so the code accepts either.
>
> This sounds reasonable, but I have no means to test these setups.
>
> > The kernel lets you bind to addresses on down interfaces, so I don't
> > know why dhcpd has to be precious about it. We often start the
> > firewalls up with whole groups of these interfaces forced down.
> > We want DHCP packets to start moving when then interface comes up
> > though, therefore the daemon should start and be running even if
> > the interface is down.
>
> I wondered about this as well but was hesitant to touch dhcpd(8) because
> I rarely use it.
>
> FWIW, ISC DHCP has the same code and comment wrt. interface check,
> altough I didn't do any runtime tests.
our dhcpd came from isc dhcpd, and the guts havent been touched
much.
> > Should I warn if the interface is down on startup?
>
> Wouldn't hurt, although you don't see it at boot time anyway, so not
> much help, imho.
>
> > There's some other questionable code in here, but I'm going to take
> > some deep breaths and try to ignore them for now.
>
> Here is the minimal diff I first used to fix my vport/DOWN issue,
> before going the implicit UP route.
this is a good start. im ok with you putting your change in, just get
someone else to ok it too.
> Regardless of vport's behaviour, this seemed sensible; I mean, I can
> `nc -l' on down interfaces, other daemons don't care about UP and I'd
> rather have dhcpd running and pull interfaces UP to fix DHCP instead of
> restarting failed dhcpd (which could still serve on other UP interfaces).
exactly.
>
> Index: dispatch.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
> retrieving revision 1.43
> diff -u -p -r1.43 dispatch.c
> --- dispatch.c 12 Apr 2017 19:17:30 -0000 1.43
> +++ dispatch.c 13 Nov 2021 23:04:36 -0000
> @@ -112,13 +112,12 @@ discover_interfaces(int *rdomain)
> for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
> /*
> * See if this is the sort of interface we want to
> - * deal with. Skip loopback, point-to-point and down
> + * deal with. Skip loopback and point-to-point
> * interfaces, except don't skip down interfaces if we're
> * trying to get a list of configurable interfaces.
> */
> if ((ifa->ifa_flags & IFF_LOOPBACK) ||
> (ifa->ifa_flags & IFF_POINTOPOINT) ||
> - (!(ifa->ifa_flags & IFF_UP)) ||
> (!(ifa->ifa_flags & IFF_BROADCAST)))
> continue;
>
>
> > OK?
> >
> > Index: dispatch.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
> > retrieving revision 1.43
> > diff -u -p -r1.43 dispatch.c
> > --- dispatch.c 12 Apr 2017 19:17:30 -0000 1.43
> > +++ dispatch.c 15 Nov 2021 03:50:46 -0000
> > @@ -47,6 +47,7 @@
> > #include <net/if.h>
> > #include <net/if_dl.h>
> > #include <net/if_media.h>
> > +#include <net/if_types.h>
> >
> > #include <netinet/in.h>
> >
> > @@ -112,14 +113,10 @@ discover_interfaces(int *rdomain)
> > for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
> > /*
> > * See if this is the sort of interface we want to
> > - * deal with. Skip loopback, point-to-point and down
> > - * interfaces, except don't skip down interfaces if we're
> > - * trying to get a list of configurable interfaces.
> > + * deal with, which is basically Ethernet.
> > */
> > if ((ifa->ifa_flags & IFF_LOOPBACK) ||
> > - (ifa->ifa_flags & IFF_POINTOPOINT) ||
> > - (!(ifa->ifa_flags & IFF_UP)) ||
> > - (!(ifa->ifa_flags & IFF_BROADCAST)))
> > + (ifa->ifa_flags & IFF_POINTOPOINT))
> > continue;
> >
> > /* See if we've seen an interface that matches this one. */
> > @@ -156,11 +153,27 @@ discover_interfaces(int *rdomain)
> > /* If we have the capability, extract link information
> > and record it in a linked list. */
> > if (ifa->ifa_addr->sa_family == AF_LINK) {
> > - struct sockaddr_dl *sdl =
> > - ((struct sockaddr_dl *)(ifa->ifa_addr));
> > + struct if_data *ifi;
> > + struct sockaddr_dl *sdl;
> > +
> > + ifi = (struct if_data *)ifa->ifa_data;
> > + if (ifi->ifi_type != IFT_ETHER &&
> > + ifi->ifi_type != IFT_CARP) {
> > + /* this interface will be cleaned up later */
> > + continue;
> > + }
> > +
> > + sdl = ((struct sockaddr_dl *)(ifa->ifa_addr));
> > + if (sdl->sdl_alen > sizeof(tmp->hw_address.haddr)) {
> > + log_warnx("interface %s long hardware address",
> > + tmp->name);
> > + /* this interface will be cleaned up later */
> > + continue;
> > + }
> > +
> > tmp->index = sdl->sdl_index;
> > tmp->hw_address.hlen = sdl->sdl_alen;
> > - tmp->hw_address.htype = HTYPE_ETHER; /* XXX */
> > + tmp->hw_address.htype = HTYPE_ETHER;
> > memcpy(tmp->hw_address.haddr,
> > LLADDR(sdl), sdl->sdl_alen);
> > } else if (ifa->ifa_addr->sa_family == AF_INET) {
> > @@ -236,6 +249,17 @@ discover_interfaces(int *rdomain)
> > last = NULL;
> > for (tmp = interfaces; tmp; tmp = next) {
> > next = tmp->next;
> > +
> > + if (tmp->index == 0) {
> > + log_warnx("Can't listen on %s - wrong interface type",
> > + tmp->name);
> > + /* Remove tmp from the list of interfaces. */
> > + if (!last)
> > + interfaces = interfaces->next;
> > + else
> > + last->next = tmp->next;
> > + continue;
> > + }
> >
> > if (!tmp->ifp) {
> > log_warnx("Can't listen on %s - it has no IP address.",
> >