diff --git a/src/if-bsd.c b/src/if-bsd.c index 5e811eed..68a2ccad 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -138,6 +138,13 @@ os_init(void) int if_init(__unused struct interface *iface) +{ + /* No extra init needed. */ + return 0; +} + +int +if_init_os(__unused struct interface *iface) { /* BSD promotes secondary address by default */ return 0; diff --git a/src/if-linux.c b/src/if-linux.c index 82de6ec6..c5278a52 100644 --- a/src/if-linux.c +++ b/src/if-linux.c @@ -299,6 +299,33 @@ if_writepathuint(struct dhcpcd_ctx *ctx, const char *path, unsigned int val) int if_init(struct interface *ifp) +{ + struct dhcpcd_ctx *ctx = ifp->ctx; + struct ifreq ifr = { .ifr_flags = 0 }; + int err = 0; + + if (ifp->index != 0) + return 0; + + /* This is a huge bug in getifaddrs(3) as there + * is no reason why this can't be returned in + * ifa_addr. */ + strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); + if (ioctl(ctx->pf_inet_fd, SIOCGIFHWADDR, &ifr) == -1) { + logerr("%s: SIOCGIFHWADDR", ifp->name); + err = -1; + } else + ifp->hwtype = ifr.ifr_hwaddr.sa_family; + if (ioctl(ctx->pf_inet_fd, SIOCGIFINDEX, &ifr) == -1) { + logerr("%s: SIOCGIFINDEX", ifp->name); + err = -1; + } else + ifp->index = (unsigned int)ifr.ifr_ifindex; + return err; +} + +int +if_init_os(struct interface *ifp) { char path[sizeof(PROC_PROMOTE) + IF_NAMESIZE]; int n; diff --git a/src/if-sun.c b/src/if-sun.c index da15d706..818331cf 100644 --- a/src/if-sun.c +++ b/src/if-sun.c @@ -116,6 +116,12 @@ os_init(void) int if_init(struct interface *ifp) +{ + return 0; +} + +int +if_init_os(struct interface *ifp) { #ifdef INET if (if_plumb(RTM_NEWADDR, ifp->ctx, AF_INET, ifp->name) == -1 && diff --git a/src/if.c b/src/if.c index d1b4a02c..af3320c4 100644 --- a/src/if.c +++ b/src/if.c @@ -400,15 +400,17 @@ if_valid_hwaddr(const uint8_t *hwaddr, size_t hwlen) return false; } -#if defined(AF_PACKET) && !defined(AF_LINK) +#ifndef AF_LINK static unsigned int if_check_arphrd(struct interface *ifp, unsigned int active, bool if_noconf) { switch (ifp->hwtype) { +#ifdef ARPHRD_NONE + case ARPHRD_NONE: /* FALLTHROUGH */ +#endif case ARPHRD_ETHER: /* FALLTHROUGH */ case ARPHRD_IEEE1394: /* FALLTHROUGH */ case ARPHRD_INFINIBAND: /* FALLTHROUGH */ - case ARPHRD_NONE: /* FALLTHROUGH */ break; case ARPHRD_LOOPBACK: case ARPHRD_PPP: @@ -659,32 +661,22 @@ if_discover(struct dhcpcd_ctx *ctx, struct ifaddrs **ifaddrs, int argc, ifp->hwlen = sll->sll_halen; if (ifp->hwlen != 0) memcpy(ifp->hwaddr, sll->sll_addr, ifp->hwlen); - active = if_check_arphrd(ifp, active, if_noconf); #endif } -#ifdef __linux__ - else { - struct ifreq ifr = { .ifr_flags = 0 }; - - /* This is a huge bug in getifaddrs(3) as there - * is no reason why this can't be returned in - * ifa_addr. */ - strlcpy(ifr.ifr_name, ifa->ifa_name, - sizeof(ifr.ifr_name)); - if (ioctl(ctx->pf_inet_fd, SIOCGIFHWADDR, &ifr) == -1) - logerr("%s: SIOCGIFHWADDR", ifa->ifa_name); - ifp->hwtype = ifr.ifr_hwaddr.sa_family; - if (ioctl(ctx->pf_inet_fd, SIOCGIFINDEX, &ifr) == -1) - logerr("%s: SIOCGIFINDEX", ifa->ifa_name); - ifp->index = (unsigned int)ifr.ifr_ifindex; - if_check_arphrd(ifp, active, if_noconf); + + if (if_init(ifp) == -1) { + logerr("%s: if_init", ifp->name); + if_free(ifp); + continue; } +#ifndef AF_LINK + active = if_check_arphrd(ifp, active, if_noconf); #endif if (!(ctx->options & (DHCPCD_DUMPLEASE | DHCPCD_TEST))) { /* Handle any platform init for the interface */ - if (active != IF_INACTIVE && if_init(ifp) == -1) { - logerr("%s: if_init", ifp->name); + if (active != IF_INACTIVE && if_init_os(ifp) == -1) { + logerr("%s: if_init_os", ifp->name); if_free(ifp); continue; } diff --git a/src/if.h b/src/if.h index f4e14bd0..c9a14b80 100644 --- a/src/if.h +++ b/src/if.h @@ -206,8 +206,9 @@ int if_nametospec(const char *, struct if_spec *); /* The below functions are provided by if-KERNEL.c */ int os_init(void); -int if_conf(struct interface *); -int if_init(struct interface *); +int if_init(struct interface *); /* init interface from kernel */ +int if_init_os(struct interface *); /* init kernel from interface */ +int if_conf(struct interface *); /* finish configuration from kernel */ int if_getssid(struct interface *); int if_ignoregroup(int, const char *); bool if_ignore(struct dhcpcd_ctx *, const char *);