]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
It's possible to receive an RA for an interface that has not yet
authorRoy Marples <roy@marples.name>
Thu, 30 May 2013 12:07:25 +0000 (12:07 +0000)
committerRoy Marples <roy@marples.name>
Thu, 30 May 2013 12:07:25 +0000 (12:07 +0000)
obtained a local link address to send an RS.
If this happens, we should process the RA.

ipv6.c
ipv6.h
ipv6ns.c
ipv6rs.c

diff --git a/ipv6.c b/ipv6.c
index 6998c5ae847517a6574c20c04641ebd80a613d99..c7a515b638a6fc7bcd4d1cebd1912228248748f1 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -373,13 +373,15 @@ ipv6_handleifa(int cmd, struct if_head *ifs, const char *ifname,
        dhcp6_handleifa(cmd, ifname, addr, flags);
 }
 
-int
-ipv6_interfacehaslinklocal(const struct interface *ifp)
+const struct ll_addr *
+ipv6_linklocal(const struct interface *ifp)
 {
        const struct ipv6_state *state;
 
        state = IPV6_CSTATE(ifp);
-       return (state && TAILQ_FIRST(&state->ll_addrs)) ? 1 : 0;
+       if (state)
+               return TAILQ_FIRST(&state->ll_addrs);
+       return NULL;
 }
 
 int ipv6_addlinklocalcallback(struct interface *ifp,
diff --git a/ipv6.h b/ipv6.h
index c99227e42facee1adc13e449036c8557cf024049..38b9a989f0e16b200726e3d2fe6d0ae7ef4b0580 100644 (file)
--- a/ipv6.h
+++ b/ipv6.h
@@ -143,7 +143,7 @@ void ipv6_handleifa(int, struct if_head *,
     const char *, const struct in6_addr *, int);
 int ipv6_handleifa_addrs(int, struct ipv6_addrhead *,
     const struct in6_addr *, int);
-int ipv6_interfacehaslinklocal(const struct interface *);
+const struct ll_addr *ipv6_linklocal(const struct interface *);
 int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *);
 void ipv6_free(struct interface *);
 int ipv6_removesubnet(const struct interface *, struct ipv6_addr *);
index c588bc0e0889c7d68504a3d8154592fda9c5489a..00748819bde12b1a5bd93a336e4a161bbf238b2e 100644 (file)
--- a/ipv6ns.c
+++ b/ipv6ns.c
@@ -337,9 +337,11 @@ ipv6ns_probeaddr(void *arg)
        if (ap->dadcallback == NULL)
                syslog(LOG_WARNING, "%s: no callback!", ap->iface->name);
 #endif
-       if (sendmsg(unspec_sock, &sndhdr, 0) == -1)
+       if (sendmsg(unspec_sock, &sndhdr, 0) == -1) {
                syslog(LOG_ERR, "%s: %s: sendmsg: %m",
                    ap->iface->name, __func__);
+               return;
+       }
 
        if (ap->dadcallback) {
                ms_to_tv(&tv, RETRANS_TIMER);
@@ -460,15 +462,17 @@ ipv6ns_proberouter(void *arg)
        syslog(LOG_INFO, "%s: sending IPv6 NS for %s",
            rap->iface->name, rap->sfrom);
 #endif
-       if (sendmsg(sock, &sndhdr, 0) == -1)
+       if (sendmsg(sock, &sndhdr, 0) == -1) {
                syslog(LOG_ERR, "%s: %s: sendmsg: %m",
                    rap->iface->name, __func__);
+               return;
+       }
 
        ms_to_tv(&tv, rap->retrans == 0 ? RETRANS_TIMER : rap->retrans);
        ms_to_tv(&rtv, MIN_RANDOM_FACTOR);
        timeradd(&tv, &rtv, &tv);
        rtv.tv_sec = 0;
-       rtv.tv_usec = arc4random() % (MAX_RANDOM_FACTOR_U - MIN_RANDOM_FACTOR_U);
+       rtv.tv_usec = arc4random() % (MAX_RANDOM_FACTOR_U -MIN_RANDOM_FACTOR_U);
        timeradd(&tv, &rtv, &tv);
        eloop_timeout_add_tv(&tv, ipv6ns_proberouter, rap);
 
index bc151c797b1b046b9ab2f56fbfed6e2d47aee389..29d4d94d6cbad573555019872a3e56383f073b51 100644 (file)
--- a/ipv6rs.c
+++ b/ipv6rs.c
@@ -232,7 +232,7 @@ ipv6rs_sendprobe(void *arg)
        struct in6_pktinfo pi;
        int hoplimit = HOPLIMIT;
 
-       if (!ipv6_interfacehaslinklocal(ifp)) {
+       if (ipv6_linklocal(ifp) == NULL) {
                syslog(LOG_DEBUG,
                    "%s: delaying Router Soliciation for LL address",
                    ifp->name);
@@ -596,6 +596,16 @@ ipv6rs_handledata(__unused void *arg)
 #endif
                return;
        }
+
+       /* We could recieve a RA before we sent a RS*/
+       if (ipv6_linklocal(ifp) == NULL) {
+#ifdef DEBUG_RS
+               syslog(LOG_DEBUG, "%s: received RA from %s (no link-local)",
+                   ifp->name, sfrom);
+#endif
+               return;
+       }
+
        TAILQ_FOREACH(rap, &ipv6_routers, next) {
                if (ifp == rap->iface &&
                    memcmp(rap->from.s6_addr, from.sin6_addr.s6_addr,