From: Roy Marples Date: Thu, 19 May 2016 20:27:07 +0000 (+0000) Subject: Spit handlelink into smaller functions to increase read-ability. X-Git-Tag: v6.11.1~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6f10046d86fa5de5b4a69d45795197cdd47a84d;p=thirdparty%2Fdhcpcd.git Spit handlelink into smaller functions to increase read-ability. --- diff --git a/dhcpcd.c b/dhcpcd.c index 31204d95..aaf3ce20 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -1086,7 +1086,7 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname) void dhcpcd_handlehwaddr(struct dhcpcd_ctx *ctx, const char *ifname, - const uint8_t *hwaddr, uint8_t hwlen) + const void *hwaddr, uint8_t hwlen) { struct interface *ifp; char buf[sizeof(ifp->hwaddr) * 3]; diff --git a/dhcpcd.h b/dhcpcd.h index 0ad5c283..f286e309 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -198,7 +198,7 @@ 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 unsigned char *, uint8_t); + const void *, uint8_t); void dhcpcd_dropinterface(struct interface *, const char *); int dhcpcd_selectprofile(struct interface *, const char *); diff --git a/if-bsd.c b/if-bsd.c index 0d5d1bd3..959bae49 100644 --- a/if-bsd.c +++ b/if-bsd.c @@ -102,7 +102,7 @@ } while (0) #ifndef CLLADDR -# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) +# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen) #endif struct priv { @@ -263,7 +263,7 @@ if_vimaster(const struct dhcpcd_ctx *ctx, const char *ifname) } static void -get_addrs(int type, char *cp, struct sockaddr **sa) +get_addrs(int type, uint8_t *cp, struct sockaddr **sa) { int i; @@ -558,11 +558,11 @@ if_address(unsigned char cmd, const struct ipv4_addr *ia) static int if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) { - char *cp; + uint8_t *ap; struct sockaddr *sa, *rti_info[RTAX_MAX]; - cp = (void *)(rtm + 1); - sa = (void *)cp; + ap = (void *)(rtm + 1); + sa = (void *)ap; if (sa->sa_family != AF_INET) return -1; if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) @@ -580,7 +580,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct rt_msghdr *rtm) return -1; #endif - get_addrs(rtm->rtm_addrs, cp, rti_info); + get_addrs(rtm->rtm_addrs, ap, rti_info); memset(rt, 0, sizeof(*rt)); rt->flags = (unsigned int)rtm->rtm_flags; COPYOUT(rt->dest, rti_info[RTAX_DST]); @@ -910,11 +910,11 @@ if_address6(unsigned char cmd, const struct ipv6_addr *ia) static int if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm) { - char *cp; + uint8_t *ap; struct sockaddr *sa, *rti_info[RTAX_MAX]; - cp = (void *)(rtm + 1); - sa = (void *)cp; + ap = (void *)(rtm + 1); + sa = (void *)ap; if (sa->sa_family != AF_INET6) return -1; if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) @@ -931,7 +931,7 @@ if_copyrt6(struct dhcpcd_ctx *ctx, struct rt6 *rt, struct rt_msghdr *rtm) return -1; #endif - get_addrs(rtm->rtm_addrs, cp, rti_info); + get_addrs(rtm->rtm_addrs, ap, rti_info); memset(rt, 0, sizeof(*rt)); rt->flags = (unsigned int)rtm->rtm_flags; COPYOUT6(rt->dest, rti_info[RTAX_DST]); @@ -1226,215 +1226,246 @@ if_getlifetime6(struct ipv6_addr *ia) } #endif -int -if_handlelink(struct dhcpcd_ctx *ctx) +static void +if_announce(struct dhcpcd_ctx *ctx, struct if_announcemsghdr *ifan) +{ + + switch(ifan->ifan_what) { + case IFAN_ARRIVAL: + dhcpcd_handleinterface(ctx, 1, ifan->ifan_name); + break; + case IFAN_DEPARTURE: + dhcpcd_handleinterface(ctx, -1, ifan->ifan_name); + break; + } +} + +static void +if_ifinfo(struct dhcpcd_ctx *ctx, struct if_msghdr *ifm) { - /* route and ifwatchd like a msg buf size of 2048 */ - char msg[2048], *p, *e, *cp; - ssize_t bytes; - struct rt_msghdr *rtm; - struct if_announcemsghdr *ifan; - struct if_msghdr *ifm; - struct ifa_msghdr *ifam; - struct sockaddr *sa, *rti_info[RTAX_MAX]; - int len; - struct sockaddr_dl sdl; struct interface *ifp; + int state; + + if ((ifp = if_findindex(ctx->ifaces, ifm->ifm_index)) == NULL) + return; + switch (ifm->ifm_data.ifi_link_state) { + case LINK_STATE_DOWN: + state = LINK_DOWN; + break; + case LINK_STATE_UP: + state = LINK_UP; + break; + default: + /* handle_carrier will re-load the interface flags and check for + * IFF_RUNNING as some drivers that don't handle link state also + * don't set IFF_RUNNING when this routing message is generated. + * As such, it is a race ...*/ + state = LINK_UNKNOWN; + break; + } + dhcpcd_handlecarrier(ctx, state, + (unsigned int)ifm->ifm_flags, ifp->name); +} + +static void +if_rtm(struct dhcpcd_ctx *ctx, struct rt_msghdr *rtm) +{ + struct sockaddr *sa; + + /* Ignore messages generated by us */ + if (rtm->rtm_pid == getpid()) { + ctx->options &= ~DHCPCD_RTM_PPID; + return; + } + + /* Ignore messages sent by the parent after forking */ + if ((ctx->options & + (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) == + (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) && + rtm->rtm_pid == ctx->ppid) + { + /* If this is the last successful message sent, + * clear the check flag as it's possible another + * process could re-use the same pid and also + * manipulate therouting table. */ + if (rtm->rtm_seq == ctx->pseq) + ctx->options &= ~DHCPCD_RTM_PPID; + return; + } + + sa = (void *)(rtm + 1); + switch (sa->sa_family) { #ifdef INET - struct rt rt; + case AF_INET: + { + struct rt rt; + + if (if_copyrt(ctx, &rt, rtm) == 0) + ipv4_handlert(ctx, rtm->rtm_type, &rt, 0); + break; + } #endif #ifdef INET6 - struct rt6 rt6; - struct in6_addr ia6, mask6; - struct sockaddr_in6 *sin6; -#endif -#if (defined(INET) && defined(IN_IFF_TENTATIVE)) || defined(INET6) - int ifa_flags; -#endif + case AF_INET6: + { + struct rt6 rt6; - if ((bytes = read(ctx->link_fd, msg, sizeof(msg))) == -1) - return -1; - e = msg + bytes; - for (p = msg; p < e; p += rtm->rtm_msglen) { - rtm = (void *)p; - switch(rtm->rtm_type) { -#ifdef RTM_IFANNOUNCE - case RTM_IFANNOUNCE: - ifan = (void *)p; - switch(ifan->ifan_what) { - case IFAN_ARRIVAL: - dhcpcd_handleinterface(ctx, 1, - ifan->ifan_name); - break; - case IFAN_DEPARTURE: - dhcpcd_handleinterface(ctx, -1, - ifan->ifan_name); - break; - } + if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) break; -#endif - case RTM_IFINFO: - ifm = (void *)p; - ifp = if_findindex(ctx->ifaces, ifm->ifm_index); - if (ifp == NULL) - break; - switch (ifm->ifm_data.ifi_link_state) { - case LINK_STATE_DOWN: - len = LINK_DOWN; - break; - case LINK_STATE_UP: - len = LINK_UP; - break; - default: - /* handle_carrier will re-load - * the interface flags and check for - * IFF_RUNNING as some drivers that - * don't handle link state also don't - * set IFF_RUNNING when this routing - * message is generated. - * As such, it is a race ...*/ - len = LINK_UNKNOWN; - break; - } - dhcpcd_handlecarrier(ctx, len, - (unsigned int)ifm->ifm_flags, ifp->name); + /* + * BSD announces host routes. + * As such, we should be notified of reachability by its + * existance with a hardware address. + */ + if (rtm->rtm_flags & (RTF_HOST)) { + uint8_t *ap; + struct sockaddr *rti_info[RTAX_MAX]; + struct in6_addr dst6; + struct sockaddr_dl sdl; + + ap = (void *)(rtm + 1); + get_addrs(rtm->rtm_addrs, ap, rti_info); + COPYOUT6(dst6, rti_info[RTAX_DST]); + DESCOPE(&dst6); + if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) + memcpy(&sdl, rti_info[RTAX_GATEWAY], + sizeof(sdl)); + else + sdl.sdl_alen = 0; + ipv6nd_neighbour(ctx, &dst6, + rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ? + IPV6ND_REACHABLE : 0); break; - case RTM_ADD: - case RTM_CHANGE: - case RTM_DELETE: - /* Ignore messages generated by us */ - if (rtm->rtm_pid == getpid()) { - ctx->options &= ~DHCPCD_RTM_PPID; - continue; - } - /* Ignore messages sent by the parent after forking */ - if ((ctx->options & - (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED)) == - (DHCPCD_RTM_PPID | DHCPCD_DAEMONISED) && - rtm->rtm_pid == ctx->ppid) - { - /* If this is the last successful message sent, - * clear the check flag as it's possible another - * process could re-use the same pid and also - * manipulate therouting table. */ - if (rtm->rtm_seq == ctx->pseq) - ctx->options &= ~DHCPCD_RTM_PPID; - continue; - } - cp = (void *)(rtm + 1); - sa = (void *)cp; - switch (sa->sa_family) { -#ifdef INET - case AF_INET: - if (if_copyrt(ctx, &rt, rtm) == 0) - ipv4_handlert(ctx, rtm->rtm_type,&rt,0); - break; -#endif -#ifdef INET6 - case AF_INET6: - if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY)) - break; - /* - * BSD caches host routes in the - * routing table. - * As such, we should be notified of - * reachability by its existance - * with a hardware address - */ - if (rtm->rtm_flags & (RTF_HOST)) { - get_addrs(rtm->rtm_addrs, cp, rti_info); - COPYOUT6(ia6, rti_info[RTAX_DST]); - DESCOPE(&ia6); - if (rti_info[RTAX_GATEWAY]->sa_family - == AF_LINK) - memcpy(&sdl, - rti_info[RTAX_GATEWAY], - sizeof(sdl)); - else - sdl.sdl_alen = 0; - ipv6nd_neighbour(ctx, &ia6, - rtm->rtm_type != RTM_DELETE && - sdl.sdl_alen ? - IPV6ND_REACHABLE : 0); - break; - } + } - if (if_copyrt6(ctx, &rt6, rtm) == 0) - ipv6_handlert(ctx, rtm->rtm_type, &rt6); - break; + if (if_copyrt6(ctx, &rt6, rtm) == 0) + ipv6_handlert(ctx, rtm->rtm_type, &rt6); + break; + } #endif - } - break; -#ifdef RTM_CHGADDR - case RTM_CHGADDR: /* FALLTHROUGH */ -#endif - case RTM_DELADDR: /* FALLTHROUGH */ - case RTM_NEWADDR: - /* XXX We have no way of knowing who generated these - * messages wich truely sucks because we want to - * avoid listening to our own delete messages. */ - ifam = (void *)p; - ifp = if_findindex(ctx->ifaces, ifam->ifam_index); - if (ifp == NULL) - break; - cp = (void *)(ifam + 1); - get_addrs(ifam->ifam_addrs, cp, rti_info); - if (rti_info[RTAX_IFA] == NULL) - break; - switch (rti_info[RTAX_IFA]->sa_family) { - case AF_LINK: + } +} + +static void +if_ifa(struct dhcpcd_ctx *ctx, struct ifa_msghdr *ifam) +{ + struct interface *ifp; + uint8_t *cp; + struct sockaddr *rti_info[RTAX_MAX]; + + /* XXX We have no way of knowing who generated these + * messages wich truely sucks because we want to + * avoid listening to our own delete messages. */ + if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) + return; + cp = (void *)(ifam + 1); + get_addrs(ifam->ifam_addrs, cp, rti_info); + if (rti_info[RTAX_IFA] == NULL) + return; + switch (rti_info[RTAX_IFA]->sa_family) { + case AF_LINK: + { + struct sockaddr_dl sdl; + #ifdef RTM_CHGADDR - if (rtm->rtm_type != RTM_CHGADDR) - break; + if (ifam->ifam_type != RTM_CHGADDR) + break; #else - if (rtm->rtm_type != RTM_NEWADDR) - break; -#endif - memcpy(&sdl, rti_info[RTAX_IFA], - rti_info[RTAX_IFA]->sa_len); - dhcpcd_handlehwaddr(ctx, ifp->name, - (const unsigned char*)CLLADDR(&sdl), - sdl.sdl_alen); - break; + if (ifam->ifam_type != RTM_NEWADDR) + break; +#endif + memcpy(&sdl, rti_info[RTAX_IFA], rti_info[RTAX_IFA]->sa_len); + dhcpcd_handlehwaddr(ctx, ifp->name, CLLADDR(&sdl),sdl.sdl_alen); + break; + } #ifdef INET - case AF_INET: - case 255: /* FIXME: Why 255? */ - COPYOUT(rt.dest, rti_info[RTAX_IFA]); - COPYOUT(rt.mask, rti_info[RTAX_NETMASK]); - COPYOUT(rt.gate, rti_info[RTAX_BRD]); - if (rtm->rtm_type == RTM_NEWADDR) { - ifa_flags = if_addrflags(&rt.dest, ifp); - if (ifa_flags == -1) - break; - } else - ifa_flags = 0; - ipv4_handleifa(ctx, rtm->rtm_type, - NULL, ifp->name, - &rt.dest, &rt.mask, &rt.gate, ifa_flags); + case AF_INET: + case 255: /* FIXME: Why 255? */ + { + struct in_addr addr, mask, bcast; + int flags; + + COPYOUT(addr, rti_info[RTAX_IFA]); + COPYOUT(mask, rti_info[RTAX_NETMASK]); + COPYOUT(bcast, rti_info[RTAX_BRD]); + if (ifam->ifam_type == RTM_NEWADDR) { + if ((flags = if_addrflags(&addr, ifp)) == -1) break; + } else + flags = 0; + ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name, + &addr, &mask, &bcast, flags); + break; + } #endif #ifdef INET6 - case AF_INET6: - sin6 = (void *)rti_info[RTAX_IFA]; - ia6 = sin6->sin6_addr; - DESCOPE(&ia6); - sin6 = (void *)rti_info[RTAX_NETMASK]; - mask6 = sin6->sin6_addr; - DESCOPE(&mask6); - if (rtm->rtm_type == RTM_NEWADDR) { - ifa_flags = if_addrflags6(&ia6, ifp); - if (ifa_flags == -1) - break; - } else - ifa_flags = 0; - ipv6_handleifa(ctx, rtm->rtm_type, NULL, - ifp->name, &ia6, ipv6_prefixlen(&mask6), - ifa_flags); + case AF_INET6: + { + struct in6_addr addr6, mask6; + struct sockaddr_in6 *sin6; + int flags; + + sin6 = (void *)rti_info[RTAX_IFA]; + addr6 = sin6->sin6_addr; + DESCOPE(&addr6); + sin6 = (void *)rti_info[RTAX_NETMASK]; + mask6 = sin6->sin6_addr; + DESCOPE(&mask6); + if (ifam->ifam_type == RTM_NEWADDR) { + if ((flags = if_addrflags6(&addr6, ifp)) == -1) break; + } else + flags = 0; + ipv6_handleifa(ctx, ifam->ifam_type, NULL, + ifp->name, &addr6, ipv6_prefixlen(&mask6), flags); + break; + } #endif - } - break; - } + } +} + +static void +if_dispatch(struct dhcpcd_ctx *ctx, struct rt_msghdr *rtm) +{ + + switch(rtm->rtm_type) { +#ifdef RTM_IFANNOUNCE + case RTM_IFANNOUNCE: + if_announce(ctx, (void *)rtm); + break; +#endif + case RTM_IFINFO: + if_ifinfo(ctx, (void *)rtm); + break; + case RTM_ADD: /* FALLTHROUGH */ + case RTM_CHANGE: /* FALLTHROUGH */ + case RTM_DELETE: + if_rtm(ctx, (void *)rtm); + break; +#ifdef RTM_CHGADDR + case RTM_CHGADDR: /* FALLTHROUGH */ +#endif + case RTM_DELADDR: /* FALLTHROUGH */ + case RTM_NEWADDR: + if_ifa(ctx, (void *)rtm); + break; + } +} + +int +if_handlelink(struct dhcpcd_ctx *ctx) +{ + /* route and ifwatchd like a msg buf size of 2048 */ + uint8_t buf[2048], *p, *e; + size_t msglen; + ssize_t bytes; + + if ((bytes = read(ctx->link_fd, buf, sizeof(buf))) == -1) + return -1; + e = buf + bytes; + for (p = buf; p < e; p += msglen) { + msglen = ((struct rt_msghdr *)p)->rtm_msglen; + if_dispatch(ctx, (struct rt_msghdr *)p); } return 0; } diff --git a/if.c b/if.c index e5f78b35..1df718d0 100644 --- a/if.c +++ b/if.c @@ -460,7 +460,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) } ifp->hwlen = sdl->sdl_alen; #ifndef CLLADDR -# define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen)) +# define CLLADDR(s) (const void *)((s)->sdl_data + (s)->sdl_nlen) #endif memcpy(ifp->hwaddr, CLLADDR(sdl), ifp->hwlen); #elif AF_PACKET