Mercurial > hg > dhcpcd
changeset 4442:52d9fd948974 draft
Merge branch 'master' into rbtree
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Tue, 16 Apr 2019 20:02:36 +0100 |
| parents | 11b2ea4f8036 (current diff) 116946128ea1 (diff) |
| children | ec7ded7718ae |
| files | configure src/dhcp.c src/dhcp6.c src/dhcpcd.c src/if-bsd.c src/if-linux.c src/if-options.c src/if.c src/if.h src/ipv4.c src/ipv4ll.c src/ipv6.c src/route.c src/route.h |
| diffstat | 18 files changed, 569 insertions(+), 312 deletions(-) [+] |
line wrap: on
line diff
--- a/configure Tue Apr 16 19:48:46 2019 +0100 +++ b/configure Tue Apr 16 20:02:36 2019 +0100 @@ -455,7 +455,7 @@ echo "CPPFLAGS+= -D_XPG4_2 -D__EXTENSIONS__ -DBSD_COMP" \ >>$CONFIG_MK echo "DHCPCD_SRCS+= if-sun.c" >>$CONFIG_MK - echo "LDADD+= -ldlpi" >>$CONFIG_MK + echo "LDADD+= -ldlpi -lkstat" >>$CONFIG_MK ;; *) echo "DHCPCD_SRCS+= if-bsd.c" >>$CONFIG_MK
--- a/src/dhcp.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/dhcp.c Tue Apr 16 20:02:36 2019 +0100 @@ -2468,7 +2468,8 @@ dhcp_arp_bind(struct interface *ifp) { - if (dhcp_arp_address(ifp) == 1) + if (ifp->ctx->options & DHCPCD_TEST || + dhcp_arp_address(ifp) == 1) dhcp_bind(ifp); } #endif @@ -3215,6 +3216,7 @@ state->reason = "TEST"; script_runreason(ifp, state->reason); eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS); + state->bpf_flags |= BPF_EOF; return; } eloop_timeout_delete(ifp->ctx->eloop, send_discover, ifp);
--- a/src/dhcp6.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/dhcp6.c Tue Apr 16 20:02:36 2019 +0100 @@ -797,8 +797,7 @@ m = state->new; ml = state->new_len; } - unicast = NULL; - /* Depending on state, get the unicast address */ + switch(state->state) { case DH6S_INIT: /* FALLTHROUGH */ case DH6S_DISCOVER: @@ -806,7 +805,6 @@ break; case DH6S_REQUEST: type = DHCP6_REQUEST; - unicast = dhcp6_findmoption(m, ml, D6_OPTION_UNICAST, &uni_len); break; case DH6S_CONFIRM: type = DHCP6_CONFIRM; @@ -816,20 +814,33 @@ break; case DH6S_RENEW: type = DHCP6_RENEW; - unicast = dhcp6_findmoption(m, ml, D6_OPTION_UNICAST, &uni_len); break; case DH6S_INFORM: type = DHCP6_INFORMATION_REQ; break; case DH6S_RELEASE: type = DHCP6_RELEASE; - unicast = dhcp6_findmoption(m, ml, D6_OPTION_UNICAST, &uni_len); break; default: errno = EINVAL; return -1; } + switch(state->state) { + case DH6S_REQUEST: /* FALLTHROUGH */ + case DH6S_RENEW: /* FALLTHROUGH */ + case DH6S_RELEASE: + if (has_option_mask(ifo->nomask6, D6_OPTION_UNICAST)) { + unicast = NULL; + break; + } + unicast = dhcp6_findmoption(m, ml, D6_OPTION_UNICAST, &uni_len); + break; + default: + unicast = NULL; + break; + } + /* In non master mode we listen and send from fixed addresses. * We should try and match an address we have to unicast to, * but for now this is the safest policy. */ @@ -1902,13 +1913,16 @@ dhcp6_checkstatusok(const struct interface *ifp, struct dhcp6_message *m, uint8_t *p, size_t len) { + struct dhcp6_state *state; uint8_t *opt; uint16_t opt_len, code; size_t mlen; void * (*f)(void *, size_t, uint16_t, uint16_t *), *farg; char buf[32], *sbuf; const char *status; - + logfunc_t *logfunc; + + state = D6_STATE(ifp); f = p ? dhcp6_findoption : dhcp6_findmoption; if (p) farg = p; @@ -1916,6 +1930,7 @@ farg = m; if ((opt = f(farg, len, D6_OPTION_STATUS_CODE, &opt_len)) == NULL) { //logdebugx("%s: no status", ifp->name); + state->lerror = 0; return 0; } @@ -1925,8 +1940,10 @@ } memcpy(&code, opt, sizeof(code)); code = ntohs(code); - if (code == D6_STATUS_OK) + if (code == D6_STATUS_OK) { + state->lerror = 0; return 1; + } /* Anything after the code is a message. */ opt += sizeof(code); @@ -1949,8 +1966,13 @@ status = sbuf; } - logerrx("%s: DHCPv6 REPLY: %s", ifp->name, status); + if (state->lerror == code || state->state == DH6S_INIT) + logfunc = logdebugx; + else + logfunc = logerrx; + logfunc("%s: DHCPv6 REPLY: %s", ifp->name, status); free(sbuf); + state->lerror = code; return -1; } @@ -3766,6 +3788,7 @@ gogogo: state->state = init_state; + state->lerror = 0; dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile), AF_INET6, ifp); if (ipv6_linklocal(ifp) == NULL) { @@ -3785,18 +3808,20 @@ struct dhcp6_state *state; state = D6_STATE(ifp); - if (state) { - switch (state->state) { - case DH6S_BOUND: - dhcp6_startrebind(ifp); - break; - case DH6S_INFORMED: - dhcp6_startinform(ifp); - break; - default: - dhcp6_startdiscover(ifp); - break; - } + if (state == NULL) + return; + + state->lerror = 0; + switch (state->state) { + case DH6S_BOUND: + dhcp6_startrebind(ifp); + break; + case DH6S_INFORMED: + dhcp6_startinform(ifp); + break; + default: + dhcp6_startdiscover(ifp); + break; } }
--- a/src/dhcp6.h Tue Apr 16 19:48:46 2019 +0100 +++ b/src/dhcp6.h Tue Apr 16 20:02:36 2019 +0100 @@ -206,7 +206,7 @@ /* The +3 is for the possible .pd extension for prefix delegation */ char leasefile[sizeof(LEASEFILE6) + IF_NAMESIZE + (IF_SSIDLEN * 4) +3]; const char *reason; - + uint16_t lerror; /* Last error received from DHCPv6 reply. */ struct authstate auth; };
--- a/src/dhcpcd.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/dhcpcd.c Tue Apr 16 20:02:36 2019 +0100 @@ -979,7 +979,12 @@ if ((!(ifp->ctx->options & DHCPCD_MASTER) || ifp->options->options & DHCPCD_IF_UP) && - if_up(ifp) == -1) + if_up(ifp) == -1 +#ifdef __sun + /* Interface could not yet be plumbed. */ + && errno != ENXIO +#endif + ) logerr("%s: %s", __func__, ifp->name); if (ifp->options->options & DHCPCD_LINK &&
--- a/src/duid.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/duid.c Tue Apr 16 20:02:36 2019 +0100 @@ -90,6 +90,7 @@ fclose(fp); r = len == 1 ? -1 : 0; #else + UNUSED(uuid); r = -1; errno = ENOSYS; #endif
--- a/src/if-bsd.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if-bsd.c Tue Apr 16 20:02:36 2019 +0100 @@ -99,14 +99,20 @@ #endif #ifdef INET6 -static void -ifa_scope(struct sockaddr_in6 *, unsigned int); +static void ifa_setscope(struct sockaddr_in6 *, unsigned int); +static unsigned int ifa_getscope(const struct sockaddr_in6 *); #endif struct priv { int pf_inet6_fd; }; +struct rtm +{ + struct rt_msghdr hdr; + char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; +}; + int if_init(__unused struct interface *iface) { @@ -418,9 +424,13 @@ case AF_INET6: { const struct sockaddr_in6 *sin; + unsigned int scope; struct ipv6_addr *ia; sin = (const void *)sa; + scope = ifa_getscope(sin); + if (scope != 0) + return if_findindex(ctx->ifaces, scope); if ((ia = ipv6_findmaskaddr(ctx, &sin->sin6_addr))) return ia->iface; break; @@ -458,11 +468,7 @@ if_route(unsigned char cmd, const struct rt *rt) { struct dhcpcd_ctx *ctx; - struct rtm - { - struct rt_msghdr hdr; - char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; - } rtmsg; + struct rtm rtmsg; struct rt_msghdr *rtm = &rtmsg.hdr; char *bp = rtmsg.buffer; struct sockaddr_dl sdl; @@ -579,7 +585,7 @@ if_copysa(&gateway.sa, &rt->rt_gateway); #ifdef INET6 if (gateway.sa.sa_family == AF_INET6) - ifa_scope(&gateway.sin6, rt->rt_ifp->index); + ifa_setscope(&gateway.sin6, rt->rt_ifp->index); #endif ADDSA(&gateway.sa); } @@ -607,19 +613,27 @@ { const struct sockaddr *rti_info[RTAX_MAX]; - if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) + if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) { + errno = EINVAL; return -1; + } #ifdef RTF_CLONED - if (rtm->rtm_flags & RTF_CLONED) + if (rtm->rtm_flags & RTF_CLONED) { + errno = ENOTSUP; return -1; + } #endif #ifdef RTF_LOCAL - if (rtm->rtm_flags & RTF_LOCAL) + if (rtm->rtm_flags & RTF_LOCAL) { + errno = ENOTSUP; return -1; + } #endif #ifdef RTF_BROADCAST - if (rtm->rtm_flags & RTF_BROADCAST) + if (rtm->rtm_flags & RTF_BROADCAST) { + errno = ENOTSUP; return -1; + } #endif get_addrs(rtm->rtm_addrs, rtm + 1, rti_info); @@ -756,7 +770,7 @@ #ifdef INET6 static void -ifa_scope(struct sockaddr_in6 *sin, unsigned int ifindex) +ifa_setscope(struct sockaddr_in6 *sin, unsigned int ifindex) { #ifdef __KAME__ @@ -776,6 +790,23 @@ #endif } +static unsigned int +ifa_getscope(const struct sockaddr_in6 *sin) +{ +#ifdef __KAME__ + uint16_t scope; +#endif + + if (!IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr)) + return 0; +#ifdef __KAME__ + memcpy(&scope, &sin->sin6_addr.s6_addr[2], sizeof(scope)); + return (unsigned int)ntohs(scope); +#else + return (unsigned int)sin->sin6_scope_id; +#endif +} + int if_address6(unsigned char cmd, const struct ipv6_addr *ia) { @@ -815,7 +846,7 @@ } ADDADDR(&ifa.ifra_addr, &ia->addr); - ifa_scope(&ifa.ifra_addr, ia->iface->index); + ifa_setscope(&ifa.ifra_addr, ia->iface->index); ipv6_mask(&mask, ia->prefix_len); ADDADDR(&ifa.ifra_prefixmask, &mask); @@ -892,7 +923,7 @@ strlcpy(ifr6.ifr_name, ifp->name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr.sin6_family = AF_INET6; ifr6.ifr_addr.sin6_addr = *addr; - ifa_scope(&ifr6.ifr_addr, ifp->index); + ifa_setscope(&ifr6.ifr_addr, ifp->index); priv = (struct priv *)ifp->ctx->priv; if (ioctl(priv->pf_inet6_fd, SIOCGIFAFLAG_IN6, &ifr6) != -1) flags = ifr6.ifr_ifru.ifru_flags6; @@ -913,7 +944,7 @@ strlcpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); ifr6.ifr_addr.sin6_family = AF_INET6; ifr6.ifr_addr.sin6_addr = ia->addr; - ifa_scope(&ifr6.ifr_addr, ia->iface->index); + ifa_setscope(&ifr6.ifr_addr, ia->iface->index); priv = (struct priv *)ia->iface->ctx->priv; if (ioctl(priv->pf_inet6_fd, SIOCGIFALIFETIME_IN6, &ifr6) == -1) return -1; @@ -1015,7 +1046,7 @@ } #endif - rt_recvrt(rtm->rtm_type, &rt); + rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); } static void @@ -1234,11 +1265,8 @@ int if_handlelink(struct dhcpcd_ctx *ctx) { - union { - struct rt_msghdr rtmsg; - unsigned char buf[2048]; - } u; - struct iovec iov = { .iov_base = u.buf, .iov_len = sizeof(u) }; + struct rtm rtm; + struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t len; @@ -1246,7 +1274,7 @@ if (len == -1) return -1; if (len != 0) - if_dispatch(ctx, &u.rtmsg); + if_dispatch(ctx, &rtm.hdr); return 0; }
--- a/src/if-linux.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if-linux.c Tue Apr 16 20:02:36 2019 +0100 @@ -550,7 +550,7 @@ return 0; if (if_copyrt(ctx, &rt, nlm) == 0) - rt_recvrt(cmd, &rt); + rt_recvrt(cmd, &rt, (pid_t)nlm->nlmsg_pid); return 0; }
--- a/src/if-options.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if-options.c Tue Apr 16 20:02:36 2019 +0100 @@ -208,11 +208,12 @@ {NULL, 0, NULL, '\0'} }; +static const char *default_script = SCRIPT; + static char * -add_environ(struct if_options *ifo, const char *value, int uniq) +add_environ(char ***array, const char *value, int uniq) { - char **newlist; - char **lst = ifo->environ; + char **newlist, **list = *array; size_t i = 0, l, lv; char *match = NULL, *p, *n; @@ -230,8 +231,8 @@ *p++ = '\0'; l = strlen(match); - while (lst && lst[i]) { - if (match && strncmp(lst[i], match, l) == 0) { + while (list && list[i]) { + if (match && strncmp(list[i], match, l) == 0) { if (uniq) { n = strdup(value); if (n == NULL) { @@ -239,25 +240,25 @@ free(match); return NULL; } - free(lst[i]); - lst[i] = n; + free(list[i]); + list[i] = n; } else { /* Append a space and the value to it */ - l = strlen(lst[i]); + l = strlen(list[i]); lv = strlen(p); - n = realloc(lst[i], l + lv + 2); + n = realloc(list[i], l + lv + 2); if (n == NULL) { logerr(__func__); free(match); return NULL; } - lst[i] = n; - lst[i][l] = ' '; - memcpy(lst[i] + l + 1, p, lv); - lst[i][l + lv + 1] = '\0'; + list[i] = n; + list[i][l] = ' '; + memcpy(list[i] + l + 1, p, lv); + list[i][l + lv + 1] = '\0'; } free(match); - return lst[i]; + return list[i]; } i++; } @@ -268,7 +269,7 @@ logerr(__func__); return NULL; } - newlist = reallocarray(lst, i + 2, sizeof(char *)); + newlist = reallocarray(list, i + 2, sizeof(char *)); if (newlist == NULL) { logerr(__func__); free(n); @@ -276,26 +277,31 @@ } newlist[i] = n; newlist[i + 1] = NULL; - ifo->environ = newlist; + *array = newlist; return newlist[i]; } -#define parse_string(buf, len, arg) parse_string_hwaddr(buf, len, arg, 0) +#define PARSE_STRING 0 +#define PARSE_STRING_NULL 1 +#define PARSE_HWADDR 2 +#define parse_string(a, b, c) parse_str((a), (b), (c), PARSE_STRING) +#define parse_hwaddr(a, b, c) parse_str((a), (b), (c), PARSE_HWADDR) static ssize_t -parse_string_hwaddr(char *sbuf, size_t slen, const char *str, int clid) +parse_str(char *sbuf, size_t slen, const char *str, int flags) { size_t l; - const char *p; - int i, punt_last = 0; + const char *p, *end; + int i; char c[4], cmd; + end = str + strlen(str); /* If surrounded by quotes then it's a string */ if (*str == '"') { - str++; - l = strlen(str); - p = str + l - 1; - if (*p == '"') - punt_last = 1; + p = end - 1; + if (*p == '"') { + str++; + end = p; + } } else { l = (size_t)hwaddr_aton(NULL, str); if ((ssize_t) l != -1 && l > 1) { @@ -312,13 +318,13 @@ l = 0; /* If processing a string on the clientid, first byte should be * 0 to indicate a non hardware type */ - if (clid && *str) { + if (flags == PARSE_HWADDR && *str) { if (sbuf) *sbuf++ = 0; l++; } c[3] = '\0'; - while (*str) { + while (str < end) { if (++l > slen && sbuf) { errno = ENOBUFS; return -1; @@ -386,11 +392,8 @@ str++; } } - if (punt_last) { - if (sbuf) - *--sbuf = '\0'; - l--; - } + if (flags == PARSE_STRING_NULL && sbuf) + *sbuf = '\0'; return (ssize_t)l; } @@ -655,7 +658,7 @@ int e, i, t; long l; unsigned long u; - char *p = NULL, *bp, *fp, *np, **nconf; + char *p = NULL, *bp, *fp, *np; ssize_t s; struct in_addr addr, addr2; in_addr_t *naddr; @@ -709,17 +712,33 @@ break; case 'c': ARG_REQUIRED; - free(ifo->script); - ifo->script = strdup(arg); - if (ifo->script == NULL) + if (ifo->script != default_script) + free(ifo->script); + s = parse_str(NULL, 0, arg, PARSE_STRING_NULL); + if (s == 0) { + ifo->script = NULL; + break; + } + dl = (size_t)s; + if (s == -1 || (ifo->script = malloc(dl)) == NULL) { + ifo->script = NULL; logerr(__func__); + return -1; + } + parse_str(ifo->script, dl, arg, PARSE_STRING_NULL); + if (ifo->script[0] == '\0' || + strcmp(ifo->script, "/dev/null") == 0) + { + free(ifo->script); + ifo->script = NULL; + } break; case 'd': ifo->options |= DHCPCD_DEBUG; break; case 'e': ARG_REQUIRED; - add_environ(ifo, arg, 1); + add_environ(&ifo->environ, arg, 1); break; case 'h': if (!arg) { @@ -970,7 +989,7 @@ return -1; } snprintf(p, dl, "skip_hooks=%s", arg); - add_environ(ifo, p, 0); + add_environ(&ifo->environ, p, 0); free(p); break; case 'D': @@ -1007,8 +1026,8 @@ /* Strings have a type of 0 */; ifo->clientid[1] = 0; if (arg) - s = parse_string_hwaddr((char *)ifo->clientid + 1, - CLIENTID_MAX_LEN, arg, 1); + s = parse_hwaddr((char *)ifo->clientid + 1, + CLIENTID_MAX_LEN, arg); else s = 0; if (s == -1) { @@ -1104,16 +1123,16 @@ *fp = ' '; return -1; } - if ((rt = rt_new0(ctx)) == NULL) { - *fp = ' '; + *fp = ' '; + if ((rt = rt_new0(ctx)) == NULL) return -1; - } sa_in_init(&rt->rt_dest, &addr); sa_in_init(&rt->rt_netmask, &addr2); sa_in_init(&rt->rt_gateway, &addr3); if (rb_tree_insert_node(&ifo->routes, rt) != rt) rt_free(rt); - *fp = ' '; + else + add_environ(&ifo->config, arg, 0); } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { if (parse_addr(&addr, NULL, p) == -1) return -1; @@ -1125,6 +1144,8 @@ sa_in_init(&rt->rt_gateway, &addr); if (rb_tree_insert_node(&ifo->routes, rt) != rt) rt_free(rt); + else + add_environ(&ifo->config, arg, 0); } else if (strncmp(arg, "interface_mtu=", strlen("interface_mtu=")) == 0 || strncmp(arg, "mtu=", strlen("mtu=")) == 0) @@ -1152,40 +1173,8 @@ } else ifo->req_prefix_len = 128; } - } else { - dl = 0; - if (ifo->config != NULL) { - while (ifo->config[dl] != NULL) { - if (strncmp(ifo->config[dl], arg, - (size_t)(p - arg)) == 0) - { - p = strdup(arg); - if (p == NULL) { - logerr(__func__); - return -1; - } - free(ifo->config[dl]); - ifo->config[dl] = p; - return 1; - } - dl++; - } - } - p = strdup(arg); - if (p == NULL) { - logerr(__func__); - return -1; - } - nconf = reallocarray(ifo->config, dl+2, sizeof(char *)); - if (nconf == NULL) { - logerr(__func__); - free(p); - return -1; - } - ifo->config = nconf; - ifo->config[dl] = p; - ifo->config[dl + 1] = NULL; - } + } else + add_environ(&ifo->config, arg, 1); break; case 'W': if (parse_addr(&addr, &addr2, arg) != 0) @@ -2290,6 +2279,7 @@ ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY; ifo->timeout = DEFAULT_TIMEOUT; ifo->reboot = DEFAULT_REBOOT; + ifo->script = UNCONST(default_script); ifo->metric = -1; ifo->auth.options |= DHCPCD_AUTH_REQUIRE; rb_tree_init(&ifo->routes, &rt_compare_list_ops); @@ -2639,7 +2629,8 @@ free(ifo->config); } rt_headclear0(ctx, &ifo->routes, AF_UNSPEC); - free(ifo->script); + if (ifo->script != default_script) + free(ifo->script); free(ifo->arping); free(ifo->blacklist); free(ifo->fallback);
--- a/src/if-sun.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if-sun.c Tue Apr 16 20:02:36 2019 +0100 @@ -30,6 +30,7 @@ #include <fcntl.h> #include <ifaddrs.h> #include <libdlpi.h> +#include <kstat.h> #include <stddef.h> #include <stdlib.h> #include <stropts.h> @@ -45,6 +46,7 @@ #include <netinet/udp.h> #include <sys/ioctl.h> +#include <sys/mac.h> #include <sys/pfmod.h> #include <sys/tihdr.h> #include <sys/utsname.h> @@ -63,6 +65,7 @@ #include "ipv4.h" #include "ipv6.h" #include "ipv6nd.h" +#include "logerr.h" #include "route.h" #include "sa.h" @@ -96,6 +99,12 @@ #endif }; +struct rtm +{ + struct rt_msghdr hdr; + char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; +}; + int if_init(__unused struct interface *ifp) { @@ -162,6 +171,63 @@ } int +if_carrier_os(struct interface *ifp) +{ + kstat_ctl_t *kcp; + kstat_t *ksp; + kstat_named_t *knp; + link_state_t linkstate; + + kcp = kstat_open(); + if (kcp == NULL) + goto err; + ksp = kstat_lookup(kcp, UNCONST("link"), 0, ifp->name); + if (ksp == NULL) + goto err; + if (kstat_read(kcp, ksp, NULL) == -1) + goto err; + knp = kstat_data_lookup(ksp, UNCONST("link_state")); + if (knp == NULL) + goto err; + if (knp->data_type != KSTAT_DATA_UINT32) + goto err; + linkstate = (link_state_t)knp->value.ui32; + kstat_close(kcp); + + switch (linkstate) { + case LINK_STATE_UP: + ifp->flags |= IFF_UP; + return LINK_UP; + case LINK_STATE_DOWN: + return LINK_DOWN; + default: + return LINK_UNKNOWN; + } + +err: + if (kcp != NULL) + kstat_close(kcp); + return LINK_UNKNOWN; +} + +int +if_mtu_os(const struct interface *ifp) +{ + dlpi_handle_t dh; + dlpi_info_t dlinfo; + int mtu; + + if (dlpi_open(ifp->name, &dh, 0) != DLPI_SUCCESS) + return -1; + if (dlpi_info(dh, &dlinfo, 0) == DLPI_SUCCESS) + mtu = dlinfo.di_max_sdu; + else + mtu = -1; + dlpi_close(dh); + return mtu; +} + +int if_getssid(struct interface *ifp) { @@ -448,46 +514,105 @@ } static void -if_finishrt(struct rt *rt) +if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg, + unsigned char cmd, const struct rt *rt) { + struct rt_msghdr *rtm; + char *bp = rtmsg->buffer; + socklen_t sl; + + /* WARNING: Solaris will not allow you to delete RTF_KERNEL routes. + * This includes subnet/prefix routes. */ - /* Solaris has a subnet route with the gateway - * of the owning address. - * dhcpcd has a blank gateway here to indicate a - * subnet route. */ - if (!sa_is_unspecified(&rt->rt_gateway)) { - switch(rt->rt_gateway.sa_family) { -#ifdef INET - case AF_INET: - { - struct in_addr *in; +#define ADDSA(sa) do { \ + sl = salen((sa)); \ + memcpy(bp, (sa), sl); \ + bp += RT_ROUNDUP(sl); \ + } while (/* CONSTCOND */ 0) + + memset(rtmsg, 0, sizeof(*rtmsg)); + rtm = &rtmsg->hdr; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = cmd; + rtm->rtm_seq = ++ctx->seq; + rtm->rtm_flags = rt->rt_flags; + rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; + + if (cmd == RTM_ADD || cmd == RTM_CHANGE) { + bool netmask_bcast = sa_is_allones(&rt->rt_netmask); - in = &satosin(&rt->rt_gateway)->sin_addr; - if (ipv4_iffindaddr(rt->rt_ifp, in, NULL)) - in->s_addr = INADDR_ANY; - break; - } -#endif -#ifdef INET6 - case AF_INET6: + rtm->rtm_flags |= RTF_UP; + if (!(rtm->rtm_flags & RTF_REJECT) && + !sa_is_loopback(&rt->rt_gateway) && + /* Solaris doesn't like interfaces on default routes. */ + !sa_is_unspecified(&rt->rt_dest)) { - struct in6_addr *in6; + rtm->rtm_addrs |= RTA_IFP; +#if 0 + if (!sa_is_unspecified(&rt->rt_ifa)) + rtm->rtm_addrs |= RTA_IFA; +#endif + } - in6 = &satosin6(&rt->rt_gateway)->sin6_addr; - if (ipv6_iffindaddr(rt->rt_ifp, in6, 0)) - *in6 = in6addr_any; - break; - } -#endif + if (netmask_bcast) + rtm->rtm_flags |= RTF_HOST; + else + rtm->rtm_flags |= RTF_GATEWAY; + + /* Emulate the kernel by marking address generated + * network routes non-static. */ + if (!(rt->rt_dflags & RTDF_IFA_ROUTE)) + rtm->rtm_flags |= RTF_STATIC; + + if (rt->rt_mtu != 0) { + rtm->rtm_inits |= RTV_MTU; + rtm->rtm_rmx.rmx_mtu = rt->rt_mtu; } } - /* Solaris likes to set route MTU to match - * interface MTU when adding routes. - * This confuses dhcpcd as it expects MTU to be 0 - * when no explicit MTU has been set. */ - if (rt->rt_mtu == (unsigned int)if_getmtu(rt->rt_ifp)) - rt->rt_mtu = 0; + if (!(rtm->rtm_flags & RTF_HOST)) + rtm->rtm_addrs |= RTA_NETMASK; + + ADDSA(&rt->rt_dest); + + if (sa_is_unspecified(&rt->rt_gateway)) + ADDSA(&rt->rt_ifa); + else + ADDSA(&rt->rt_gateway); + + if (rtm->rtm_addrs & RTA_NETMASK) + ADDSA(&rt->rt_netmask); + + if (rtm->rtm_addrs & RTA_IFP) { + struct sockaddr_dl sdl; + + if_linkaddr(&sdl, rt->rt_ifp); + ADDSA((struct sockaddr *)&sdl); + } + + if (rtm->rtm_addrs & RTA_IFA) { + ADDSA(&rt->rt_ifa); + rtm->rtm_addrs |= RTA_SRC; + } + if (rtm->rtm_addrs & RTA_SRC) + ADDSA(&rt->rt_ifa); + +#undef ADDSA + + rtm->rtm_msglen = (unsigned short)(bp - (char *)rtm); +} + +int +if_route(unsigned char cmd, const struct rt *rt) +{ + struct rtm rtm; + struct dhcpcd_ctx *ctx = rt->rt_ifp->ctx; + + if_route0(ctx, &rtm, cmd, rt); + + if (write(ctx->link_fd, &rtm, rtm.hdr.rtm_msglen) == -1) + return -1; + return 0; } static int @@ -509,7 +634,8 @@ if (rt->rt_flags & RTF_GATEWAY && rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) COPYSA(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); - COPYSA(&rt->rt_ifa, rti_info[RTAX_SRC]); + if (rtm->rtm_addrs & RTA_SRC) + COPYSA(&rt->rt_ifa, rti_info[RTAX_SRC]); rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; if (rtm->rtm_index) @@ -529,6 +655,98 @@ return 0; } +static struct rt * +if_route_get(struct dhcpcd_ctx *ctx, struct rt *rt) +{ + struct rtm rtm; + int s; + struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; + struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; + ssize_t len; + struct rt *rtw = rt; + + if_route0(ctx, &rtm, RTM_GET, rt); + rt = NULL; + s = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC, 0); + if (s == -1) + return NULL; + if (write(s, &rtm, rtm.hdr.rtm_msglen) == -1) + goto out; + if ((len = recvmsg(s, &msg, 0)) == -1) + goto out; + if ((size_t)len < sizeof(rtm.hdr) || len < rtm.hdr.rtm_msglen) { + errno = EINVAL; + goto out; + } + if (if_copyrt(ctx, rtw, &rtm.hdr) == -1) + goto out; + rt = rtw; + +out: + close(s); + return rt; +} + +static void +if_finishrt(struct dhcpcd_ctx *ctx, struct rt *rt) +{ + int mtu; + + /* Solaris has a subnet route with the gateway + * of the owning address. + * dhcpcd has a blank gateway here to indicate a + * subnet route. */ + if (!sa_is_unspecified(&rt->rt_dest) && + !sa_is_unspecified(&rt->rt_gateway)) + { + switch(rt->rt_gateway.sa_family) { +#ifdef INET + case AF_INET: + { + struct in_addr *in; + + in = &satosin(&rt->rt_gateway)->sin_addr; + if (ipv4_findaddr(ctx, in)) + in->s_addr = INADDR_ANY; + break; + } +#endif +#ifdef INET6 + case AF_INET6: + { + struct in6_addr *in6; + + in6 = &satosin6(&rt->rt_gateway)->sin6_addr; + if (ipv6_findaddr(ctx, in6, 0)) + *in6 = in6addr_any; + break; + } +#endif + } + } + + /* Solaris doesn't set interfaces for some routes. + * This sucks, so we need to call RTM_GET to + * work out the interface. */ + if (rt->rt_ifp == NULL) { + if (if_route_get(ctx, rt) == NULL) { + rt->rt_ifp = if_loopback(ctx); + if (rt->rt_ifp == NULL) { + logerr(__func__); + return; + } + } + } + + /* Solaris likes to set route MTU to match + * interface MTU when adding routes. + * This confuses dhcpcd as it expects MTU to be 0 + * when no explicit MTU has been set. */ + mtu = if_getmtu(rt->rt_ifp); + if (rt->rt_mtu == (unsigned int)mtu) + rt->rt_mtu = 0; +} + static int if_addrflags0(int fd, const char *ifname) { @@ -581,8 +799,8 @@ #endif if (if_copyrt(ctx, &rt, rtm) == 0) { - if_finishrt(&rt); - rt_recvrt(rtm->rtm_type, &rt); + if_finishrt(ctx, &rt); + rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid); } } @@ -714,15 +932,18 @@ { struct interface *ifp; int state; + unsigned int flags; if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL) return; - if (ifm->ifm_flags & IFF_OFFLINE || !(ifm->ifm_flags & IFF_UP)) + flags = (unsigned int)ifm->ifm_flags; + if (ifm->ifm_flags & IFF_OFFLINE) state = LINK_DOWN; - else + else { state = LINK_UP; - dhcpcd_handlecarrier(ctx, state, - (unsigned int)ifm->ifm_flags, ifp->name); + flags |= IFF_UP; + } + dhcpcd_handlecarrier(ctx, state, flags, ifp->name); } static void @@ -752,18 +973,15 @@ int if_handlelink(struct dhcpcd_ctx *ctx) { - union { - struct rt_msghdr rtmsg; - unsigned char buf[2048]; - } u; - struct iovec iov = { .iov_base = u.buf, .iov_len = sizeof(u) }; + struct rtm rtm; + struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t len; if ((len = recvmsg(ctx->link_fd, &msg, 0)) == -1) return -1; if (len != 0) - if_dispatch(ctx, &u.rtmsg); + if_dispatch(ctx, &rtm.hdr); return 0; } @@ -810,6 +1028,7 @@ if (ioctl(fd, SIOCSLIFFLAGS, &lifr) == -1) return -1; } + return 0; } @@ -838,15 +1057,20 @@ static int if_plumbif(const struct dhcpcd_ctx *ctx, int af, const char *ifname) { - dlpi_handle_t dh; - int fd, af_fd, mux_fd, retval; + dlpi_handle_t dh, dh_arp = NULL; + int fd, af_fd, mux_fd, arp_fd = -1, mux_id, retval; + uint64_t flags; struct lifreq lifr; const char *udp_dev; + struct strioctl ioc; + struct if_spec spec; - memset(&lifr, 0, sizeof(lifr)); + if (if_nametospec(ifname, &spec) == -1) + return -1; + switch (af) { case AF_INET: - lifr.lifr_flags = IFF_IPV4; + flags = IFF_IPV4; af_fd = ctx->pf_inet_fd; udp_dev = UDP_DEV_NAME; break; @@ -855,7 +1079,7 @@ struct priv *priv; /* We will take care of setting the link local address. */ - lifr.lifr_flags = IFF_IPV6 | IFF_NOLINKLOCAL; + flags = IFF_IPV6 | IFF_NOLINKLOCAL; priv = (struct priv *)ctx->priv; af_fd = priv->pf_inet6_fd; udp_dev = UDP6_DEV_NAME; @@ -876,13 +1100,17 @@ mux_fd = -1; if (ioctl(fd, I_PUSH, IP_MOD_NAME) == -1) goto out; + memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); + lifr.lifr_ppa = spec.ppa; + lifr.lifr_flags = flags; if (ioctl(fd, SIOCSLIFNAME, &lifr) == -1) goto out; /* Get full flags. */ if (ioctl(af_fd, SIOCGLIFFLAGS, &lifr) == -1) goto out; + flags = lifr.lifr_flags; /* Open UDP as a multiplexor to PLINK the interface stream. * UDP is used because STREAMS will not let you PLINK a driver @@ -894,20 +1122,49 @@ ; if (errno != EINVAL) goto out; + if(ioctl(mux_fd, I_PUSH, ARP_MOD_NAME) == -1) + goto out; - if (lifr.lifr_flags & IFF_IPV4 && !(lifr.lifr_flags & IFF_NOARP)) { - if (ioctl(mux_fd, I_PUSH, ARP_MOD_NAME) == -1) + if (flags & (IFF_NOARP | IFF_IPV6)) { + /* PLINK the interface stream so it persists. */ + if (ioctl(mux_fd, I_PLINK, fd) == -1) goto out; + goto done; } - /* PLINK the interface stream so it persists. */ - if (ioctl(mux_fd, I_PLINK, fd) == -1) + if (dlpi_open(ifname, &dh_arp, DLPI_NOATTACH) != DLPI_SUCCESS) + goto out; + arp_fd = dlpi_fd(dh_arp); + if (ioctl(arp_fd, I_PUSH, ARP_MOD_NAME) == -1) goto out; + memset(&lifr, 0, sizeof(lifr)); + strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); + lifr.lifr_ppa = spec.ppa; + lifr.lifr_flags = flags; + memset(&ioc, 0, sizeof(ioc)); + ioc.ic_cmd = SIOCSLIFNAME; + ioc.ic_dp = (char *)&lifr; + ioc.ic_len = sizeof(lifr); + if (ioctl(arp_fd, I_STR, &ioc) == -1) + goto out; + + /* PLINK the interface stream so it persists. */ + mux_id = ioctl(mux_fd, I_PLINK, fd); + if (mux_id == -1) + goto out; + if (ioctl(mux_fd, I_PLINK, arp_fd) == -1) { + ioctl(mux_fd, I_PUNLINK, mux_id); + goto out; + } + +done: retval = 0; out: dlpi_close(dh); + if (dh_arp != NULL) + dlpi_close(dh_arp); if (mux_fd != -1) close(mux_fd); return retval; @@ -963,102 +1220,6 @@ return if_unplumbif(ctx, af, ifname); } -int -if_route(unsigned char cmd, const struct rt *rt) -{ - struct dhcpcd_ctx *ctx; - struct rtm - { - struct rt_msghdr hdr; - char buffer[sizeof(struct sockaddr_storage) * RTAX_MAX]; - } rtmsg; - struct rt_msghdr *rtm; - char *bp = rtmsg.buffer; - size_t l; - - /* WARNING: Solaris will not allow you to delete RTF_KERNEL routes. - * This includes subnet/prefix routes. */ - - ctx = rt->rt_ifp->ctx; - -#define ADDSA(sa) do { \ - l = RT_ROUNDUP(salen((sa))); \ - memcpy(bp, (sa), l); \ - bp += l; \ - } while (/* CONSTCOND */ 0) - - memset(&rtmsg, 0, sizeof(rtmsg)); - rtm = &rtmsg.hdr; - rtm->rtm_version = RTM_VERSION; - rtm->rtm_type = cmd; - rtm->rtm_seq = ++ctx->seq; - rtm->rtm_flags = rt->rt_flags; - rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; - - if (cmd == RTM_ADD || cmd == RTM_CHANGE) { - bool netmask_bcast = sa_is_allones(&rt->rt_netmask); - - rtm->rtm_flags |= RTF_UP; - if (!(rtm->rtm_flags & RTF_REJECT) && - !sa_is_loopback(&rt->rt_gateway)) - { - rtm->rtm_addrs |= RTA_IFP; - if (!sa_is_unspecified(&rt->rt_ifa)) - rtm->rtm_addrs |= RTA_IFA; - } - if (netmask_bcast) - rtm->rtm_flags |= RTF_HOST; - else - rtm->rtm_flags |= RTF_GATEWAY; - - /* Emulate the kernel by marking address generated - * network routes non-static. */ - if (!(rt->rt_dflags & RTDF_IFA_ROUTE)) - rtm->rtm_flags |= RTF_STATIC; - - if (rt->rt_mtu != 0) { - rtm->rtm_inits |= RTV_MTU; - rtm->rtm_rmx.rmx_mtu = rt->rt_mtu; - } - } - - ADDSA(&rt->rt_dest); - - if (sa_is_unspecified(&rt->rt_gateway)) - ADDSA(&rt->rt_ifa); - else - ADDSA(&rt->rt_gateway); - - if (rtm->rtm_addrs & RTA_NETMASK) - ADDSA(&rt->rt_netmask); - - if (rtm->rtm_addrs & RTA_IFP) { - struct sockaddr_dl sdl; - - if_linkaddr(&sdl, rt->rt_ifp); - ADDSA((struct sockaddr *)&sdl); - } - -/* This no workie :/ */ -#if 1 - /* route(1M) says RTA_IFA is accepted but ignored - * it's unclear how RTA_SRC is different. */ - if (rtm->rtm_addrs & RTA_IFA) { - rtm->rtm_addrs &= ~RTA_IFA; - rtm->rtm_addrs |= RTA_SRC; - } - if (rtm->rtm_addrs & RTA_SRC) - ADDSA(&rt->rt_ifa); -#endif - -#undef ADDSA - - rtm->rtm_msglen = (unsigned short)(bp - (char *)rtm); - if (write(ctx->link_fd, rtm, rtm->rtm_msglen) == -1) - return -1; - return 0; -} - #ifdef INET static int if_walkrt(struct dhcpcd_ctx *ctx, char *data, size_t len) @@ -1087,6 +1248,7 @@ default: break; } + memset(&rt, 0, sizeof(rt)); rt.rt_dflags |= RTDF_INIT; in.s_addr = re->ipRouteDest; @@ -1099,13 +1261,10 @@ in.s_addr = re->ipRouteInfo.re_src_addr; sa_in_init(&rt.rt_ifa, &in); rt.rt_mtu = re->ipRouteInfo.re_max_frag; - if_octetstr(ifname, &re->ipRouteIfIndex, sizeof(ifname)); rt.rt_ifp = if_find(ctx->ifaces, ifname); - if (rt.rt_ifp != NULL) { - if_finishrt(&rt); - rt_recvrt(RTM_ADD, &rt); - } + if_finishrt(ctx, &rt); + rt_recvrt(RTM_ADD, &rt, 0); } while (++re < e); return 0; } @@ -1140,6 +1299,7 @@ default: break; } + memset(&rt, 0, sizeof(rt)); rt.rt_dflags |= RTDF_INIT; sa_in6_init(&rt.rt_dest, &re->ipv6RouteDest); @@ -1147,13 +1307,10 @@ sa_in6_init(&rt.rt_netmask, &in6); sa_in6_init(&rt.rt_gateway, &re->ipv6RouteNextHop); rt.rt_mtu = re->ipv6RouteInfo.re_max_frag; - if_octetstr(ifname, &re->ipv6RouteIfIndex, sizeof(ifname)); rt.rt_ifp = if_find(ctx->ifaces, ifname); - if (rt.rt_ifp != NULL) { - if_finishrt(&rt); - rt_recvrt(RTM_ADD, &rt); - } + if_finishrt(ctx, &rt); + rt_recvrt(RTM_ADD, &rt, 0); } while (++re < e); return 0; } @@ -1314,6 +1471,9 @@ return -1; } + /* We need to update the index now */ + ia->iface->index = if_nametoindex(ia->alias); + sin_addr = (struct sockaddr_in *)&ss_addr; sin_addr->sin_family = AF_INET; sin_addr->sin_addr = ia->addr; @@ -1405,4 +1565,11 @@ { } + +int +ip6_forwarding(__unused const char *ifname) +{ + + return 1; +} #endif
--- a/src/if.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if.c Tue Apr 16 20:02:36 2019 +0100 @@ -136,9 +136,15 @@ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); - if (ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr) == -1) + r = ioctl(ifp->ctx->pf_inet_fd, SIOCGIFFLAGS, &ifr); + if (r != -1) + ifp->flags = (unsigned int)ifr.ifr_flags; + +#ifdef __sun + return if_carrier_os(ifp); +#else + if (r == -1) return LINK_UNKNOWN; - ifp->flags = (unsigned int)ifr.ifr_flags; #ifdef SIOCGIFMEDIA memset(&ifmr, 0, sizeof(ifmr)); @@ -155,6 +161,7 @@ #else r = ifr.ifr_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN; #endif +#endif /* __sun */ return r; } @@ -711,6 +718,11 @@ int r; struct ifreq ifr; +#ifdef __sun + if (mtu == 0) + return if_mtu_os(ifp); +#endif + memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); ifr.ifr_mtu = mtu; @@ -720,6 +732,17 @@ return ifr.ifr_mtu; } +#ifdef ALIAS_ADDR +int +if_makealias(char *alias, size_t alias_len, const char *ifname, int lun) +{ + + if (lun == 0) + return strlcpy(alias, ifname, alias_len); + return snprintf(alias, alias_len, "%s:%u", ifname, lun); +} +#endif + struct interface * if_findifpfromcmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, int *hoplimit) {
--- a/src/if.h Tue Apr 16 19:48:46 2019 +0100 +++ b/src/if.h Tue Apr 16 20:02:36 2019 +0100 @@ -128,6 +128,13 @@ #define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu)) int if_carrier(struct interface *); +#ifdef ALIAS_ADDR +int if_makealias(char *, size_t, const char *, int); +#endif + +int if_carrier_os(struct interface *); +int if_mtu_os(const struct interface *); + /* * Helper to decode an interface name of bge0:1 to * devname = bge0, drvname = bge0, ppa = 0, lun = 1.
--- a/src/ipv4.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/ipv4.c Tue Apr 16 20:02:36 2019 +0100 @@ -571,10 +571,12 @@ lun = 0; state = IPV4_STATE(ia->iface); find_lun: - if (lun == 0) - strlcpy(alias, ia->iface->name, sizeof(alias)); - else - snprintf(alias, sizeof(alias), "%s:%u", ia->iface->name, lun); + if (if_makealias(alias, IF_NAMESIZE, ia->iface->name, lun) >= + IF_NAMESIZE) + { + errno = ENOMEM; + return -1; + } TAILQ_FOREACH(iap, &state->addrs, next) { if (iap->alias[0] != '\0' && iap->addr.s_addr == INADDR_ANY) { /* No address assigned? Lets use it. */
--- a/src/ipv4ll.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/ipv4ll.c Tue Apr 16 20:02:36 2019 +0100 @@ -310,6 +310,7 @@ ipv4_deladdr(state->addr, 1); state->down = 1; state->addr = NULL; + rt_build(ifp->ctx, AF_INET); script_runreason(ifp, "IPV4LL"); }
--- a/src/ipv6.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/ipv6.c Tue Apr 16 20:02:36 2019 +0100 @@ -624,6 +624,10 @@ uint32_t pltime, vltime; bool vltime_was_zero; __printflike(1, 2) void (*logfunc)(const char *, ...); +#ifdef __sun + struct ipv6_state *state; + struct ipv6_addr *ia2; +#endif /* Remember the interface of the address. */ ifp = ia->iface; @@ -759,13 +763,13 @@ } #ifdef ALIAS_ADDR -/* Find the next logical aliase address we can use. */ +/* Find the next logical alias address we can use. */ static int ipv6_aliasaddr(struct ipv6_addr *ia, struct ipv6_addr **repl) { struct ipv6_state *state; struct ipv6_addr *iap; - unsigned int unit; + unsigned int lun; char alias[IF_NAMESIZE]; if (ia->alias[0] != '\0') @@ -784,12 +788,14 @@ } } - unit = 0; + lun = 0; find_unit: - if (unit == 0) - strlcpy(alias, ia->iface->name, sizeof(alias)); - else - snprintf(alias, sizeof(alias), "%s:%u", ia->iface->name, unit); + if (if_makealias(alias, IF_NAMESIZE, ia->iface->name, lun) >= + IF_NAMESIZE) + { + errno = ENOMEM; + return -1; + } TAILQ_FOREACH(iap, &state->addrs, next) { if (iap->alias[0] == '\0') continue; @@ -805,11 +811,11 @@ } if (iap != NULL) { - if (unit == UINT_MAX) { + if (lun == UINT_MAX) { errno = ERANGE; return -1; } - unit++; + lun++; goto find_unit; }
--- a/src/route.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/route.c Tue Apr 16 20:02:36 2019 +0100 @@ -366,7 +366,7 @@ /* If something other than dhcpcd removes a route, * we need to remove it from our internal table. */ void -rt_recvrt(int cmd, const struct rt *rt) +rt_recvrt(int cmd, const struct rt *rt, pid_t pid) { struct dhcpcd_ctx *ctx; struct rt *f; @@ -381,8 +381,11 @@ case RTM_DELETE: f = rb_tree_find_node(&ctx->routes, rt); if (f != NULL) { + char buf[32]; + rb_tree_remove_node(&ctx->routes, f); - rt_desc("deleted", f); + snprintf(buf, sizeof(buf), "pid %d deleted", pid); + rt_desc(buf, f); rt_free(f); } break;
--- a/src/route.h Tue Apr 16 19:48:46 2019 +0100 +++ b/src/route.h Tue Apr 16 20:02:36 2019 +0100 @@ -106,7 +106,7 @@ struct rt * rt_new0(struct dhcpcd_ctx *); void rt_setif(struct rt *, struct interface *); struct rt * rt_new(struct interface *); -void rt_recvrt(int, const struct rt *); +void rt_recvrt(int, const struct rt *, pid_t); void rt_build(struct dhcpcd_ctx *, int); #endif
--- a/src/script.c Tue Apr 16 19:48:46 2019 +0100 +++ b/src/script.c Tue Apr 16 20:02:36 2019 +0100 @@ -704,9 +704,7 @@ int status = 0; struct fd_list *fd; - if (ifp->options->script && - (ifp->options->script[0] == '\0' || - strcmp(ifp->options->script, "/dev/null") == 0) && + if (ifp->options->script == NULL && TAILQ_FIRST(&ifp->ctx->control_fds) == NULL) return 0; @@ -717,12 +715,10 @@ return -1; } - if (ifp->options->script && - (ifp->options->script[0] == '\0' || - strcmp(ifp->options->script, "/dev/null") == 0)) + if (ifp->options->script == NULL) goto send_listeners; - argv[0] = ifp->options->script ? ifp->options->script : UNCONST(SCRIPT); + argv[0] = ifp->options->script; argv[1] = NULL; logdebugx("%s: executing `%s' %s", ifp->name, argv[0], reason);
