]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
if: support changing hardware address type on Linux
authorRoy Marples <roy@marples.name>
Thu, 23 Apr 2020 14:15:41 +0000 (14:15 +0000)
committerRoy Marples <roy@marples.name>
Thu, 23 Apr 2020 14:15:41 +0000 (14:15 +0000)
src/dhcpcd.c
src/dhcpcd.h
src/if-bsd.c
src/if-linux.c
src/if-sun.c

index 0059f47b1e492e19b6a5b70e9930a7d6703b8700..fa52fdfc396c7ee58ec6756c08cc48afa7b8c9f2 100644 (file)
@@ -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,
index 57d177e30eb2c8ee3c47106ee4ce6a1dd09f1085..77b800583a6f3a7989d39e725a076d73fbd736a2 100644 (file)
@@ -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 *);
 
index 47e3e57be7d35900095cb419e31895ea7a17cc4e..e51891128ff1a067a82350e5cd1279898d4102df 100644 (file)
@@ -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
index e3338465c03aed9ef6d3cc3022deaabb3802a6ae..8d397ebccd99f9d142a32ec4d129451b3301094d 100644 (file)
@@ -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,
index 05d454ae6ab0a9bf7cf866d2797128da8dc85627..2339e23677542d7d280488023f30c147cce437dc 100644 (file)
@@ -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