From: Roy Marples Date: Fri, 10 Mar 2017 11:05:02 +0000 (+0000) Subject: Only conflict on ARP when sip matches OR sip is INADDR_ANY and X-Git-Tag: v7.0.0-beta1~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5e1d4fd7bb41a5fb9c19b82d757ed6ba9834347;p=thirdparty%2Fdhcpcd.git Only conflict on ARP when sip matches OR sip is INADDR_ANY and tip matches and we haven't added the address yet. --- diff --git a/dhcp.c b/dhcp.c index 39193b5b..f0ce8d53 100644 --- 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); diff --git a/ipv4ll.c b/ipv4ll.c index ce28c817..fd37ac8d 100644 --- 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 &&