]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Only conflict on ARP when sip matches OR sip is INADDR_ANY and
authorRoy Marples <roy@marples.name>
Fri, 10 Mar 2017 11:05:02 +0000 (11:05 +0000)
committerRoy Marples <roy@marples.name>
Fri, 10 Mar 2017 11:05:02 +0000 (11:05 +0000)
tip matches and we haven't added the address yet.

dhcp.c
ipv4ll.c

diff --git a/dhcp.c b/dhcp.c
index 39193b5b30f4c8c323743d0c4add8531d0ac9b22..f0ce8d538ece341bf8fc24c64dfc5654f4fb82d5 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -2095,9 +2095,7 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
        if (state->arping_index != -1 &&
            state->arping_index < ifo->arping_len &&
            amsg &&
-           (amsg->sip.s_addr == ifo->arping[state->arping_index] ||
-           (amsg->sip.s_addr == 0 &&
-           amsg->tip.s_addr == ifo->arping[state->arping_index])))
+           amsg->sip.s_addr == ifo->arping[state->arping_index])
        {
                char buf[HWADDR_LEN * 3];
 
@@ -2160,9 +2158,7 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
 
        /* Bound address */
        if (amsg && state->addr &&
-           (amsg->sip.s_addr == state->addr->addr.s_addr ||
-           (amsg->sip.s_addr == 0 &&
-           amsg->tip.s_addr == state->addr->addr.s_addr)))
+           amsg->sip.s_addr == state->addr->addr.s_addr)
        {
                astate->failed = state->addr->addr;
                arp_report_conflicted(astate, amsg);
index ce28c817162a5ff487a59d43a04e0b117ed4dc36..fd37ac8d075cd6ca341330159831bab8da2dfd0a 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -244,7 +244,6 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
 {
        struct interface *ifp;
        struct ipv4ll_state *state;
-       in_addr_t fail;
 
        assert(astate != NULL);
        assert(astate->iface != NULL);
@@ -252,23 +251,19 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
        state = IPV4LL_STATE(ifp);
        assert(state != NULL);
 
-       fail = 0;
-       /* RFC 3927 2.2.1, Probe Conflict Detection */
+       /*
+        * NULL amsg means kernel detected DAD.
+        * We always fail on matching sip.
+        * We only fail on matching tip and we haven't added that address yet.
+        */
        if (amsg == NULL ||
-           (amsg->sip.s_addr == astate->addr.s_addr ||
-           (amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr)))
-               fail = astate->addr.s_addr;
-
-       /* RFC 3927 2.5, Conflict Defense */
-       if (state->addr != NULL &&
-           IN_LINKLOCAL(ntohl(state->addr->addr.s_addr)) &&
-           amsg && amsg->sip.s_addr == state->addr->addr.s_addr)
-               fail = state->addr->addr.s_addr;
-
-       if (fail == 0)
+           amsg->sip.s_addr == astate->addr.s_addr ||
+           (amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr
+            && ipv4_iffindaddr(ifp, &amsg->tip, NULL) == NULL))
+               astate->failed = astate->addr;
+       else
                return;
 
-       astate->failed.s_addr = fail;
        arp_report_conflicted(astate, amsg);
 
        if (state->addr != NULL &&