summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-04-23 14:15:41 +0000
committerRoy Marples <roy@marples.name>2020-04-23 14:15:41 +0000
commitb18431f9b8feff00fdd9d71532c38723eaf9aad8 (patch)
treebc46aa14bf60a57da0ed5b6f923cd98741377555 /src
parent3863f7bd6b991cc27ee29c764dab12b8902c61e4 (diff)
downloaddhcpcd-b18431f9b8feff00fdd9d71532c38723eaf9aad8.tar.xz
if: support changing hardware address type on Linux
Diffstat (limited to 'src')
-rw-r--r--src/dhcpcd.c20
-rw-r--r--src/dhcpcd.h3
-rw-r--r--src/if-bsd.c3
-rw-r--r--src/if-linux.c11
-rw-r--r--src/if-sun.c3
5 files changed, 22 insertions, 18 deletions
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