From: Roy Marples Date: Thu, 23 Apr 2020 14:15:41 +0000 (+0000) Subject: if: support changing hardware address type on Linux X-Git-Tag: v9.1.0~113 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1a1e7aa075784a2ff0a3ab4b6d45aa3b6a83850a;p=thirdparty%2Fdhcpcd.git if: support changing hardware address type on Linux --- diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 0059f47b..fa52fdfc 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -1208,17 +1208,12 @@ dhcpcd_linkoverflow(struct dhcpcd_ctx *ctx) } void -dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname, - const void *hwaddr, uint8_t hwlen) +dhcpcd_handlehwaddr(struct interface *ifp, + uint16_t hwtype, const void *hwaddr, uint8_t hwlen) { - struct interface *ifp; char buf[sizeof(ifp->hwaddr) * 3]; - ifp = if_find(ctx->ifaces, ifname); - if (ifp == NULL) - return; - - if (!if_valid_hwaddr(hwaddr, hwlen)) + if (hwaddr == NULL || !if_valid_hwaddr(hwaddr, hwlen)) hwlen = 0; if (hwlen > sizeof(ifp->hwaddr)) { @@ -1227,7 +1222,14 @@ dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname, return; } - if (ifp->hwlen == hwlen && memcmp(ifp->hwaddr, hwaddr, hwlen) == 0) + if (ifp->hwtype != hwtype) { + loginfox("%s: hardware address type changed from %d to %d", + ifp->name, ifp->hwtype, hwtype); + ifp->hwtype = hwtype; + } + + if (ifp->hwlen == hwlen && + (hwlen == 0 || memcmp(ifp->hwaddr, hwaddr, hwlen) == 0)) return; loginfox("%s: new hardware address: %s", ifp->name, diff --git a/src/dhcpcd.h b/src/dhcpcd.h index 57d177e3..77b80058 100644 --- a/src/dhcpcd.h +++ b/src/dhcpcd.h @@ -257,8 +257,7 @@ void dhcpcd_linkoverflow(struct dhcpcd_ctx *); int dhcpcd_handleargs(struct dhcpcd_ctx *, struct fd_list *, int, char **); void dhcpcd_handlecarrier(struct dhcpcd_ctx *, int, unsigned int, const char *); int dhcpcd_handleinterface(void *, int, const char *); -void dhcpcd_handlehwaddr(struct dhcpcd_ctx *, const char *, - const void *, uint8_t); +void dhcpcd_handlehwaddr(struct interface *, uint16_t, const void *, uint8_t); void dhcpcd_dropinterface(struct interface *, const char *); int dhcpcd_selectprofile(struct interface *, const char *); diff --git a/src/if-bsd.c b/src/if-bsd.c index 47e3e57b..e5189112 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -1330,7 +1330,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) break; #endif memcpy(&sdl, rti_info[RTAX_IFA], rti_info[RTAX_IFA]->sa_len); - dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen); + dhcpcd_handlehwaddr(ifp, ifp->hwtype, + CLLADDR(&sdl), sdl.sdl_alen); break; } #ifdef INET diff --git a/src/if-linux.c b/src/if-linux.c index e3338465..8d397ebc 100644 --- a/src/if-linux.c +++ b/src/if-linux.c @@ -931,12 +931,13 @@ link_netlink(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm) } /* Re-read hardware address and friends */ - if (!(ifi->ifi_flags & IFF_UP) && hwaddr) { - uint8_t l; + if (!(ifi->ifi_flags & IFF_UP)) { + void *hwa = hwaddr != NULL ? RTA_DATA(hwaddr) : NULL; + uint8_t hwl = l2addr_len(ifi->ifi_type); - l = l2addr_len(ifi->ifi_type); - if (hwaddr->rta_len == RTA_LENGTH(l)) - dhcpcd_handlehwaddr(ctx, ifn, RTA_DATA(hwaddr), l); + if (hwaddr != NULL && hwaddr->rta_len != RTA_LENGTH(hwl)) + hwa = NULL; + dhcpcd_handlehwaddr(ifp, ifi->ifi_type, hwa, hwl); } dhcpcd_handlecarrier(ctx, diff --git a/src/if-sun.c b/src/if-sun.c index 05d454ae..2339e236 100644 --- a/src/if-sun.c +++ b/src/if-sun.c @@ -955,7 +955,8 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) ifam->ifam_type != RTM_NEWADDR) break; memcpy(&sdl, rti_info[RTAX_IFA], sizeof(sdl)); - dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen); + dhcpcd_handlehwaddr(ifp, ifp->hwtype, + CLLADDR(&sdl), sdl.sdl_alen); break; } #ifdef INET