Import dhcpcd-7.0.4 with the following changes:
* Routing: Fix case when cloning route changes but needs to be replaced * DHCP6: Transpose DHCP userclass option into DHCP6 * DHCP6: Fix sending custom vendor class option * Auth: Allow zero value replay detection data * Auth: Allow different tokens for send and receive * ND6: Warn if router lifetime is set to zero * DHCP6: Softwire Address and Port-Mapped Clients, RFC7598
This commit is contained in:
parent
71c9531719
commit
483cca5a38
|
@ -151,7 +151,24 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
|||
|
||||
memcpy(&replay, d, sizeof(replay));
|
||||
replay = ntohll(replay);
|
||||
if (state->token) {
|
||||
/*
|
||||
* Test for a replay attack.
|
||||
*
|
||||
* NOTE: Some servers always send a replay data value of zero.
|
||||
* This is strictly compliant with RFC 3315 and 3318 which say:
|
||||
* "If the RDM field contains 0x00, the replay detection field MUST be
|
||||
* set to the value of a monotonically increasing counter."
|
||||
* An example of a monotonically increasing sequence is:
|
||||
* 1, 2, 2, 2, 2, 2, 2
|
||||
* Errata 3474 updates RFC 3318 to say:
|
||||
* "If the RDM field contains 0x00, the replay detection field MUST be
|
||||
* set to the value of a strictly increasing counter."
|
||||
*
|
||||
* Taking the above into account, dhcpcd will only test for
|
||||
* strictly speaking replay attacks if it receives any non zero
|
||||
* replay data to validate against.
|
||||
*/
|
||||
if (state->token && state->replay != 0) {
|
||||
if (state->replay == (replay ^ 0x8000000000000000ULL)) {
|
||||
/* We don't know if the singular point is increasing
|
||||
* or decreasing. */
|
||||
|
@ -174,7 +191,7 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
|||
* Rest of data is MAC. */
|
||||
switch (protocol) {
|
||||
case AUTH_PROTO_TOKEN:
|
||||
secretid = 0;
|
||||
secretid = auth->token_rcv_secretid;
|
||||
break;
|
||||
case AUTH_PROTO_DELAYED:
|
||||
if (dlen < sizeof(secretid) + sizeof(hmac_code)) {
|
||||
|
@ -182,6 +199,7 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
|||
return NULL;
|
||||
}
|
||||
memcpy(&secretid, d, sizeof(secretid));
|
||||
secretid = ntohl(secretid);
|
||||
d += sizeof(secretid);
|
||||
dlen -= sizeof(secretid);
|
||||
break;
|
||||
|
@ -197,6 +215,7 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
|||
dlen -= realm_len;
|
||||
}
|
||||
memcpy(&secretid, d, sizeof(secretid));
|
||||
secretid = ntohl(secretid);
|
||||
d += sizeof(secretid);
|
||||
dlen -= sizeof(secretid);
|
||||
break;
|
||||
|
@ -266,7 +285,6 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
|||
}
|
||||
|
||||
/* Find a token for the realm and secret */
|
||||
secretid = ntohl(secretid);
|
||||
TAILQ_FOREACH(t, &auth->tokens, next) {
|
||||
if (t->secretid == secretid &&
|
||||
t->realm_len == realm_len &&
|
||||
|
@ -478,14 +496,16 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
|
|||
uint64_t rdm;
|
||||
uint8_t hmac_code[HMAC_LENGTH];
|
||||
time_t now;
|
||||
uint8_t hops, *p, info, *m, *data;
|
||||
uint8_t hops, *p, *m, *data;
|
||||
uint32_t giaddr, secretid;
|
||||
bool auth_info;
|
||||
|
||||
if (auth->protocol == 0 && t == NULL) {
|
||||
/* Ignore the token argument given to us - always send using the
|
||||
* configured token. */
|
||||
if (auth->protocol == AUTH_PROTO_TOKEN) {
|
||||
TAILQ_FOREACH(t, &auth->tokens, next) {
|
||||
if (t->secretid == 0 &&
|
||||
t->realm_len == 0)
|
||||
break;
|
||||
if (t->secretid == auth->token_snd_secretid)
|
||||
break;
|
||||
}
|
||||
if (t == NULL) {
|
||||
errno = EINVAL;
|
||||
|
@ -532,9 +552,9 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
|
|||
/* DISCOVER or INFORM messages don't write auth info */
|
||||
if ((mp == 4 && (mt == DHCP_DISCOVER || mt == DHCP_INFORM)) ||
|
||||
(mp == 6 && (mt == DHCP6_SOLICIT || mt == DHCP6_INFORMATION_REQ)))
|
||||
info = 0;
|
||||
auth_info = false;
|
||||
else
|
||||
info = 1;
|
||||
auth_info = true;
|
||||
|
||||
/* Work out the auth area size.
|
||||
* We only need to do this for DISCOVER messages */
|
||||
|
@ -545,11 +565,11 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
|
|||
dlen += t->key_len;
|
||||
break;
|
||||
case AUTH_PROTO_DELAYEDREALM:
|
||||
if (info && t)
|
||||
if (auth_info && t)
|
||||
dlen += t->realm_len;
|
||||
/* FALLTHROUGH */
|
||||
case AUTH_PROTO_DELAYED:
|
||||
if (info && t)
|
||||
if (auth_info && t)
|
||||
dlen += sizeof(t->secretid) + sizeof(hmac_code);
|
||||
break;
|
||||
}
|
||||
|
@ -572,18 +592,32 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
|
|||
/* Write out our option */
|
||||
*data++ = auth->protocol;
|
||||
*data++ = auth->algorithm;
|
||||
*data++ = auth->rdm;
|
||||
switch (auth->rdm) {
|
||||
case AUTH_RDM_MONOTONIC:
|
||||
rdm = get_next_rdm_monotonic(auth);
|
||||
break;
|
||||
default:
|
||||
/* This block appeases gcc, clang doesn't need it */
|
||||
rdm = get_next_rdm_monotonic(auth);
|
||||
break;
|
||||
/*
|
||||
* RFC 3315 21.4.4.1 says that SOLICIT in DELAYED authentication
|
||||
* should not set RDM or it's data.
|
||||
* An expired draft draft-ietf-dhc-dhcpv6-clarify-auth-01 suggets
|
||||
* this should not be set for INFORMATION REQ messages as well,
|
||||
* which is probably a good idea because both states start from zero.
|
||||
*/
|
||||
if (auth_info ||
|
||||
!(auth->protocol & (AUTH_PROTO_DELAYED | AUTH_PROTO_DELAYEDREALM)))
|
||||
{
|
||||
*data++ = auth->rdm;
|
||||
switch (auth->rdm) {
|
||||
case AUTH_RDM_MONOTONIC:
|
||||
rdm = get_next_rdm_monotonic(auth);
|
||||
break;
|
||||
default:
|
||||
/* This block appeases gcc, clang doesn't need it */
|
||||
rdm = get_next_rdm_monotonic(auth);
|
||||
break;
|
||||
}
|
||||
rdm = htonll(rdm);
|
||||
memcpy(data, &rdm, 8);
|
||||
} else {
|
||||
*data++ = 0; /* rdm */
|
||||
memset(data, 0, 8); /* replay detection data */
|
||||
}
|
||||
rdm = htonll(rdm);
|
||||
memcpy(data, &rdm, 8);
|
||||
data += 8;
|
||||
dlen -= 1 + 1 + 1 + 8;
|
||||
|
||||
|
@ -603,7 +637,7 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
|
|||
}
|
||||
|
||||
/* DISCOVER or INFORM messages don't write auth info */
|
||||
if (!info)
|
||||
if (!auth_info)
|
||||
return (ssize_t)dlen;
|
||||
|
||||
/* Loading a saved lease without an authentication option */
|
||||
|
|
|
@ -71,6 +71,8 @@ struct auth {
|
|||
uint64_t last_replay;
|
||||
uint8_t last_replay_set;
|
||||
struct token_head tokens;
|
||||
uint32_t token_snd_secretid;
|
||||
uint32_t token_rcv_secretid;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define CONFIG_H
|
||||
|
||||
#define PACKAGE "dhcpcd"
|
||||
#define VERSION "7.0.3"
|
||||
#define VERSION "7.0.4"
|
||||
|
||||
#ifndef CONFIG
|
||||
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
|
||||
|
|
|
@ -193,6 +193,48 @@ dhcp6_printoptions(const struct dhcpcd_ctx *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
dhcp6_makeuser(void *data, const struct interface *ifp)
|
||||
{
|
||||
const struct if_options *ifo = ifp->options;
|
||||
struct dhcp6_option o;
|
||||
uint8_t *p;
|
||||
const uint8_t *up, *ue;
|
||||
uint16_t ulen, unlen;
|
||||
size_t olen;
|
||||
|
||||
/* Convert the DHCPv4 user class option to DHCPv6 */
|
||||
up = ifo->userclass;
|
||||
ulen = *up++;
|
||||
if (ulen == 0)
|
||||
return 0;
|
||||
|
||||
p = data;
|
||||
olen = 0;
|
||||
if (p != NULL)
|
||||
p += sizeof(o);
|
||||
|
||||
ue = up + ulen;
|
||||
for (; up < ue; up += ulen) {
|
||||
ulen = *up++;
|
||||
olen += sizeof(ulen) + ulen;
|
||||
if (data == NULL)
|
||||
continue;
|
||||
unlen = htons(ulen);
|
||||
memcpy(p, &unlen, sizeof(unlen));
|
||||
p += sizeof(unlen);
|
||||
memcpy(p, up, ulen);
|
||||
p += ulen;
|
||||
}
|
||||
if (data != NULL) {
|
||||
o.code = htons(D6_OPTION_USER_CLASS);
|
||||
o.len = htons((uint16_t)olen);
|
||||
memcpy(data, &o, sizeof(o));
|
||||
}
|
||||
|
||||
return sizeof(o) + olen;
|
||||
}
|
||||
|
||||
static size_t
|
||||
dhcp6_makevendor(void *data, const struct interface *ifp)
|
||||
{
|
||||
|
@ -245,7 +287,7 @@ dhcp6_makevendor(void *data, const struct interface *ifp)
|
|||
{
|
||||
hvlen = htons((uint16_t)vivco->len);
|
||||
memcpy(p, &hvlen, sizeof(hvlen));
|
||||
p += sizeof(len);
|
||||
p += sizeof(hvlen);
|
||||
memcpy(p, vivco->data, vivco->len);
|
||||
p += vivco->len;
|
||||
}
|
||||
|
@ -677,6 +719,8 @@ dhcp6_makemessage(struct interface *ifp)
|
|||
len += sizeof(*state->send);
|
||||
len += sizeof(o) + ifp->ctx->duid_len;
|
||||
len += sizeof(o) + sizeof(uint16_t); /* elapsed */
|
||||
if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
|
||||
len += dhcp6_makeuser(NULL, ifp);
|
||||
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
|
||||
len += dhcp6_makevendor(NULL, ifp);
|
||||
|
||||
|
@ -844,6 +888,8 @@ dhcp6_makemessage(struct interface *ifp)
|
|||
si_len = 0;
|
||||
COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len));
|
||||
|
||||
if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
|
||||
p += dhcp6_makeuser(p, ifp);
|
||||
if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
|
||||
p += dhcp6_makevendor(p, ifp);
|
||||
|
||||
|
@ -3410,13 +3456,6 @@ dhcp6_recv(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
|
|||
bytes = recvmsg_realloc(s, &ctx->rcvhdr, 0);
|
||||
if (bytes == -1) {
|
||||
logerr("%s: recvmsg_realloc", __func__);
|
||||
close(s);
|
||||
eloop_event_delete(ctx->eloop, s);
|
||||
if (ia != NULL)
|
||||
ia->dhcp6_fd = -1;
|
||||
else
|
||||
ctx->dhcp6_fd = -1;
|
||||
eloop_exit(ctx->eloop, 1);
|
||||
return;
|
||||
}
|
||||
len = (size_t)bytes;
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#define D6_OPTION_UNICAST 12
|
||||
#define D6_OPTION_STATUS_CODE 13
|
||||
#define D6_OPTION_RAPID_COMMIT 14
|
||||
#define D6_OPTION_USER_CLASS 15
|
||||
#define D6_OPTION_VENDOR_CLASS 16
|
||||
#define D6_OPTION_VENDOR_OPTS 17
|
||||
#define D6_OPTION_INTERFACE_ID 18
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 8, 2018
|
||||
.Dd April 29, 2018
|
||||
.Dt DHCPCD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -753,6 +753,17 @@ to rebind, reconfigure or exit need to include the same restrictive flags
|
|||
so that
|
||||
.Nm
|
||||
knows which process to signal.
|
||||
.Pp
|
||||
Some DHCP servers implement ClientID filtering.
|
||||
If
|
||||
.Nm
|
||||
is replacing an in-use DHCP client then you might need to adjust the clientid
|
||||
option
|
||||
.Nm
|
||||
sends to match.
|
||||
If using a DUID in place of the ClientID, edit
|
||||
.Pa @DBDIR@/duid
|
||||
accordingly.
|
||||
.Sh FILES
|
||||
.Bl -ohang
|
||||
.It Pa @SYSCONFDIR@/dhcpcd.conf
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 2, 2018
|
||||
.Dd April 29, 2018
|
||||
.Dt DHCPCD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -74,9 +74,16 @@ Example:
|
|||
.D1 # A generic 192.168.0.1 network
|
||||
.D1 profile 192.168.0.1
|
||||
.D1 static ip_address=192.168.0.98/24
|
||||
.It Ic authprotocol Ar protocol Ar algorithm Ar rdm
|
||||
.It Ic authprotocol Ar protocol Op Ar algorithm Op Ar rdm
|
||||
Authenticate DHCP messages.
|
||||
See the Supported Authentication Protocols section.
|
||||
If
|
||||
.Ar protocol
|
||||
is
|
||||
.Ar token
|
||||
then
|
||||
.Ar algorithm is
|
||||
snd_secretid/rcv_secretid so you can send and recieve different tokens.
|
||||
.It Ic authtoken Ar secretid Ar realm Ar expire Ar key
|
||||
Define a shared key for use in authentication.
|
||||
.Ar realm
|
||||
|
@ -863,7 +870,11 @@ References an option from the global definition.
|
|||
.Ss Supported Authentication Protocols
|
||||
.Bl -tag -width -indent
|
||||
.It Ic token
|
||||
Sends and expects the token with the secretid 0 and realm of "" in each message.
|
||||
Sends a plain text token the server expects and matches a token sent by
|
||||
the server.
|
||||
The tokens to not have to be the same.
|
||||
If unspecified, the token with secretid of 0 will be used in sending messages
|
||||
and validating received messages.
|
||||
.It Ic delayedrealm
|
||||
Delayed Authentication.
|
||||
.Nm dhcpcd
|
||||
|
|
|
@ -496,13 +496,12 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
|
||||
rtm->rtm_flags |= RTF_UP;
|
||||
rtm->rtm_addrs |= RTA_GATEWAY;
|
||||
#ifdef RTA_LABEL
|
||||
rtm->rtm_addrs |= RTA_LABEL;
|
||||
#endif
|
||||
if (!(rtm->rtm_flags & RTF_REJECT) &&
|
||||
!sa_is_loopback(&rt->rt_gateway))
|
||||
{
|
||||
rtm->rtm_addrs |= RTA_IFP;
|
||||
rtm->rtm_index = (unsigned short)rt->rt_ifp->index;
|
||||
if (!gateway_unspec)
|
||||
rtm->rtm_addrs |= RTA_IFP;
|
||||
if (!sa_is_unspecified(&rt->rt_ifa))
|
||||
rtm->rtm_addrs |= RTA_IFA;
|
||||
}
|
||||
|
@ -574,10 +573,8 @@ if_route(unsigned char cmd, const struct rt *rt)
|
|||
if (rtm->rtm_addrs & RTA_NETMASK)
|
||||
ADDSA(&rt->rt_netmask);
|
||||
|
||||
if (rtm->rtm_addrs & RTA_IFP) {
|
||||
rtm->rtm_index = (unsigned short)rt->rt_ifp->index;
|
||||
if (rtm->rtm_addrs & RTA_IFP)
|
||||
ADDSA((struct sockaddr *)&sdl);
|
||||
}
|
||||
|
||||
if (rtm->rtm_addrs & RTA_IFA)
|
||||
ADDSA(&rt->rt_ifa);
|
||||
|
|
|
@ -1850,6 +1850,7 @@ err_sla:
|
|||
logerrx("invalid code: %s", arg);
|
||||
return -1;
|
||||
}
|
||||
fp = strskipwhite(fp);
|
||||
if (fp) {
|
||||
s = parse_string(NULL, 0, fp);
|
||||
if (s == -1) {
|
||||
|
@ -1912,12 +1913,32 @@ err_sla:
|
|||
}
|
||||
if (fp)
|
||||
*fp++ = '\0';
|
||||
if (strcasecmp(arg, "hmacmd5") == 0 ||
|
||||
strcasecmp(arg, "hmac-md5") == 0)
|
||||
ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
|
||||
else {
|
||||
logerrx("%s: unsupported algorithm", arg);
|
||||
return 1;
|
||||
if (ifo->auth.protocol == AUTH_PROTO_TOKEN) {
|
||||
np = strchr(arg, '/');
|
||||
if (np) {
|
||||
if (fp == NULL || np < fp)
|
||||
*np++ = '\0';
|
||||
else
|
||||
np = NULL;
|
||||
}
|
||||
if (parse_uint32(&ifo->auth.token_snd_secretid,
|
||||
arg) == -1)
|
||||
logerrx("%s: not a number", arg);
|
||||
else
|
||||
ifo->auth.token_rcv_secretid =
|
||||
ifo->auth.token_snd_secretid;
|
||||
if (np &&
|
||||
parse_uint32(&ifo->auth.token_rcv_secretid,
|
||||
np) == -1)
|
||||
logerrx("%s: not a number", arg);
|
||||
} else {
|
||||
if (strcasecmp(arg, "hmacmd5") == 0 ||
|
||||
strcasecmp(arg, "hmac-md5") == 0)
|
||||
ifo->auth.algorithm = AUTH_ALG_HMAC_MD5;
|
||||
else {
|
||||
logerrx("%s: unsupported algorithm", arg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
arg = fp;
|
||||
if (arg == NULL) {
|
||||
|
|
|
@ -749,7 +749,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
|
|||
struct in6_addr pi_prefix;
|
||||
struct ipv6_addr *ap;
|
||||
struct dhcp_opt *dho;
|
||||
uint8_t new_rap, new_data;
|
||||
bool new_rap, new_data;
|
||||
uint32_t old_lifetime;
|
||||
__printflike(1, 2) void (*logfunc)(const char *, ...);
|
||||
#ifdef IPV6_MANAGETEMPADDR
|
||||
uint8_t new_ap;
|
||||
|
@ -764,25 +765,25 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
|
|||
}
|
||||
|
||||
if (len < sizeof(struct nd_router_advert)) {
|
||||
logerr("IPv6 RA packet too short from %s", ctx->sfrom);
|
||||
logerrx("IPv6 RA packet too short from %s", ctx->sfrom);
|
||||
return;
|
||||
}
|
||||
|
||||
/* RFC 4861 7.1.2 */
|
||||
if (hoplimit != 255) {
|
||||
logerr("invalid hoplimit(%d) in RA from %s",
|
||||
logerrx("invalid hoplimit(%d) in RA from %s",
|
||||
hoplimit, ctx->sfrom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
|
||||
logerr("RA from non local address %s", ctx->sfrom);
|
||||
logerrx("RA from non local address %s", ctx->sfrom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(ifp->options->options & DHCPCD_IPV6RS)) {
|
||||
#ifdef DEBUG_RS
|
||||
logerr("%s: unexpected RA from %s",
|
||||
logerrx("%s: unexpected RA from %s",
|
||||
ifp->name, ctx->sfrom);
|
||||
#endif
|
||||
return;
|
||||
|
@ -820,9 +821,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
|
|||
free(rap->data);
|
||||
rap->data_len = 0;
|
||||
}
|
||||
new_data = 1;
|
||||
new_data = true;
|
||||
} else
|
||||
new_data = 0;
|
||||
new_data = false;
|
||||
if (rap == NULL) {
|
||||
rap = calloc(1, sizeof(*rap));
|
||||
if (rap == NULL) {
|
||||
|
@ -833,9 +834,9 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
|
|||
rap->from = ctx->from.sin6_addr;
|
||||
strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
|
||||
TAILQ_INIT(&rap->addrs);
|
||||
new_rap = 1;
|
||||
new_rap = true;
|
||||
} else
|
||||
new_rap = 0;
|
||||
new_rap = false;
|
||||
if (rap->data_len == 0) {
|
||||
rap->data = malloc(len);
|
||||
if (rap->data == NULL) {
|
||||
|
@ -858,7 +859,11 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
|
|||
|
||||
clock_gettime(CLOCK_MONOTONIC, &rap->acquired);
|
||||
rap->flags = nd_ra->nd_ra_flags_reserved;
|
||||
old_lifetime = rap->lifetime;
|
||||
rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
|
||||
if (!new_rap && rap->lifetime == 0 && old_lifetime != 0)
|
||||
logwarnx("%s: %s: no longer a default router",
|
||||
ifp->name, rap->sfrom);
|
||||
if (nd_ra->nd_ra_reachable) {
|
||||
rap->reachable = ntohl(nd_ra->nd_ra_reachable);
|
||||
if (rap->reachable > MAX_REACHABLE_TIME)
|
||||
|
@ -1529,9 +1534,6 @@ ipv6nd_handledata(void *arg)
|
|||
len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0);
|
||||
if (len == -1) {
|
||||
logerr(__func__);
|
||||
eloop_event_delete(ctx->eloop, ctx->nd_fd);
|
||||
close(ctx->nd_fd);
|
||||
ctx->nd_fd = -1;
|
||||
return;
|
||||
}
|
||||
ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
|
||||
|
|
|
@ -359,7 +359,7 @@ rt_add(struct rt *nrt, struct rt *ort)
|
|||
* As such, we need to delete and re-add the route to flush children
|
||||
* to correct the flags. */
|
||||
if (change && ort != NULL && ort->rt_flags & RTF_CLONING)
|
||||
change = true;
|
||||
change = false;
|
||||
#endif
|
||||
|
||||
if (change) {
|
||||
|
|
Loading…
Reference in New Issue