From: Roy Marples Date: Fri, 14 Oct 2016 08:55:04 +0000 (+0000) Subject: Support kernels which implement RFC5227. X-Git-Tag: v7.0.0-beta1~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c66f2657465d2c62f91bc241870345ca5d490adc;p=thirdparty%2Fdhcpcd.git Support kernels which implement RFC5227. This means we don't have to open an ARP socket unless we need to ARPing. Allow ARP an ARPing to be optional features. --- diff --git a/README b/README index e2389015..50a69c77 100644 --- a/README +++ b/README @@ -24,6 +24,8 @@ dhcpcd can also be made smaller by removing the IPv4 or IPv6 stack: * --disable-inet6 Or by removing the following features: * --disable-auth + * --disable-arp + * --disable-arping * --disable-ipv4ll * --disable-dhcp6 diff --git a/arp.c b/arp.c index d08907f6..02536caa 100644 --- a/arp.c +++ b/arp.c @@ -52,6 +52,7 @@ #include "if-options.h" #include "ipv4ll.h" +#if defined(ARP) && (!defined(KERNEL_RFC5227) || defined(ARPING)) #define ARP_LEN \ (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN)) @@ -101,26 +102,6 @@ eexit: return -1; } -void -arp_report_conflicted(const struct arp_state *astate, - const struct arp_msg *amsg) -{ - - if (amsg != NULL) { - char buf[HWADDR_LEN * 3]; - - logger(astate->iface->ctx, LOG_ERR, - "%s: hardware address %s claims %s", - astate->iface->name, - hwaddr_ntoa(amsg->sha, astate->iface->hwlen, - buf, sizeof(buf)), - inet_ntoa(astate->failed)); - } else - logger(astate->iface->ctx, LOG_ERR, - "%s: DAD detected %s", - astate->iface->name, inet_ntoa(astate->failed)); -} - static void arp_packet(struct interface *ifp, uint8_t *data, size_t len) { @@ -184,6 +165,18 @@ arp_packet(struct interface *ifp, uint8_t *data, size_t len) } } +void +arp_close(struct interface *ifp) +{ + struct iarp_state *state; + + if ((state = ARP_STATE(ifp)) != NULL && state->fd != -1) { + eloop_event_delete(ifp->ctx->eloop, state->fd); + if_closeraw(ifp, state->fd); + state->fd = -1; + } +} + static void arp_read(void *arg) { @@ -215,6 +208,8 @@ arp_open(struct interface *ifp) { struct iarp_state *state; +printf("ARP OPENED!!!\n"); + state = ARP_STATE(ifp); if (state->fd == -1) { state->fd = if_openraw(ifp, ETHERTYPE_ARP); @@ -228,6 +223,59 @@ arp_open(struct interface *ifp) return state->fd; } +static void +arp_probed(void *arg) +{ + struct arp_state *astate = arg; + + astate->probed_cb(astate); +} + +static void +arp_probe1(void *arg) +{ + struct arp_state *astate = arg; + struct interface *ifp = astate->iface; + struct timespec tv; + + if (++astate->probes < PROBE_NUM) { + tv.tv_sec = PROBE_MIN; + tv.tv_nsec = (suseconds_t)arc4random_uniform( + (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC); + timespecnorm(&tv); + eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate); + } else { + tv.tv_sec = ANNOUNCE_WAIT; + tv.tv_nsec = 0; + eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate); + } + logger(ifp->ctx, LOG_DEBUG, + "%s: ARP probing %s (%d of %d), next in %0.1f seconds", + ifp->name, inet_ntoa(astate->addr), + astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM, + timespec_to_double(&tv)); + if (arp_request(ifp, 0, astate->addr.s_addr) == -1) + logger(ifp->ctx, LOG_ERR, "send_arp: %m"); +} + +void +arp_probe(struct arp_state *astate) +{ + + if (arp_open(astate->iface) == -1) { + logger(astate->iface->ctx, LOG_ERR, + "%s: %s: %m", __func__, astate->iface->name); + return; + } + astate->probes = 0; + logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s", + astate->iface->name, inet_ntoa(astate->addr)); + arp_probe1(astate); +} +#else /* !ARP */ +#define arp_close(ifp) {} +#endif /* ARP */ + static void arp_announced(void *arg) { @@ -238,8 +286,7 @@ arp_announced(void *arg) return; } - /* As there is no announced callback, free the ARP state. */ - arp_free(astate); + /* Keep the ARP state open to handle ongoing ACD. */ } static void @@ -248,6 +295,11 @@ arp_announce1(void *arg) struct arp_state *astate = arg; struct interface *ifp = astate->iface; +#ifdef KERNEL_RFC5227 + /* We rely on the kernel announcing correctly. + * As the timings are not random we can callback safely. */ + astate->claims++; +#else if (++astate->claims < ANNOUNCE_NUM) logger(ifp->ctx, LOG_DEBUG, "%s: ARP announcing %s (%d of %d), " @@ -261,6 +313,7 @@ arp_announce1(void *arg) astate->claims, ANNOUNCE_NUM); if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr) == -1) logger(ifp->ctx, LOG_ERR, "send_arp: %m"); +#endif eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT, astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced, astate); @@ -270,63 +323,36 @@ void arp_announce(struct arp_state *astate) { +#ifndef KERNEL_RFC5227 if (arp_open(astate->iface) == -1) { logger(astate->iface->ctx, LOG_ERR, "%s: %s: %m", __func__, astate->iface->name); return; } +#endif + astate->claims = 0; arp_announce1(astate); } -static void -arp_probed(void *arg) -{ - struct arp_state *astate = arg; - - astate->probed_cb(astate); -} - -static void -arp_probe1(void *arg) -{ - struct arp_state *astate = arg; - struct interface *ifp = astate->iface; - struct timespec tv; - - if (++astate->probes < PROBE_NUM) { - tv.tv_sec = PROBE_MIN; - tv.tv_nsec = (suseconds_t)arc4random_uniform( - (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC); - timespecnorm(&tv); - eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate); - } else { - tv.tv_sec = ANNOUNCE_WAIT; - tv.tv_nsec = 0; - eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate); - } - logger(ifp->ctx, LOG_DEBUG, - "%s: ARP probing %s (%d of %d), next in %0.1f seconds", - ifp->name, inet_ntoa(astate->addr), - astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM, - timespec_to_double(&tv)); - if (arp_request(ifp, 0, astate->addr.s_addr) == -1) - logger(ifp->ctx, LOG_ERR, "send_arp: %m"); -} - void -arp_probe(struct arp_state *astate) +arp_report_conflicted(const struct arp_state *astate, + const struct arp_msg *amsg) { - if (arp_open(astate->iface) == -1) { + if (amsg != NULL) { + char buf[HWADDR_LEN * 3]; + logger(astate->iface->ctx, LOG_ERR, - "%s: %s: %m", __func__, astate->iface->name); - return; - } - astate->probes = 0; - logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s", - astate->iface->name, inet_ntoa(astate->addr)); - arp_probe1(astate); + "%s: hardware address %s claims %s", + astate->iface->name, + hwaddr_ntoa(amsg->sha, astate->iface->hwlen, + buf, sizeof(buf)), + inet_ntoa(astate->failed)); + } else + logger(astate->iface->ctx, LOG_ERR, + "%s: DAD detected %s", + astate->iface->name, inet_ntoa(astate->failed)); } struct arp_state * @@ -403,9 +429,8 @@ arp_free(struct arp_state *astate) free(astate); /* If there are no more ARP states, close the socket. */ - if (state->fd != -1 && TAILQ_FIRST(&state->arp_states) == NULL) { - eloop_event_delete(ifp->ctx->eloop, state->fd); - if_closeraw(ifp, state->fd); + if (TAILQ_FIRST(&state->arp_states) == NULL) { + arp_close(ifp); free(state); ifp->if_data[IF_DATA_ARP] = NULL; } @@ -434,10 +459,11 @@ arp_free_but(struct arp_state *astate) } void -arp_close(struct interface *ifp) +arp_drop(struct interface *ifp) { arp_free_but1(ifp, NULL); + arp_close(ifp); } void diff --git a/arp.h b/arp.h index b844e498..7e251ec0 100644 --- a/arp.h +++ b/arp.h @@ -43,6 +43,14 @@ #include "dhcpcd.h" #include "if.h" +#ifdef IN_IFF_DUPLICATED +/* NetBSD gained RFC 5227 support in the kernel. + * This means dhcpcd doesn't need ARP except for ARPing support. */ +#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 799003900 +#define KERNEL_RFC5227 +#endif +#endif + struct arp_msg { uint16_t op; unsigned char sha[HWADDR_LEN]; @@ -77,21 +85,25 @@ struct iarp_state { #define ARP_CSTATE(ifp) \ ((const struct iarp_state *)(ifp)->if_data[IF_DATA_ARP]) -#ifdef INET +#if defined(ARP) && (!defined(KERNEL_RFC5227) || defined(ARPING)) int arp_open(struct interface *); ssize_t arp_request(const struct interface *, in_addr_t, in_addr_t); -void arp_report_conflicted(const struct arp_state *, const struct arp_msg *); -void arp_announce(struct arp_state *); void arp_probe(struct arp_state *); +void arp_close(struct interface *); +#endif + +#ifdef ARP +void arp_report_conflicted(const struct arp_state *, const struct arp_msg *); struct arp_state *arp_new(struct interface *, const struct in_addr *); +struct arp_state *arp_find(struct interface *, const struct in_addr *); +void arp_announce(struct arp_state *); void arp_cancel(struct arp_state *); void arp_free(struct arp_state *); void arp_free_but(struct arp_state *); -struct arp_state *arp_find(struct interface *, const struct in_addr *); -void arp_close(struct interface *); +void arp_drop(struct interface *); void arp_handleifa(int, struct ipv4_addr *); #else -#define arp_close(a) {} +#define arp_drop(a) {} #endif #endif diff --git a/configure b/configure index b47f91e1..602560e2 100755 --- a/configure +++ b/configure @@ -7,6 +7,8 @@ exec 3>config.log # Ensure that we do not inherit these from env HOOKSET=false INET= +ARP= +ARPING= IPV4LL= INET6= ARC4RANDOM= @@ -44,11 +46,15 @@ for x do --enable-fork) FORK=yes;; --disable-static) STATIC=no;; --enable-static) STATIC=yes;; - --disable-ipv4|--disable-inet) INET=no;; + --disable-ipv4|--disable-inet) INET=no; ARP=no; ARPING=no; IPV4LL=no;; --enable-ipv4|--enable-inet) INET=yes;; + --disable-arp) ARP=no; ARPING=no; IPV4LL=no;; + --enable-arp) ARP=yes; INET=yes;; + --disable-arping) ARPING=no;; + --enable-arping) ARPING=yes; ARP=yes; INET=yes;; --disable-ipv4ll) IPV4LL=no;; - --enable-ipv4ll) IPV4LL=yes; INET=yes;; - --disable-ipv6|--disable-inet6) INET6=no;; + --enable-ipv4ll) IPV4LL=yes; ARP=yes; INET=yes;; + --disable-ipv6|--disable-inet6) INET6=no; DHCP6=no;; --enable-ipv6|--enable-inet6) INET6=yes;; --disable-dhcp6) DHCP6=no;; --enable-dhcp6) DHCP6=yes;; @@ -444,7 +450,16 @@ esac if [ -z "$INET" -o "$INET" = yes ]; then echo "Enabling INET support" echo "CPPFLAGS+= -DINET" >>$CONFIG_MK - echo "DHCPCD_SRCS+= arp.c dhcp.c ipv4.c" >>$CONFIG_MK + echo "DHCPCD_SRCS+= dhcp.c ipv4.c" >>$CONFIG_MK + if [ -z "$ARP" -o "$ARP" = yes ]; then + echo "Enabling ARP support" + echo "CPPFLAGS+= -DARP" >>$CONFIG_MK + echo "DHCPCD_SRCS+= arp.c" >>$CONFIG_MK + fi + if [ -z "$ARPING" -o "$ARPING" = yes ]; then + echo "Enabling ARPing support" + echo "CPPFLAGS+= -DARPING" >>$CONFIG_MK + fi if [ -z "$IPV4LL" -o "$IPV4LL" = yes ]; then echo "Enabling IPv4LL support" echo "CPPFLAGS+= -DIPV4LL" >>$CONFIG_MK diff --git a/dhcp.c b/dhcp.c index c1d4282a..fedd1d0c 100644 --- a/dhcp.c +++ b/dhcp.c @@ -123,7 +123,9 @@ struct udp_bootp_packet }; static int dhcp_open(struct interface *); +#ifdef ARP static void dhcp_arp_conflicted(struct arp_state *, const struct arp_msg *); +#endif void dhcp_printoptions(const struct dhcpcd_ctx *ctx, @@ -1880,20 +1882,26 @@ static int dhcp_leaseextend(struct interface *ifp) { +#ifdef ARP if (ifp->options->options & DHCPCD_ARP) { + const struct dhcp_state *state; struct arp_state *astate; - if ((astate = arp_new(ifp, NULL)) == NULL) + state = D_CSTATE(ifp); + if ((astate = arp_new(ifp, &state->lease.addr)) == NULL) return -1; + astate->conflicted_cb = dhcp_arp_conflicted; +#ifndef KERNEL_RFC5227 if (arp_open(ifp) == -1) return -1; +#endif - astate->conflicted_cb = dhcp_arp_conflicted; logger(ifp->ctx, LOG_WARNING, "%s: extending lease until DaD failure or DHCP", ifp->name); return 0; } +#endif logger(ifp->ctx, LOG_WARNING, "%s: extending lease", ifp->name); return 0; @@ -1926,12 +1934,14 @@ dhcp_expire(void *arg) dhcp_expire1(ifp); } +#ifdef ARP static void dhcp_decline(struct interface *ifp) { send_message(ifp, DHCP_DECLINE, NULL); } +#endif static void dhcp_startrenew(void *arg) @@ -1987,14 +1997,18 @@ dhcp_rebind(void *arg) send_rebind(ifp); } +#ifdef ARP static void dhcp_arp_probed(struct arp_state *astate) { + struct interface *ifp; struct dhcp_state *state; struct if_options *ifo; - state = D_STATE(astate->iface); - ifo = astate->iface->options; + ifp = astate->iface; + state = D_STATE(ifp); + ifo = ifp->options; +#ifdef ARPING if (state->arping_index < ifo->arping_len) { /* We didn't find a profile for this * address or hwaddr, so move to the next @@ -2003,19 +2017,27 @@ dhcp_arp_probed(struct arp_state *astate) astate->addr.s_addr = ifo->arping[state->arping_index - 1]; arp_probe(astate); + return; } - dhcpcd_startinterface(astate->iface); + arp_free(astate); +#ifdef KERNEL_RFC5227 + /* As arping is finished, close the ARP socket. + * The kernel will handle ACD from here. */ + arp_close(ifp); +#endif + dhcpcd_startinterface(ifp); return; } +#endif /* Already bound so DAD has worked */ if (state->state == DHS_BOUND) return; - logger(astate->iface->ctx, LOG_DEBUG, "%s: DAD completed for %s", - astate->iface->name, inet_ntoa(astate->addr)); + logger(ifp->ctx, LOG_DEBUG, "%s: DAD completed for %s", + ifp->name, inet_ntoa(astate->addr)); if (state->state != DHS_INFORM) - dhcp_bind(astate->iface); + dhcp_bind(ifp); #ifndef IN_IFF_TENTATIVE else { struct bootp *bootp; @@ -2025,8 +2047,7 @@ dhcp_arp_probed(struct arp_state *astate) len = state->new_len; state->new = state->offer; state->new_len = state->offer_len; - get_lease(astate->iface, &state->lease, - state->new, state->new_len); + get_lease(ifp, &state->lease, state->new, state->new_len); ipv4_applyaddr(astate->iface); state->new = bootp; state->new_len = len; @@ -2034,14 +2055,14 @@ dhcp_arp_probed(struct arp_state *astate) #endif /* If we forked, stop here. */ - if (astate->iface->ctx->options & DHCPCD_FORKED) + if (ifp->ctx->options & DHCPCD_FORKED) return; /* Stop IPv4LL now we have a working DHCP address */ - ipv4ll_drop(astate->iface); + ipv4ll_drop(ifp); if (ifo->options & DHCPCD_INFORM) - dhcp_inform(astate->iface); + dhcp_inform(ifp); } static void @@ -2049,11 +2070,15 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg) { struct interface *ifp; struct dhcp_state *state; +#ifdef ARPING struct if_options *ifo; +#endif ifp = astate->iface; - ifo = ifp->options; state = D_STATE(ifp); + +#ifdef ARPING + ifo = ifp->options; if (state->arping_index && state->arping_index <= ifo->arping_len && amsg && @@ -2078,10 +2103,16 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg) } dhcp_close(ifp); arp_free(astate); +#ifdef KERNEL_RFC5227 + /* As arping is finished, close the ARP socket. + * The kernel will handle ACD from here. */ + arp_close(ifp); +#endif eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); dhcpcd_startinterface(ifp); return; } +#endif /* RFC 2131 3.1.5, Client-server interaction * NULL amsg means IN_IFF_DUPLICATED */ @@ -2131,6 +2162,7 @@ dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg) return; } } +#endif void dhcp_bind(struct interface *ifp) @@ -2305,6 +2337,7 @@ dhcp_message_new(struct bootp **bootp, return sizeof(**bootp); } +#ifdef ARP static int dhcp_arp_address(struct interface *ifp) { @@ -2322,13 +2355,13 @@ dhcp_arp_address(struct interface *ifp) /* If the interface already has the address configured * then we can't ARP for duplicate detection. */ ia = ipv4_findaddr(ifp->ctx, &addr); + if ((astate = arp_new(ifp, &addr)) == NULL) + return 0; + astate->probed_cb = dhcp_arp_probed; + astate->conflicted_cb = dhcp_arp_conflicted; #ifdef IN_IFF_TENTATIVE if (ia == NULL || ia->addr_flags & IN_IFF_NOTUSEABLE) { - if ((astate = arp_new(ifp, &addr)) != NULL) { - astate->probed_cb = dhcp_arp_probed; - astate->conflicted_cb = dhcp_arp_conflicted; - } if (ia == NULL) { struct dhcp_lease l; @@ -2347,12 +2380,8 @@ dhcp_arp_address(struct interface *ifp) get_lease(ifp, &l, state->offer, state->offer_len); logger(ifp->ctx, LOG_INFO, "%s: probing address %s/%d", ifp->name, inet_ntoa(l.addr), inet_ntocidr(l.mask)); - if ((astate = arp_new(ifp, &addr)) != NULL) { - astate->probed_cb = dhcp_arp_probed; - astate->conflicted_cb = dhcp_arp_conflicted; - /* We need to handle DAD. */ - arp_probe(astate); - } + /* We need to handle DAD. */ + arp_probe(astate); return 0; } #endif @@ -2367,6 +2396,7 @@ dhcp_arp_bind(struct interface *ifp) if (dhcp_arp_address(ifp) == 1) dhcp_bind(ifp); } +#endif static void dhcp_static(struct interface *ifp) @@ -2395,7 +2425,11 @@ dhcp_static(struct interface *ifp) ia ? &ia->addr : &ifo->req_addr, ia ? &ia->mask : &ifo->req_mask); if (state->offer_len) +#ifdef ARP dhcp_arp_bind(ifp); +#else + dhcp_bind(ifp); +#endif } void @@ -2440,8 +2474,10 @@ dhcp_inform(struct interface *ifp) ipv4_deladdr(ia, 1); state->offer_len = dhcp_message_new(&state->offer, &ifo->req_addr, &ifo->req_mask); +#ifdef ARP if (dhcp_arp_address(ifp) == 0) return; +#endif ia = ipv4_iffindaddr(ifp, &ifo->req_addr, &ifo->req_mask); assert(ia != NULL); @@ -2925,7 +2961,7 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len, case 0: LOGDHCP(LOG_WARNING, "IPv4LL disabled from"); ipv4ll_drop(ifp); - arp_close(ifp); + arp_drop(ifp); break; case 1: LOGDHCP(LOG_WARNING, "IPv4LL enabled from"); @@ -3084,7 +3120,11 @@ rapidcommit: lease->frominfo = 0; eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); +#ifdef ARP dhcp_arp_bind(ifp); +#else + dhcp_bind(ifp); +#endif } static void * @@ -3231,7 +3271,6 @@ dhcp_readpacket(void *arg) logger(ifp->ctx, LOG_ERR, "%s: dhcp if_readrawpacket: %m", ifp->name); dhcp_close(ifp); - arp_close(ifp); return; } dhcp_handlepacket(ifp, buf, (size_t)bytes, flags); @@ -3314,7 +3353,7 @@ dhcp_free(struct interface *ifp) struct dhcpcd_ctx *ctx; dhcp_close(ifp); - arp_close(ifp); + arp_drop(ifp); if (state) { free(state->old); free(state->new); @@ -3467,6 +3506,7 @@ dhcp_start1(void *arg) state->offer = NULL; state->offer_len = 0; +#ifdef ARPING if (state->arping_index < ifo->arping_len) { struct arp_state *astate; @@ -3478,6 +3518,7 @@ dhcp_start1(void *arg) } return; } +#endif if (ifo->options & DHCPCD_STATIC) { dhcp_static(ifp); diff --git a/dhcp.h b/dhcp.h index d62ead9d..a21eea30 100644 --- a/dhcp.h +++ b/dhcp.h @@ -208,7 +208,9 @@ struct dhcp_state { struct timespec started; unsigned char *clientid; struct authstate auth; +#ifdef ARPING size_t arping_index; +#endif }; #define D_STATE(ifp) \ diff --git a/dhcpcd.c b/dhcpcd.c index 8b8f1220..33dfe05e 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -370,7 +370,7 @@ dhcpcd_drop(struct interface *ifp, int stop) ipv6_drop(ifp); ipv4ll_drop(ifp); dhcp_drop(ifp, stop ? "STOP" : "EXPIRE"); - arp_close(ifp); + arp_drop(ifp); } static void @@ -722,7 +722,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, ifp->carrier = LINK_DOWN; script_runreason(ifp, "NOCARRIER"); #ifdef NOCARRIER_PRESERVE_IP - arp_close(ifp); + arp_drop(ifp); dhcp_abort(ifp); if_sortinterfaces(ctx); ipv4_preferanother(ifp); @@ -1446,6 +1446,12 @@ main(int argc, char **argv) #ifdef INET " INET" #endif +#ifdef ARP + " ARP" +#endif +#ifdef ARPING + " ARPing" +#endif #ifdef IPV4LL " IPv4LL" #endif diff --git a/ipv4.c b/ipv4.c index 837fb886..876ca0af 100644 --- a/ipv4.c +++ b/ipv4.c @@ -890,7 +890,11 @@ ipv4_deladdr(struct ipv4_addr *addr, int keeparp) int r; struct ipv4_state *state; struct ipv4_addr *ap; +#ifdef ARP struct arp_state *astate; +#else + UNUSED(keeparp); +#endif logger(addr->iface->ctx, LOG_DEBUG, "%s: deleting IP address %s", addr->iface->name, addr->saddr); @@ -902,8 +906,10 @@ ipv4_deladdr(struct ipv4_addr *addr, int keeparp) logger(addr->iface->ctx, LOG_ERR, "%s: %s: %m", addr->iface->name, __func__); +#ifdef ARP if (!keeparp && (astate = arp_find(addr->iface, &addr->addr)) != NULL) arp_free(astate); +#endif state = IPV4_STATE(addr->iface); TAILQ_FOREACH(ap, &state->addrs, next) { @@ -1237,7 +1243,7 @@ ipv4_applyaddr(void *arg) ifp->name); return; } -#ifdef IN_IFF_NOTUSEABLE +#if defined(ARP) && defined(IN_IFF_NOTUSEABLE) if (ia->addr_flags & IN_IFF_NOTUSEABLE) return; #endif @@ -1256,13 +1262,17 @@ ipv4_applyaddr(void *arg) * notification right now via our link socket. */ if_initrt(ifp->ctx); ipv4_buildroutes(ifp->ctx); + +#ifdef ARP /* Announce the address */ if (ifo->options & DHCPCD_ARP) { struct arp_state *astate; - if ((astate = arp_new(ifp, &state->addr->addr)) != NULL) + if ((astate = arp_find(ifp, &state->addr->addr)) != NULL) arp_announce(astate); } +#endif + if (state->state == DHS_BOUND) { script_runreason(ifp, state->reason); dhcpcd_daemonise(ifp->ctx); @@ -1336,7 +1346,9 @@ ipv4_handleifa(struct dhcpcd_ctx *ctx, } if (addr->s_addr != INADDR_ANY && addr->s_addr != INADDR_BROADCAST) { +#ifdef ARP arp_handleifa(cmd, ia); +#endif dhcp_handleifa(cmd, ia); } diff --git a/ipv4ll.c b/ipv4ll.c index 398a692a..77e678aa 100644 --- a/ipv4ll.c +++ b/ipv4ll.c @@ -268,6 +268,11 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg) if (state->addr != NULL && astate->failed.s_addr == state->addr->addr.s_addr) { +#ifdef KERNEL_RFC5227 + logger(ifp->ctx, LOG_WARNING, + "%s: IPv4LL defence failed for %s", + ifp->name, state->addr->saddr); +#else struct timespec now, defend; /* RFC 3927 Section 2.5 says a defence should @@ -296,7 +301,7 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg) state->defend = now; return; } - +#endif ipv4_deladdr(state->addr, 1); state->down = 1; state->addr = NULL;