]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Spit handlelink into smaller functions to increase read-ability.
authorRoy Marples <roy@marples.name>
Thu, 19 May 2016 20:27:07 +0000 (20:27 +0000)
committerRoy Marples <roy@marples.name>
Thu, 19 May 2016 20:27:07 +0000 (20:27 +0000)
dhcpcd.c
dhcpcd.h
if-bsd.c
if.c

index 31204d951fa4a80628a8dfe225697bc05cdb2e0b..aaf3ce20403846d173169c873173ad55326bb135 100644 (file)
--- 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];
index 0ad5c283569d4ff6dc590245a57bed6df33181a8..f286e3093f254f1d101b1c8271399236325d7366 100644 (file)
--- 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 *);
 
index 0d5d1bd3a68618b85ac2eb39db488ff1ef92d77b..959bae49d1ce787a880b90908fed1eb4d332f4dc 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
        } 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 e5f78b354ec9783ffe3d95be3e648901c62e1acf..1df718d07bbf5c83f33c4ff509915dffb75aac7e 100644 (file)
--- 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