From c40a479dcf295c00a7caaf10befdaa0b3865d23e Mon Sep 17 00:00:00 2001 From: roy Date: Fri, 30 Jan 2015 09:47:05 +0000 Subject: [PATCH] Sync --- external/bsd/dhcpcd/dist/arp.c | 4 +- external/bsd/dhcpcd/dist/arp.h | 6 +- external/bsd/dhcpcd/dist/auth.c | 4 +- external/bsd/dhcpcd/dist/auth.h | 4 +- external/bsd/dhcpcd/dist/common.c | 4 +- external/bsd/dhcpcd/dist/common.h | 4 +- external/bsd/dhcpcd/dist/control.c | 4 +- external/bsd/dhcpcd/dist/control.h | 4 +- external/bsd/dhcpcd/dist/crypt/crypt.h | 4 +- external/bsd/dhcpcd/dist/crypt/hmac_md5.c | 4 +- external/bsd/dhcpcd/dist/defs.h | 6 +- external/bsd/dhcpcd/dist/dev.h | 4 +- external/bsd/dhcpcd/dist/dhcp-common.c | 4 +- external/bsd/dhcpcd/dist/dhcp-common.h | 4 +- external/bsd/dhcpcd/dist/dhcp.c | 54 +- external/bsd/dhcpcd/dist/dhcp.h | 16 +- external/bsd/dhcpcd/dist/dhcp6.c | 19 +- external/bsd/dhcpcd/dist/dhcp6.h | 14 +- .../bsd/dhcpcd/dist/dhcpcd-definitions.conf | 4 +- external/bsd/dhcpcd/dist/dhcpcd-embedded.c | 4 +- external/bsd/dhcpcd/dist/dhcpcd-embedded.h | 4 +- .../bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in | 4 +- external/bsd/dhcpcd/dist/dhcpcd.8.in | 18 +- external/bsd/dhcpcd/dist/dhcpcd.c | 38 +- external/bsd/dhcpcd/dist/dhcpcd.conf.5.in | 20 +- external/bsd/dhcpcd/dist/dhcpcd.h | 7 +- external/bsd/dhcpcd/dist/duid.c | 4 +- external/bsd/dhcpcd/dist/duid.h | 4 +- external/bsd/dhcpcd/dist/eloop.c | 4 +- external/bsd/dhcpcd/dist/eloop.h | 4 +- external/bsd/dhcpcd/dist/if-bsd.c | 158 ++++- external/bsd/dhcpcd/dist/if-options.c | 55 +- external/bsd/dhcpcd/dist/if-options.h | 7 +- external/bsd/dhcpcd/dist/if.c | 46 +- external/bsd/dhcpcd/dist/if.h | 9 +- external/bsd/dhcpcd/dist/ipv4.c | 4 +- external/bsd/dhcpcd/dist/ipv4.h | 4 +- external/bsd/dhcpcd/dist/ipv4ll.c | 4 +- external/bsd/dhcpcd/dist/ipv6.c | 626 +++++++++++++++--- external/bsd/dhcpcd/dist/ipv6.h | 73 +- external/bsd/dhcpcd/dist/ipv6nd.c | 71 +- external/bsd/dhcpcd/dist/ipv6nd.h | 8 +- external/bsd/dhcpcd/dist/script.c | 10 +- 43 files changed, 1077 insertions(+), 276 deletions(-) diff --git a/external/bsd/dhcpcd/dist/arp.c b/external/bsd/dhcpcd/dist/arp.c index aababc1f4f5c..3cdcb2bcfaf6 100644 --- a/external/bsd/dhcpcd/dist/arp.c +++ b/external/bsd/dhcpcd/dist/arp.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: arp.c,v 1.8 2014/11/26 13:43:06 roy Exp $"); + __RCSID("$NetBSD: arp.c,v 1.9 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/arp.h b/external/bsd/dhcpcd/dist/arp.h index b6446c403401..2675b8896360 100644 --- a/external/bsd/dhcpcd/dist/arp.h +++ b/external/bsd/dhcpcd/dist/arp.h @@ -1,8 +1,8 @@ -/* $NetBSD: arp.h,v 1.7 2014/12/19 10:54:08 roy Exp $ */ +/* $NetBSD: arp.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -77,6 +77,6 @@ void arp_free(struct arp_state *); void arp_free_but(struct arp_state *); void arp_close(struct interface *); #else -#define arp_close(a) +#define arp_close(a) {} #endif #endif diff --git a/external/bsd/dhcpcd/dist/auth.c b/external/bsd/dhcpcd/dist/auth.c index 0d5b3373c07a..a6ac9ab63044 100644 --- a/external/bsd/dhcpcd/dist/auth.c +++ b/external/bsd/dhcpcd/dist/auth.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: auth.c,v 1.7 2014/11/14 12:00:54 roy Exp $"); + __RCSID("$NetBSD: auth.c,v 1.8 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/auth.h b/external/bsd/dhcpcd/dist/auth.h index 6c3e740fee03..d70113736b71 100644 --- a/external/bsd/dhcpcd/dist/auth.h +++ b/external/bsd/dhcpcd/dist/auth.h @@ -1,8 +1,8 @@ -/* $NetBSD: auth.h,v 1.7 2014/11/14 12:00:54 roy Exp $ */ +/* $NetBSD: auth.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/common.c b/external/bsd/dhcpcd/dist/common.c index 3e868058a4e0..f419a1f1339a 100644 --- a/external/bsd/dhcpcd/dist/common.c +++ b/external/bsd/dhcpcd/dist/common.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: common.c,v 1.7 2014/11/14 12:00:54 roy Exp $"); + __RCSID("$NetBSD: common.c,v 1.8 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/common.h b/external/bsd/dhcpcd/dist/common.h index 0ebf8b44152f..b1dfcfbd437c 100644 --- a/external/bsd/dhcpcd/dist/common.h +++ b/external/bsd/dhcpcd/dist/common.h @@ -1,8 +1,8 @@ -/* $NetBSD: common.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: common.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/control.c b/external/bsd/dhcpcd/dist/control.c index 52dabacc366e..f5618815eaf5 100644 --- a/external/bsd/dhcpcd/dist/control.c +++ b/external/bsd/dhcpcd/dist/control.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: control.c,v 1.6 2014/11/07 20:51:02 roy Exp $"); + __RCSID("$NetBSD: control.c,v 1.7 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/control.h b/external/bsd/dhcpcd/dist/control.h index 28537996de01..0573f029fd68 100644 --- a/external/bsd/dhcpcd/dist/control.h +++ b/external/bsd/dhcpcd/dist/control.h @@ -1,8 +1,8 @@ -/* $NetBSD: control.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: control.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/crypt/crypt.h b/external/bsd/dhcpcd/dist/crypt/crypt.h index e8e1ac0181a2..40d39380666a 100644 --- a/external/bsd/dhcpcd/dist/crypt/crypt.h +++ b/external/bsd/dhcpcd/dist/crypt/crypt.h @@ -1,8 +1,8 @@ -/* $NetBSD: crypt.h,v 1.5 2014/11/07 20:51:03 roy Exp $ */ +/* $NetBSD: crypt.h,v 1.6 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/crypt/hmac_md5.c b/external/bsd/dhcpcd/dist/crypt/hmac_md5.c index f07ba505c0ba..d9d3bb474d82 100644 --- a/external/bsd/dhcpcd/dist/crypt/hmac_md5.c +++ b/external/bsd/dhcpcd/dist/crypt/hmac_md5.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: hmac_md5.c,v 1.5 2014/11/07 20:51:03 roy Exp $"); + __RCSID("$NetBSD: hmac_md5.c,v 1.6 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/defs.h b/external/bsd/dhcpcd/dist/defs.h index 4770b3372040..91e649770831 100644 --- a/external/bsd/dhcpcd/dist/defs.h +++ b/external/bsd/dhcpcd/dist/defs.h @@ -1,8 +1,8 @@ -/* $NetBSD: defs.h,v 1.12 2014/12/19 10:54:08 roy Exp $ */ +/* $NetBSD: defs.h,v 1.13 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "6.6.7" +#define VERSION "6.7.0" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" diff --git a/external/bsd/dhcpcd/dist/dev.h b/external/bsd/dhcpcd/dist/dev.h index 7d91852073dd..3ce22b472b53 100644 --- a/external/bsd/dhcpcd/dist/dev.h +++ b/external/bsd/dhcpcd/dist/dev.h @@ -1,8 +1,8 @@ -/* $NetBSD: dev.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: dev.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/external/bsd/dhcpcd/dist/dhcp-common.c b/external/bsd/dhcpcd/dist/dhcp-common.c index 1a1314c4337d..bf4a42b3a8d7 100644 --- a/external/bsd/dhcpcd/dist/dhcp-common.c +++ b/external/bsd/dhcpcd/dist/dhcp-common.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: dhcp-common.c,v 1.6 2014/11/07 20:51:02 roy Exp $"); + __RCSID("$NetBSD: dhcp-common.c,v 1.7 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/dhcp-common.h b/external/bsd/dhcpcd/dist/dhcp-common.h index 812ecf9f9190..ecf5954a9aa2 100644 --- a/external/bsd/dhcpcd/dist/dhcp-common.h +++ b/external/bsd/dhcpcd/dist/dhcp-common.h @@ -1,8 +1,8 @@ -/* $NetBSD: dhcp-common.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: dhcp-common.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/dhcp.c b/external/bsd/dhcpcd/dist/dhcp.c index 73dc3fa28b72..9ec6efbea8c2 100644 --- a/external/bsd/dhcpcd/dist/dhcp.c +++ b/external/bsd/dhcpcd/dist/dhcp.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: dhcp.c,v 1.26 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: dhcp.c,v 1.27 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -2489,6 +2489,16 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp, /* reset the message counter */ state->interval = 0; + /* Ensure that no reject options are present */ + for (i = 1; i < 255; i++) { + if (has_option_mask(ifo->rejectmask, i) && + get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) == 0) + { + log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from); + return; + } + } + if (type == DHCP_NAK) { /* For NAK, only check if we require the ServerID */ if (has_option_mask(ifo->requiremask, DHO_SERVERID) && @@ -2525,6 +2535,23 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp, return; } + /* Ensure that all required options are present */ + for (i = 1; i < 255; i++) { + if (has_option_mask(ifo->requiremask, i) && + get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) != 0) + { + /* If we are bootp, then ignore the need for serverid. + * To ignore bootp, require dhcp_message_type. + * However, nothing really stops bootp from providing + * DHCP style options as well so the above isn't + * always true. */ + if (type == 0 && i == DHO_SERVERID) + continue; + log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from); + return; + } + } + /* DHCP Auto-Configure, RFC 2563 */ if (type == DHCP_OFFER && dhcp->yiaddr == 0) { log_dhcp(LOG_WARNING, "no address given", iface, dhcp, from); @@ -2571,20 +2598,6 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp, return; } - /* Ensure that all required options are present */ - for (i = 1; i < 255; i++) { - if (has_option_mask(ifo->requiremask, i) && - get_option_uint8(iface->ctx, &tmp, dhcp, (uint8_t)i) != 0) - { - /* If we are bootp, then ignore the need for serverid. - * To ignore bootp, require dhcp_message_type. */ - if (type == 0 && i == DHO_SERVERID) - continue; - log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from); - return; - } - } - /* Ensure that the address offered is valid */ if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) && (dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) && @@ -2879,7 +2892,14 @@ dhcp_open(struct interface *ifp) if (state->raw_fd == -1) { state->raw_fd = if_openrawsocket(ifp, ETHERTYPE_IP); if (state->raw_fd == -1) { - syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name); + if (errno == ENOENT) { + syslog(LOG_ERR, "%s not found", if_pfname); + /* May as well disable IPv4 entirely at + * this point as we really need it. */ + ifp->options->options &= ~DHCPCD_IPV4; + } else + syslog(LOG_ERR, "%s: %s: %m", + __func__, ifp->name); return -1; } eloop_event_add(ifp->ctx->eloop, diff --git a/external/bsd/dhcpcd/dist/dhcp.h b/external/bsd/dhcpcd/dist/dhcp.h index e8fef505655b..fa9d6aed8462 100644 --- a/external/bsd/dhcpcd/dist/dhcp.h +++ b/external/bsd/dhcpcd/dist/dhcp.h @@ -1,8 +1,8 @@ -/* $NetBSD: dhcp.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: dhcp.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -292,13 +292,13 @@ void dhcp_close(struct interface *); void dhcp_free(struct interface *); int dhcp_dump(struct interface *); #else -#define dhcp_drop(a, b) +#define dhcp_drop(a, b) {} #define dhcp_start(a) {} -#define dhcp_reboot(a, b) b = b -#define dhcp_reboot_newopts(a, b) -#define dhcp_close(a) -#define dhcp_free(a) -#define dhcp_dump(a) -1 +#define dhcp_reboot(a, b) (b = b) +#define dhcp_reboot_newopts(a, b) (b = b) +#define dhcp_close(a) {} +#define dhcp_free(a) {} +#define dhcp_dump(a) (-1) #endif #endif diff --git a/external/bsd/dhcpcd/dist/dhcp6.c b/external/bsd/dhcpcd/dist/dhcp6.c index 1ca1e17acffb..68d47e0f60fb 100644 --- a/external/bsd/dhcpcd/dist/dhcp6.c +++ b/external/bsd/dhcpcd/dist/dhcp6.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: dhcp6.c,v 1.8 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: dhcp6.c,v 1.9 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -1739,6 +1739,7 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid, a->ia_type = ot; memcpy(a->iaid, iaid, sizeof(a->iaid)); a->addr = iap->addr; + a->created = *acquired; /* * RFC 5942 Section 5 @@ -1821,6 +1822,7 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid, } a->iface = ifp; a->flags = IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX; + a->created = *acquired; a->dadcallback = dhcp6_dadcallback; a->ia_type = D6_OPTION_IA_PD; memcpy(a->iaid, iaid, sizeof(a->iaid)); @@ -2287,7 +2289,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, a->dadcallback = dhcp6_dadcallback; a->delegating_iface = ifs; memcpy(&a->iaid, &prefix->iaid, sizeof(a->iaid)); - a->acquired = prefix->acquired; + a->created = a->acquired = prefix->acquired; a->prefix_pltime = prefix->prefix_pltime; a->prefix_vltime = prefix->prefix_vltime; a->prefix = addr; @@ -2306,6 +2308,7 @@ dhcp6_ifdelegateaddr(struct interface *ifp, struct ipv6_addr *prefix, /* Keep our flags */ a->flags |= ap->flags; a->flags &= ~IPV6_AF_NEW; + a->created = ap->created; free(ap); } } @@ -2686,6 +2689,14 @@ dhcp6_handledata(void *arg) ifp->name, opt->var, ctx->sfrom); return; } + if (has_option_mask(ifo->rejectmask6, opt->option) && + dhcp6_getmoption(opt->option, r, len)) + { + syslog(LOG_WARNING, + "%s: reject DHCPv6 (option %s) from %s", + ifp->name, opt->var, ctx->sfrom); + return; + } } /* Authenticate the message */ @@ -3292,7 +3303,7 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason) state = D6_STATE(ifp); if (state) { dhcp_auth_reset(&state->auth); - if (options & DHCPCD_RELEASE) { + if (drop && options & DHCPCD_RELEASE) { if (ifp->carrier == LINK_UP) dhcp6_startrelease(ifp); unlink(state->leasefile); diff --git a/external/bsd/dhcpcd/dist/dhcp6.h b/external/bsd/dhcpcd/dist/dhcp6.h index d3d72726b666..04f820f6432e 100644 --- a/external/bsd/dhcpcd/dist/dhcp6.h +++ b/external/bsd/dhcpcd/dist/dhcp6.h @@ -1,8 +1,8 @@ -/* $NetBSD: dhcp6.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: dhcp6.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -248,13 +248,13 @@ void dhcp6_drop(struct interface *, const char *); int dhcp6_dump(struct interface *); #else #define dhcp6_findaddr(a, b, c) (0) -#define dhcp6_find_delegates(a) +#define dhcp6_find_delegates(a) {} #define dhcp6_start(a, b) (0) -#define dhcp6_reboot(a) -#define dhcp6_env(a, b, c, d, e) -#define dhcp6_free(a) +#define dhcp6_reboot(a) {} +#define dhcp6_env(a, b, c, d, e) {} +#define dhcp6_free(a) {} #define dhcp6_dadcompleted(a) (0) -#define dhcp6_drop(a, b) +#define dhcp6_drop(a, b) {} #define dhcp6_dump(a) (-1) #endif diff --git a/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf b/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf index d9fe26f6c161..cb8bddaf47ca 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf +++ b/external/bsd/dhcpcd/dist/dhcpcd-definitions.conf @@ -1,6 +1,6 @@ -# $NetBSD: dhcpcd-definitions.conf,v 1.6 2014/11/07 20:51:02 roy Exp $ +# $NetBSD: dhcpcd-definitions.conf,v 1.7 2015/01/30 09:47:05 roy Exp $ -# Copyright (c) 2006-2014 Roy Marples +# Copyright (c) 2006-2015 Roy Marples # All rights reserved # DHCP option definitions for dhcpcd(8) diff --git a/external/bsd/dhcpcd/dist/dhcpcd-embedded.c b/external/bsd/dhcpcd/dist/dhcpcd-embedded.c index 59f9ab05ebf1..efb81f4eaa4e 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-embedded.c +++ b/external/bsd/dhcpcd/dist/dhcpcd-embedded.c @@ -1,5 +1,5 @@ #include - __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.6 2014/11/07 20:51:02 roy Exp $"); + __RCSID("$NetBSD: dhcpcd-embedded.c,v 1.7 2015/01/30 09:47:05 roy Exp $"); /* * DO NOT EDIT @@ -9,7 +9,7 @@ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2013 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/dhcpcd-embedded.h b/external/bsd/dhcpcd/dist/dhcpcd-embedded.h index 3d985c4f0ef3..a7baa3542874 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-embedded.h +++ b/external/bsd/dhcpcd/dist/dhcpcd-embedded.h @@ -1,8 +1,8 @@ -/* $NetBSD: dhcpcd-embedded.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: dhcpcd-embedded.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in b/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in index a42986975a47..2860f6fe3c43 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in +++ b/external/bsd/dhcpcd/dist/dhcpcd-run-hooks.8.in @@ -1,5 +1,5 @@ -.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.12 2014/11/07 20:51:02 roy Exp $ -.\" Copyright (c) 2006-2014 Roy Marples +.\" $NetBSD: dhcpcd-run-hooks.8.in,v 1.13 2015/01/30 09:47:05 roy Exp $ +.\" Copyright (c) 2006-2015 Roy Marples .\" All rights reserved .\" .\" Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/dhcpcd.8.in b/external/bsd/dhcpcd/dist/dhcpcd.8.in index 2f2ba66265da..6e5e8b49b618 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.8.in +++ b/external/bsd/dhcpcd/dist/dhcpcd.8.in @@ -1,5 +1,5 @@ -.\" $NetBSD: dhcpcd.8.in,v 1.39 2014/12/17 20:50:08 roy Exp $ -.\" Copyright (c) 2006-2014 Roy Marples +.\" $NetBSD: dhcpcd.8.in,v 1.40 2015/01/30 09:47:05 roy Exp $ +.\" Copyright (c) 2006-2015 Roy Marples .\" All rights reserved .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 26, 2014 +.Dd January 15, 2015 .Dt DHCPCD 8 .Os .Sh NAME @@ -123,6 +123,14 @@ and .Li RFC 6106 . .Pp .Nm +is also an implementation of the IPv6 Privacy Extensions to AutoConf as +specified in +.Li RFC 4941 . +This feature needs to be enabled in the kernel and +.Nm +will start using it. +.Pp +.Nm is also an implemenation of the DHCPv6 client as specified in .Li RFC 3315 . By default, @@ -702,8 +710,8 @@ RFC\ 951, RFC\ 1534, RFC\ 2104, RFC\ 2131, RFC\ 2132, RFC\ 2563, RFC\ 2855, RFC\ 3004, RFC\ 3118, RFC\ 3203, RFC\ 3315, RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3495, RFC\ 3925, RFC\ 3927, RFC\ 4039, RFC\ 4075, RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4074, RFC\ 4861, RFC\ 4833, -RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6603, RFC\ 6704, -RFC\ 7217. +RFC\ 4941, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106, RFC\ 6334, RFC\ 6603, +RFC\ 6704, RFC\ 7217. .Sh AUTHORS .An Roy Marples Aq Mt roy@marples.name .Sh BUGS diff --git a/external/bsd/dhcpcd/dist/dhcpcd.c b/external/bsd/dhcpcd/dist/dhcpcd.c index 3fb26df7c3be..f55c4f5255cf 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.c +++ b/external/bsd/dhcpcd/dist/dhcpcd.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: dhcpcd.c,v 1.21 2014/12/20 13:15:48 prlw1 Exp $"); + __RCSID("$NetBSD: dhcpcd.c,v 1.22 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -28,7 +28,7 @@ * SUCH DAMAGE. */ -const char dhcpcd_copyright[] = "Copyright (c) 2006-2014 Roy Marples"; +const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples"; #define _WITH_DPRINTF /* Stop FreeBSD bitching */ @@ -320,6 +320,7 @@ stop_interface(struct interface *ifp) dhcp6_drop(ifp, NULL); ipv6nd_drop(ifp); + ipv6_drop(ifp); dhcp_drop(ifp, "STOP"); arp_close(ifp); if (ifp->options->options & DHCPCD_DEPARTED) @@ -388,7 +389,7 @@ configure_interface1(struct interface *ifp) ifp->options->options & DHCPCD_IPV6RA_OWN ? 1 : 0); if (ra_global == -1 || ra_iface == -1) ifo->options &= ~DHCPCD_IPV6RS; - else if (ra_iface == 0) + else if (ra_iface == 0 && !(ifp->ctx->options & DHCPCD_TEST)) ifo->options |= DHCPCD_IPV6RA_OWN; } @@ -605,11 +606,7 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, script_runreason(ifp, "NOCARRIER"); dhcp6_drop(ifp, "EXPIRE6"); ipv6nd_drop(ifp); - /* Don't blindly delete our knowledge of LL addresses. - * We need to listen to what the kernel does with - * them as some OS's will remove, mark tentative or - * do nothing. */ - ipv6_free_ll_callbacks(ifp); + ipv6_drop(ifp); dhcp_drop(ifp, "EXPIRE"); arp_close(ifp); } @@ -625,8 +622,11 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags, #endif if (ifp->wireless) if_getssid(ifp); - configure_interface(ifp, ctx->argc, ctx->argv); + dhcpcd_initstate(ifp); script_runreason(ifp, "CARRIER"); + /* RFC4941 Section 3.5 */ + if (ifp->options->options & DHCPCD_IPV6RA_OWN) + ipv6_gentempifid(ifp); dhcpcd_startinterface(ifp); } } @@ -907,6 +907,10 @@ dhcpcd_handleinterface(void *arg, int action, const char *ifname) i = -1; ifs = if_discover(ctx, -1, UNCONST(argv)); + if (ifs == NULL) { + syslog(LOG_ERR, "%s: if_discover: %m", __func__); + return -1; + } TAILQ_FOREACH_SAFE(ifp, ifs, next, ifn) { if (strcmp(ifp->name, ifname) != 0) continue; @@ -1007,8 +1011,10 @@ reconf_reboot(struct dhcpcd_ctx *ctx, int action, int argc, char **argv, int oi) struct interface *ifn, *ifp; ifs = if_discover(ctx, argc - oi, argv + oi); - if (ifs == NULL) + if (ifs == NULL) { + syslog(LOG_ERR, "%s: if_discover: %m", __func__); return; + } while ((ifp = TAILQ_FIRST(ifs))) { TAILQ_REMOVE(ifs, ifp, next); @@ -1514,8 +1520,10 @@ main(int argc, char **argv) /* We need to try and find the interface so we can * load the hardware address to compare automated IAID */ ctx.ifaces = if_discover(&ctx, 1, argv + optind); - if (ctx.ifaces == NULL) + if (ctx.ifaces == NULL) { + syslog(LOG_ERR, "if_discover: %m"); goto exit_failure; + } ifp = TAILQ_FIRST(ctx.ifaces); if (ifp == NULL) { ifp = calloc(1, sizeof(*ifp)); @@ -1707,12 +1715,16 @@ main(int argc, char **argv) dev_start(&ctx); ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv); + if (ctx.ifaces == NULL) { + syslog(LOG_ERR, "if_discover: %m"); + goto exit_failure; + } for (i = 0; i < ctx.ifc; i++) { if (if_find(&ctx, ctx.ifv[i]) == NULL) syslog(LOG_ERR, "%s: interface not found or invalid", ctx.ifv[i]); } - if (ctx.ifaces == NULL || TAILQ_FIRST(ctx.ifaces) == NULL) { + if (TAILQ_FIRST(ctx.ifaces) == NULL) { if (ctx.ifc == 0) syslog(LOG_ERR, "no valid interfaces found"); else diff --git a/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in b/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in index 13bff42df6a4..0b376997e17f 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in +++ b/external/bsd/dhcpcd/dist/dhcpcd.conf.5.in @@ -1,5 +1,5 @@ -.\" $NetBSD: dhcpcd.conf.5.in,v 1.17 2014/12/17 20:50:08 roy Exp $ -.\" Copyright (c) 2006-2014 Roy Marples +.\" $NetBSD: dhcpcd.conf.5.in,v 1.18 2015/01/30 09:47:05 roy Exp $ +.\" Copyright (c) 2006-2015 Roy Marples .\" All rights reserved .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 13, 2014 +.Dd January 20, 2015 .Dt DHCPCD.CONF 5 .Os .Sh NAME @@ -345,6 +345,12 @@ encodes the FQDN hostname as specified in .It Ic interface Ar interface Subsequent options are only parsed for this .Ar interface . +.It Ic ipv6ra_autoconf +Generate SLAAC addresses for each Prefix advertised by a +Router Advertisement message with the Auto flag set. +On by default. +.It Ic ipv6ra_noautoconf +Disables the above option. .It Ic ipv6ra_fork By default, when .Nm dhcpcd @@ -484,6 +490,14 @@ To enforce that only responds to DHCP servers and not BOOTP servers, you can .Ic require .Ar dhcp_message_type . +This isn't an exact science though because a BOOTP server can send DHCP like +options. +.It Ic reject Ar option +Reject a DHCP message that contains the +.Ar option . +This is useful when you cannot use +.Ic require +to select / de-select BOOTP messages. .It Ic script Ar script Use .Ar script diff --git a/external/bsd/dhcpcd/dist/dhcpcd.h b/external/bsd/dhcpcd/dist/dhcpcd.h index 185e05f1fcc7..2fc8aa3694c7 100644 --- a/external/bsd/dhcpcd/dist/dhcpcd.h +++ b/external/bsd/dhcpcd/dist/dhcpcd.h @@ -1,8 +1,8 @@ -/* $NetBSD: dhcpcd.h,v 1.8 2014/11/26 13:43:06 roy Exp $ */ +/* $NetBSD: dhcpcd.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -62,6 +62,9 @@ struct interface { struct dhcpcd_ctx *ctx; TAILQ_ENTRY(interface) next; char name[IF_NAMESIZE]; +#ifdef __linux + char alias[IF_NAMESIZE]; +#endif unsigned int index; unsigned int flags; sa_family_t family; diff --git a/external/bsd/dhcpcd/dist/duid.c b/external/bsd/dhcpcd/dist/duid.c index 4b42769df7f2..e4efc7227c21 100644 --- a/external/bsd/dhcpcd/dist/duid.c +++ b/external/bsd/dhcpcd/dist/duid.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: duid.c,v 1.6 2014/11/07 20:51:02 roy Exp $"); + __RCSID("$NetBSD: duid.c,v 1.7 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/duid.h b/external/bsd/dhcpcd/dist/duid.h index d68a02d8e9d0..9582f568b982 100644 --- a/external/bsd/dhcpcd/dist/duid.h +++ b/external/bsd/dhcpcd/dist/duid.h @@ -1,8 +1,8 @@ -/* $NetBSD: duid.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: duid.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/eloop.c b/external/bsd/dhcpcd/dist/eloop.c index 39e2b7b64d33..28171e2f509b 100644 --- a/external/bsd/dhcpcd/dist/eloop.c +++ b/external/bsd/dhcpcd/dist/eloop.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: eloop.c,v 1.7 2014/11/14 12:00:54 roy Exp $"); + __RCSID("$NetBSD: eloop.c,v 1.8 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/eloop.h b/external/bsd/dhcpcd/dist/eloop.h index a8b877e23a40..d21e0b71537a 100644 --- a/external/bsd/dhcpcd/dist/eloop.h +++ b/external/bsd/dhcpcd/dist/eloop.h @@ -1,8 +1,8 @@ -/* $NetBSD: eloop.h,v 1.6 2014/11/07 20:51:02 roy Exp $ */ +/* $NetBSD: eloop.h,v 1.7 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/if-bsd.c b/external/bsd/dhcpcd/dist/if-bsd.c index 681f8ffa2127..42bc1ba0b7df 100644 --- a/external/bsd/dhcpcd/dist/if-bsd.c +++ b/external/bsd/dhcpcd/dist/if-bsd.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: if-bsd.c,v 1.16 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: if-bsd.c,v 1.17 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,7 @@ if_openlinksocket(void) #endif } +#if defined(INET) || defined(INET6) static void if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) { @@ -160,6 +162,7 @@ if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) link_addr(ifp->name, sdl); #endif } +#endif static int if_getssid1(const char *ifname, uint8_t *ssid) @@ -260,6 +263,8 @@ if_vimaster(const char *ifname) } #ifdef INET +const char *if_pfname = "Berkley Packet Filter"; + int if_openrawsocket(struct interface *ifp, int protocol) { @@ -616,6 +621,8 @@ if_address6(const struct ipv6_addr *a, int action) if (a->autoconf) ifa.ifra_flags |= IN6_IFF_AUTOCONF; #endif + if (a->flags & IPV6_AF_TEMPORARY) + ifa.ifra_flags |= IN6_IFF_TEMPORARY; #define ADDADDR(v, addr) { \ (v)->sin6_family = AF_INET6; \ @@ -785,6 +792,51 @@ if_addrflags6(const struct in6_addr *addr, const struct interface *ifp) } return flags; } + +int +if_getlifetime6(struct ipv6_addr *ia) +{ + int s, r; + struct in6_ifreq ifr6; + + s = socket(PF_INET6, SOCK_DGRAM, 0); + r = -1; + if (s != -1) { + memset(&ifr6, 0, sizeof(ifr6)); + strncpy(ifr6.ifr_name, ia->iface->name, sizeof(ifr6.ifr_name)); + ifr6.ifr_addr.sin6_family = AF_INET6; + ifr6.ifr_addr.sin6_addr = ia->addr; + ifa_scope(&ifr6.ifr_addr, ia->iface->index); + if (ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) != -1) { + time_t t; + struct in6_addrlifetime *lifetime; + + t = time(NULL); + lifetime = &ifr6.ifr_ifru.ifru_lifetime; + + if (lifetime->ia6t_preferred) + ia->prefix_pltime = + (uint32_t)(lifetime->ia6t_preferred - + MIN(t, lifetime->ia6t_preferred)); + else + ia->prefix_pltime = ND6_INFINITE_LIFETIME; + if (lifetime->ia6t_expire) { + ia->prefix_vltime = + (uint32_t)(lifetime->ia6t_expire - + MIN(t, lifetime->ia6t_expire)); + /* Calculate the created time */ + get_monotonic(&ia->created); + ia->created.tv_sec -= + lifetime->ia6t_vltime - ia->prefix_vltime; + } else + ia->prefix_vltime = ND6_INFINITE_LIFETIME; + + r = 0; + } + close(s); + } + return r; +} #endif int @@ -806,7 +858,7 @@ if_managelink(struct dhcpcd_ctx *ctx) #endif #ifdef INET6 struct rt6 rt6; - struct in6_addr ia6; + struct in6_addr ia6, net6; struct sockaddr_in6 *sin6; int ifa_flags; #endif @@ -972,6 +1024,10 @@ if_managelink(struct dhcpcd_ctx *ctx) rti_info[RTAX_IFA]; ia6 = sin6->sin6_addr; DESCOPE(&ia6); + sin6 = (struct sockaddr_in6*)(void *) + rti_info[RTAX_NETMASK]; + net6 = sin6->sin6_addr; + DESCOPE(&net6); if (rtm->rtm_type == RTM_NEWADDR) { ifa_flags = if_addrflags6(&ia6, ifp); if (ifa_flags == -1) @@ -979,7 +1035,8 @@ if_managelink(struct dhcpcd_ctx *ctx) } else ifa_flags = 0; ipv6_handleifa(ctx, rtm->rtm_type, NULL, - ifp->name, &ia6, ifa_flags); + ifp->name, &ia6, ipv6_prefixlen(&net6), + ifa_flags); break; #endif } @@ -1035,6 +1092,65 @@ inet6_sysctl(int code, int val, int action) } #endif +#ifndef IPV6CTL_TEMPVLTIME +#define get_inet6_sysctlbyname(code) inet6_sysctlbyname(code, 0, 0) +#define set_inet6_sysctlbyname(code, val) inet6_sysctlbyname(code, val, 1) +static int +inet6_sysctlbyname(const char *name, int val, int action) +{ + size_t size; + + size = sizeof(val); + if (action) { + if (sysctlbyname(name, NULL, 0, &val, size) == -1) + return -1; + return 0; + } + if (sysctlbyname(name, &val, &size, NULL, 0) == -1) + return -1; + return val; +} +#endif + +int +ip6_use_tempaddr(__unused const char *ifname) +{ + int val; + +#ifdef IPV6CTL_USETEMPADDR + val = get_inet6_sysctl(IPV6CTL_USETEMPADDR); +#else + val = get_inet6_sysctlbyname("net.inet6.ip6.use_tempaddr"); +#endif + return val == -1 ? TEMP_PREFERRED_LIFETIME : val; +} + +int +ip6_temp_preferred_lifetime(__unused const char *ifname) +{ + int val; + +#ifdef IPV6CTL_TEMPPLTIME + val = get_inet6_sysctl(IPV6CTL_TEMPPLTIME); +#else + val = get_inet6_sysctlbyname("net.inet6.ip6.temppltime"); +#endif + return val < 0 ? TEMP_PREFERRED_LIFETIME : val; +} + +int +ip6_temp_valid_lifetime(__unused const char *ifname) +{ + int val; + +#ifdef IPV6CTL_TEMPVLTIME + val = get_inet6_sysctl(IPV6CTL_TEMPVLTIME); +#else + val = get_inet6_sysctlbyname("net.inet6.ip6.tempvltime"); +#endif + return val < 0 ? TEMP_VALID_LIFETIME : val; +} + #define del_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, -1) #define get_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, 0) #define set_if_nd6_flag(ifname, flag) if_nd6_flag(ifname, flag, 1) @@ -1186,8 +1302,16 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own) syslog(LOG_ERR, "%s: get_if_nd6_flag: ND6_IFF_OVERRIDE_RTADV: %m", ifp->name); - else if (override == 0 && !own) - return 0; + else if (override == 0 && own) { + if (set_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV) + == -1) + syslog(LOG_ERR, + "%s: set_if_nd6_flag: " + "ND6_IFF_OVERRIDE_RTADV: %m", + ifp->name); + else + override = 1; + } #endif #ifdef ND6_IFF_ACCEPT_RTADV @@ -1202,27 +1326,19 @@ if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *ifp, int own) ifp->name); if (del_if_nd6_flag(ifp->name, ND6_IFF_ACCEPT_RTADV) == -1) - { syslog(LOG_ERR, "%s: del_if_nd6_flag: " "ND6_IFF_ACCEPT_RTADV: %m", ifp->name); - return ra; - } + else + ra = 0; + } else if (ra == 0 && !own) + syslog(LOG_WARNING, + "%s: IPv6 kernel autoconf disabled", ifp->name); #ifdef ND6_IFF_OVERRIDE_RTADV - if (override == 0 && - set_if_nd6_flag(ifp->name, ND6_IFF_OVERRIDE_RTADV) - == -1) - { - syslog(LOG_ERR, - "%s: set_if_nd6_flag: " - "ND6_IFF_OVERRIDE_RTADV: %m", - ifp->name); - return ra; - } + if (override == 0 && ra) + return ctx->ra_global; #endif - return 0; - } return ra; #else return ctx->ra_global; diff --git a/external/bsd/dhcpcd/dist/if-options.c b/external/bsd/dhcpcd/dist/if-options.c index 4bd466f1e964..f4a36cd0a77f 100644 --- a/external/bsd/dhcpcd/dist/if-options.c +++ b/external/bsd/dhcpcd/dist/if-options.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: if-options.c,v 1.19 2014/11/26 13:43:06 roy Exp $"); + __RCSID("$NetBSD: if-options.c,v 1.20 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -96,6 +96,9 @@ #define O_SLAAC O_BASE + 35 #define O_GATEWAY O_BASE + 36 #define O_PFXDLGMIX O_BASE + 37 +#define O_IPV6RA_AUTOCONF O_BASE + 38 +#define O_IPV6RA_NOAUTOCONF O_BASE + 39 +#define O_REJECT O_BASE + 40 const struct option cf_options[] = { {"background", no_argument, NULL, 'b'}, @@ -149,6 +152,8 @@ const struct option cf_options[] = { {"fallback", required_argument, NULL, O_FALLBACK}, {"ipv6rs", no_argument, NULL, O_IPV6RS}, {"noipv6rs", no_argument, NULL, O_NOIPV6RS}, + {"ipv6ra_autoconf", no_argument, NULL, O_IPV6RA_AUTOCONF}, + {"ipv6ra_noautoconf", no_argument, NULL, O_IPV6RA_NOAUTOCONF}, {"ipv6ra_fork", no_argument, NULL, O_IPV6RA_FORK}, {"ipv6ra_own", no_argument, NULL, O_IPV6RA_OWN}, {"ipv6ra_own_default", no_argument, NULL, O_IPV6RA_OWN_D}, @@ -183,6 +188,7 @@ const struct option cf_options[] = { {"slaac", required_argument, NULL, O_SLAAC}, {"gateway", no_argument, NULL, O_GATEWAY}, {"ia_pd_mix", no_argument, NULL, O_PFXDLGMIX}, + {"reject", required_argument, NULL, O_REJECT}, {NULL, 0, NULL, '\0'} }; @@ -526,9 +532,14 @@ set_option_space(struct dhcpcd_ctx *ctx, const struct dhcp_opt **d, size_t *dl, const struct dhcp_opt **od, size_t *odl, struct if_options *ifo, - uint8_t *request[], uint8_t *require[], uint8_t *no[]) + uint8_t *request[], uint8_t *require[], uint8_t *no[], uint8_t *reject[]) { +#if !defined(INET) && !defined(INET6) + /* Satisfy use */ + ctx = ctx; +#endif + #ifdef INET6 if (strncmp(arg, "dhcp6_", strlen("dhcp6_")) == 0) { *d = ctx->dhcp6_opts; @@ -538,6 +549,7 @@ set_option_space(struct dhcpcd_ctx *ctx, *request = ifo->requestmask6; *require = ifo->requiremask6; *no = ifo->nomask6; + *reject = ifo->rejectmask6; return arg + strlen("dhcp6_"); } #endif @@ -556,6 +568,7 @@ set_option_space(struct dhcpcd_ctx *ctx, *request = ifo->requestmask; *require = ifo->requiremask; *no = ifo->nomask; + *reject = ifo->rejectmask; return arg; } @@ -643,7 +656,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, in_addr_t *naddr; struct rt *rt; const struct dhcp_opt *d, *od; - uint8_t *request, *require, *no; + uint8_t *request, *require, *no, *reject; struct dhcp_opt **dop, *ndop; size_t *dop_len, dl, odl; struct vivco *vivco; @@ -745,9 +758,21 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, break; case 'o': arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, - &request, &require, &no); + &request, &require, &no, &reject); if (make_option_mask(d, dl, od, odl, request, arg, 1) != 0 || - make_option_mask(d, dl, od, odl, no, arg, -1) != 0) + make_option_mask(d, dl, od, odl, no, arg, -1) != 0 || + make_option_mask(d, dl, od, odl, reject, arg, -1) != 0) + { + syslog(LOG_ERR, "unknown option `%s'", arg); + return -1; + } + break; + case O_REJECT: + arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, + &request, &require, &no, &reject); + if (make_option_mask(d, dl, od, odl, reject, arg, 1) != 0 || + make_option_mask(d, dl, od, odl, request, arg, -1) != 0 || + make_option_mask(d, dl, od, odl, require, arg, -1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; @@ -964,7 +989,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, break; case 'O': arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, - &request, &require, &no); + &request, &require, &no, &reject); if (make_option_mask(d, dl, od, odl, request, arg, -1) != 0 || make_option_mask(d, dl, od, odl, require, arg, -1) != 0 || make_option_mask(d, dl, od, odl, no, arg, 1) != 0) @@ -975,10 +1000,11 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, break; case 'Q': arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, - &request, &require, &no); + &request, &require, &no, &reject); if (make_option_mask(d, dl, od, odl, require, arg, 1) != 0 || make_option_mask(d, dl, od, odl, request, arg, 1) != 0 || - make_option_mask(d, dl, od, odl, no, arg, -1) != 0) + make_option_mask(d, dl, od, odl, no, arg, -1) != 0 || + make_option_mask(d, dl, od, odl, reject, arg, -1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; @@ -1168,7 +1194,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, break; case O_DESTINATION: arg = set_option_space(ctx, arg, &d, &dl, &od, &odl, ifo, - &request, &require, &no); + &request, &require, &no, &reject); if (make_option_mask(d, dl, od, odl, ifo->dstmask, arg, 2) != 0) { @@ -1214,6 +1240,12 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, case O_IPV6RA_OWN_D: ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT; break; + case O_IPV6RA_AUTOCONF: + ifo->options |= DHCPCD_IPV6RA_AUTOCONF; + break; + case O_IPV6RA_NOAUTOCONF: + ifo->options &= ~DHCPCD_IPV6RA_AUTOCONF; + break; case O_NOALIAS: ifo->options |= DHCPCD_NOALIAS; break; @@ -2026,7 +2058,8 @@ read_config(struct dhcpcd_ctx *ctx, ifo->options |= DHCPCD_GATEWAY | DHCPCD_ARP; #endif #ifdef INET6 - ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS | DHCPCD_IPV6RA_REQRDNSS; + ifo->options |= DHCPCD_IPV6 | DHCPCD_IPV6RS; + ifo->options |= DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS; ifo->options |= DHCPCD_DHCP6; #endif ifo->timeout = DEFAULT_TIMEOUT; diff --git a/external/bsd/dhcpcd/dist/if-options.h b/external/bsd/dhcpcd/dist/if-options.h index 93585265b912..129af65004ac 100644 --- a/external/bsd/dhcpcd/dist/if-options.h +++ b/external/bsd/dhcpcd/dist/if-options.h @@ -1,8 +1,8 @@ -/* $NetBSD: if-options.h,v 1.7 2014/11/26 13:43:06 roy Exp $ */ +/* $NetBSD: if-options.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -108,6 +108,7 @@ #define DHCPCD_NOPFXDLG (1ULL << 51) #define DHCPCD_PFXDLGONLY (1ULL << 52) #define DHCPCD_PFXDLGMIX (1ULL << 53) +#define DHCPCD_IPV6RA_AUTOCONF (1ULL << 54) extern const struct option cf_options[]; @@ -142,9 +143,11 @@ struct if_options { uint8_t requestmask[256 / NBBY]; uint8_t requiremask[256 / NBBY]; uint8_t nomask[256 / NBBY]; + uint8_t rejectmask[256 / NBBY]; uint8_t requestmask6[(UINT16_MAX + 1) / NBBY]; uint8_t requiremask6[(UINT16_MAX + 1) / NBBY]; uint8_t nomask6[(UINT16_MAX + 1) / NBBY]; + uint8_t rejectmask6[(UINT16_MAX + 1) / NBBY]; uint8_t dstmask[256 / NBBY]; uint32_t leasetime; time_t timeout; diff --git a/external/bsd/dhcpcd/dist/if.c b/external/bsd/dhcpcd/dist/if.c index f04654952894..8965a496e9c5 100644 --- a/external/bsd/dhcpcd/dist/if.c +++ b/external/bsd/dhcpcd/dist/if.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: if.c,v 1.10 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: if.c,v 1.11 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -73,6 +73,11 @@ #include "ipv4.h" #include "ipv6nd.h" +#ifdef __QNX__ +/* QNX carries defines for, but does not actually support PF_LINK */ +#undef IFLR_ACTIVE +#endif + void if_free(struct interface *ifp) { @@ -81,9 +86,9 @@ if_free(struct interface *ifp) return; ipv4_free(ifp); dhcp_free(ifp); - ipv6_free(ifp); dhcp6_free(ifp); ipv6nd_free(ifp); + ipv6_free(ifp); free_options(ifp->options); free(ifp); } @@ -96,20 +101,11 @@ if_carrier(struct interface *iface) #ifdef SIOCGIFMEDIA struct ifmediareq ifmr; #endif -#ifdef __linux__ - char *p; -#endif if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return LINK_UNKNOWN; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name)); -#ifdef __linux__ - /* We can only test the real interface up */ - if ((p = strchr(ifr.ifr_name, ':'))) - *p = '\0'; -#endif - if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) { close(s); return LINK_UNKNOWN; @@ -136,19 +132,11 @@ if_setflag(struct interface *ifp, short flag) { struct ifreq ifr; int s, r; -#ifdef __linux__ - char *p; -#endif if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return -1; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name)); -#ifdef __linux__ - /* We can only bring the real interface up */ - if ((p = strchr(ifr.ifr_name, ':'))) - *p = '\0'; -#endif r = -1; if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { if (flag == 0 || (ifr.ifr_flags & flag) == flag) @@ -193,7 +181,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) const struct sockaddr_in *dst; #endif #ifdef INET6 - struct sockaddr_in6 *sin6; + struct sockaddr_in6 *sin6, *net6; int ifa_flags; #endif #ifdef AF_LINK @@ -271,6 +259,9 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) p = argv[i]; } else { p = ifa->ifa_name; +#ifdef __linux__ + strlcpy(ifn, ifa->ifa_name, sizeof(ifn)); +#endif /* -1 means we're discovering against a specific * interface, but we still need the below rules * to apply. */ @@ -311,7 +302,12 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) break; } ifp->ctx = ctx; +#ifdef __linux__ + strlcpy(ifp->name, ifn, sizeof(ifp->name)); + strlcpy(ifp->alias, p, sizeof(ifp->alias)); +#else strlcpy(ifp->name, p, sizeof(ifp->name)); +#endif ifp->flags = ifa->ifa_flags; ifp->carrier = if_carrier(ifp); @@ -503,6 +499,7 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) if (ifp == NULL) break; /* Should be impossible */ sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr; + net6 = (struct sockaddr_in6 *)(void *)ifa->ifa_netmask; #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) /* Remove the scope from the address */ @@ -513,7 +510,9 @@ if_discover(struct dhcpcd_ctx *ctx, int argc, char * const *argv) if (ifa_flags != -1) ipv6_handleifa(ctx, RTM_NEWADDR, ifs, ifa->ifa_name, - &sin6->sin6_addr, ifa_flags); + &sin6->sin6_addr, + ipv6_prefixlen(&net6->sin6_addr), + ifa_flags); break; #endif } @@ -541,6 +540,9 @@ if_findindexname(struct dhcpcd_ctx *ctx, unsigned int idx, const char *name) if ((ifp->options == NULL || !(ifp->options->options & DHCPCD_PFXDLGONLY)) && ((name && strcmp(ifp->name, name) == 0) || +#ifdef __linux__ + (name && strcmp(ifp->alias, name) == 0) || +#endif (!name && ifp->index == idx))) return ifp; } diff --git a/external/bsd/dhcpcd/dist/if.h b/external/bsd/dhcpcd/dist/if.h index 66832a9944ce..f551fe0733cb 100644 --- a/external/bsd/dhcpcd/dist/if.h +++ b/external/bsd/dhcpcd/dist/if.h @@ -1,8 +1,8 @@ -/* $NetBSD: if.h,v 1.7 2014/12/17 20:50:08 roy Exp $ */ +/* $NetBSD: if.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -105,6 +105,7 @@ int if_openlinksocket(void); int if_managelink(struct dhcpcd_ctx *); #ifdef INET +extern const char *if_pfname; int if_openrawsocket(struct interface *, int); ssize_t if_sendrawpacket(const struct interface *, int, const void *, size_t); @@ -126,12 +127,16 @@ int if_route(const struct rt *rt, int); #ifdef INET6 int if_checkipv6(struct dhcpcd_ctx *ctx, const struct interface *, int); +int ip6_use_tempaddr(const char *ifname); +int ip6_temp_preferred_lifetime(const char *ifname); +int ip6_temp_valid_lifetime(const char *ifname); int if_address6(const struct ipv6_addr *, int); #define if_addaddress6(a) if_address6(a, 1) #define if_deladdress6(a) if_address6(a, -1) int if_addrflags6(const struct in6_addr *, const struct interface *); +int if_getlifetime6(struct ipv6_addr *); int if_route6(const struct rt6 *rt, int); #define if_addroute6(rt) if_route6(rt, 1) diff --git a/external/bsd/dhcpcd/dist/ipv4.c b/external/bsd/dhcpcd/dist/ipv4.c index cfbd0ead7485..4153e3f3a6fb 100644 --- a/external/bsd/dhcpcd/dist/ipv4.c +++ b/external/bsd/dhcpcd/dist/ipv4.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: ipv4.c,v 1.10 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: ipv4.c,v 1.11 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/ipv4.h b/external/bsd/dhcpcd/dist/ipv4.h index 6c5e40adfc1f..57dc515c4bfe 100644 --- a/external/bsd/dhcpcd/dist/ipv4.h +++ b/external/bsd/dhcpcd/dist/ipv4.h @@ -1,8 +1,8 @@ -/* $NetBSD: ipv4.h,v 1.7 2014/11/26 13:43:06 roy Exp $ */ +/* $NetBSD: ipv4.h,v 1.8 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/ipv4ll.c b/external/bsd/dhcpcd/dist/ipv4ll.c index 685497db794a..3a4562685eee 100644 --- a/external/bsd/dhcpcd/dist/ipv4ll.c +++ b/external/bsd/dhcpcd/dist/ipv4ll.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: ipv4ll.c,v 1.7 2014/11/14 12:00:54 roy Exp $"); + __RCSID("$NetBSD: ipv4ll.c,v 1.8 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without diff --git a/external/bsd/dhcpcd/dist/ipv6.c b/external/bsd/dhcpcd/dist/ipv6.c index 1fb29e87a1d6..c4ed6534b31a 100644 --- a/external/bsd/dhcpcd/dist/ipv6.c +++ b/external/bsd/dhcpcd/dist/ipv6.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: ipv6.c,v 1.7 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: ipv6.c,v 1.8 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -38,28 +38,17 @@ #include #include -#ifdef __linux__ - /* Match Linux defines to BSD */ -# ifdef IFA_F_OPTIMISTIC -# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC) -# else -# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | 0x04) +#ifndef __linux__ +# ifndef __QNX__ +# include # endif -# ifdef IF_F_DADFAILED -# define IN6_IFF_DUPLICATED IFA_F_DADFAILED -# else -# define IN6_IFF_DUPLICATED 0x08 -# endif -# define IN6_IFF_DETACHED 0 -#else -# include # include -#ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */ -# include -#endif -#ifndef __sun -# include -#endif +# ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */ +# include +# endif +# ifndef __sun +# include +# endif #endif #include @@ -70,6 +59,7 @@ #include #include +#define ELOOP_QUEUE 7 #include "common.h" #include "dhcpcd.h" #include "dhcp6.h" @@ -78,6 +68,14 @@ #include "ipv6.h" #include "ipv6nd.h" +#ifdef HAVE_MD5_H +# ifndef DEPGEN +# include +# endif +#else +# include "md5.h" +#endif + #ifdef SHA2_H # include SHA2_H #else @@ -93,6 +91,22 @@ # warning polling tentative address flags periodically instead #endif +#ifdef __linux__ + /* Match Linux defines to BSD */ +# define IN6_IFF_TEMPORARY IFA_F_TEMPORARY +# ifdef IFA_F_OPTIMISTIC +# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC) +# else +# define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | 0x04) +# endif +# ifdef IF_F_DADFAILED +# define IN6_IFF_DUPLICATED IFA_F_DADFAILED +# else +# define IN6_IFF_DUPLICATED 0x08 +# endif +# define IN6_IFF_DETACHED 0 +#endif + #define IN6_IFF_NOTUSEABLE \ (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED) @@ -105,6 +119,14 @@ # endif #endif + +#ifdef IPV6_MANAGETEMPADDR +static void ipv6_regentempifid(void *); +static void ipv6_regentempaddr(void *); +#else +#define ipv6_regentempifid(a) {} +#endif + struct ipv6_ctx * ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx) { @@ -151,6 +173,7 @@ ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx) ctx->dhcp_fd = -1; dhcpcd_ctx->ipv6 = ctx; + return ctx; } @@ -570,7 +593,7 @@ ipv6_checkaddrflags(void *arg) else if (!(ifa_flags & IN6_IFF_TENTATIVE)) { ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR, ap->iface->ctx->ifaces, ap->iface->name, - &ap->addr, ifa_flags); + &ap->addr, ap->prefix_len, ifa_flags); } else { struct timeval tv; @@ -610,7 +633,6 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now) struct interface *ifp; struct ipv6_state *state; struct ipv6_addr *nap; - struct timeval n; uint32_t pltime, vltime; /* Ensure no other interface has this address */ @@ -628,6 +650,30 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now) } } + if (!(ap->flags & IPV6_AF_DADCOMPLETED) && + ipv6_iffindaddr(ap->iface, &ap->addr)) + ap->flags |= IPV6_AF_DADCOMPLETED; + + syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG, + "%s: adding address %s", ap->iface->name, ap->saddr); + if (ap->prefix_pltime == ND6_INFINITE_LIFETIME && + ap->prefix_vltime == ND6_INFINITE_LIFETIME) + syslog(LOG_DEBUG, + "%s: pltime infinity, vltime infinity", + ap->iface->name); + else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME) + syslog(LOG_DEBUG, + "%s: pltime infinity, vltime %"PRIu32" seconds", + ap->iface->name, ap->prefix_vltime); + else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME) + syslog(LOG_DEBUG, + "%s: pltime %"PRIu32"seconds, vltime infinity", + ap->iface->name, ap->prefix_pltime); + else + syslog(LOG_DEBUG, + "%s: pltime %"PRIu32" seconds, vltime %"PRIu32" seconds", + ap->iface->name, ap->prefix_pltime, ap->prefix_vltime); + /* Adjust plftime and vltime based on acquired time */ pltime = ap->prefix_pltime; vltime = ap->prefix_vltime; @@ -635,33 +681,49 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now) (ap->prefix_pltime != ND6_INFINITE_LIFETIME || ap->prefix_vltime != ND6_INFINITE_LIFETIME)) { + struct timeval n; + if (now == NULL) { get_monotonic(&n); now = &n; } timersub(now, &ap->acquired, &n); if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) - ap->prefix_pltime -= n.tv_sec; + ap->prefix_pltime -= (uint32_t)n.tv_sec; if (ap->prefix_vltime != ND6_INFINITE_LIFETIME) - ap->prefix_vltime -= n.tv_sec; + ap->prefix_vltime -= (uint32_t)n.tv_sec; } - syslog(ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG, - "%s: adding address %s", ap->iface->name, ap->saddr); - if (!(ap->flags & IPV6_AF_DADCOMPLETED) && - ipv6_iffindaddr(ap->iface, &ap->addr)) - ap->flags |= IPV6_AF_DADCOMPLETED; if (if_addaddress6(ap) == -1) { syslog(LOG_ERR, "if_addaddress6: %m"); +#if 0 + syslog(LOG_DEBUG, + "%s: adj pltime %"PRIu32" seconds, " + "vltime %"PRIu32" seconds", + ap->iface->name, ap->prefix_pltime, ap->prefix_vltime); +#endif /* Restore real pltime and vltime */ ap->prefix_pltime = pltime; ap->prefix_vltime = vltime; return -1; } +#ifdef IPV6_MANAGETEMPADDR + /* RFC4941 Section 3.4 */ + if (ap->flags & IPV6_AF_TEMPORARY && + ap->prefix_pltime && + ap->prefix_vltime && + ap->iface->options->options & DHCPCD_IPV6RA_OWN && + ip6_use_tempaddr(ap->iface->name)) + eloop_timeout_add_sec(ap->iface->ctx->eloop, + (time_t)ap->prefix_pltime - REGEN_ADVANCE, + ipv6_regentempaddr, ap); +#endif + /* Restore real pltime and vltime */ ap->prefix_pltime = pltime; ap->prefix_vltime = vltime; + ap->flags &= ~IPV6_AF_NEW; ap->flags |= IPV6_AF_ADDED; if (ap->delegating_iface) @@ -669,23 +731,6 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now) if (ap->iface->options->options & DHCPCD_IPV6RA_OWN && ipv6_removesubnet(ap->iface, ap) == -1) syslog(LOG_ERR,"ipv6_removesubnet: %m"); - if (ap->prefix_pltime == ND6_INFINITE_LIFETIME && - ap->prefix_vltime == ND6_INFINITE_LIFETIME) - syslog(LOG_DEBUG, - "%s: vltime infinity, pltime infinity", - ap->iface->name); - else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME) - syslog(LOG_DEBUG, - "%s: vltime %"PRIu32" seconds, pltime infinity", - ap->iface->name, ap->prefix_vltime); - else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME) - syslog(LOG_DEBUG, - "%s: vltime infinity, pltime %"PRIu32"seconds", - ap->iface->name, ap->prefix_pltime); - else - syslog(LOG_DEBUG, - "%s: vltime %"PRIu32" seconds, pltime %"PRIu32" seconds", - ap->iface->name, ap->prefix_vltime, ap->prefix_pltime); #ifdef IPV6_POLLADDRFLAG eloop_timeout_delete(ap->iface->ctx->eloop, @@ -793,13 +838,16 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop, TAILQ_FOREACH_SAFE(ap, addrs, next, apn) { if (ifd && ap->delegating_iface != ifd) continue; - TAILQ_REMOVE(addrs, ap, next); + if (drop != 2) + TAILQ_REMOVE(addrs, ap, next); eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap); if (drop && ap->flags & IPV6_AF_ADDED && (ap->iface->options->options & (DHCPCD_EXITING | DHCPCD_PERSISTENT)) != (DHCPCD_EXITING | DHCPCD_PERSISTENT)) { + if (drop == 2) + TAILQ_REMOVE(addrs, ap, next); /* Find the same address somewhere else */ apf = ipv6_findaddr(ap->iface->ctx, &ap->addr, 0); if (apf == NULL || @@ -813,8 +861,11 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop, get_monotonic(&now); ipv6_addaddr(apf, &now); } + if (drop == 2) + free(ap); } - free(ap); + if (drop != 2) + free(ap); } } @@ -825,7 +876,7 @@ ipv6_getstate(struct interface *ifp) state = IPV6_STATE(ifp); if (state == NULL) { - ifp->if_data[IF_DATA_IPV6] = malloc(sizeof(*state)); + ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state)); state = IPV6_STATE(ifp); if (state == NULL) { syslog(LOG_ERR, "%s: %m", __func__); @@ -833,6 +884,12 @@ ipv6_getstate(struct interface *ifp) } TAILQ_INIT(&state->addrs); TAILQ_INIT(&state->ll_callbacks); + + /* Regenerate new ids */ + if (ifp->options && + ifp->options->options & DHCPCD_IPV6RA_OWN && + ip6_use_tempaddr(ifp->name)) + ipv6_regentempifid(ifp); } return state; } @@ -840,7 +897,7 @@ ipv6_getstate(struct interface *ifp) void ipv6_handleifa(struct dhcpcd_ctx *ctx, int cmd, struct if_head *ifs, const char *ifname, - const struct in6_addr *addr, int flags) + const struct in6_addr *addr, uint8_t prefix_len, int flags) { struct interface *ifp; struct ipv6_state *state; @@ -888,16 +945,50 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx, break; case RTM_NEWADDR: if (ap == NULL) { + char buf[INET6_ADDRSTRLEN]; + const char *cbp; + ap = calloc(1, sizeof(*ap)); ap->iface = ifp; ap->addr = *addr; - inet_ntop(AF_INET6, &addr->s6_addr, - ap->saddr, sizeof(ap->saddr)); + ap->prefix_len = prefix_len; + ipv6_makeprefix(&ap->prefix, &ap->addr, + ap->prefix_len); + cbp = inet_ntop(AF_INET6, &addr->s6_addr, + buf, sizeof(buf)); + if (cbp) + snprintf(ap->saddr, sizeof(ap->saddr), + "%s/%d", cbp, prefix_len); + if (if_getlifetime6(ap) == -1) { + /* No support or address vanished. + * Either way, just set a deprecated + * infinite time lifetime and continue. + * This is fine because we only want + * to know this when trying to extend + * temporary addresses. + * As we can't extend infinite, we'll + * create a new temporary address. */ + ap->prefix_pltime = 0; + ap->prefix_vltime = + ND6_INFINITE_LIFETIME; + } + /* This is a minor regression against RFC 4941 + * because the kernel only knows when the + * lifetimes were last updated, not when the + * address was initially created. + * Provided dhcpcd is not restarted, this + * won't be a problem. + * If we don't like it, we can always + * pretend lifetimes are infinite and always + * generate a new temporary address on + * restart. */ + ap->acquired = ap->created; TAILQ_INSERT_TAIL(&state->addrs, ap, next); } ap->addr_flags = flags; - + if (ap->addr_flags & IN6_IFF_TEMPORARY) + ap->flags |= IPV6_AF_TEMPORARY; if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) { #ifdef IPV6_POLLADDRFLAG if (ap->addr_flags & IN6_IFF_TENTATIVE) { @@ -953,7 +1044,8 @@ ipv6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr) return NULL; } -int ipv6_addlinklocalcallback(struct interface *ifp, +int +ipv6_addlinklocalcallback(struct interface *ifp, void (*callback)(void *), void *arg) { struct ipv6_state *state; @@ -977,21 +1069,6 @@ int ipv6_addlinklocalcallback(struct interface *ifp, return 0; } -void -ipv6_free_ll_callbacks(struct interface *ifp) -{ - struct ipv6_state *state; - struct ll_callback *cb; - - state = IPV6_STATE(ifp); - if (state) { - while ((cb = TAILQ_FIRST(&state->ll_callbacks))) { - TAILQ_REMOVE(&state->ll_callbacks, cb, next); - free(cb); - } - } -} - static struct ipv6_addr * ipv6_newlinklocal(struct interface *ifp) { @@ -1141,6 +1218,10 @@ ipv6_start(struct interface *ifp) !(ap->addr_flags & IN6_IFF_DUPLICATED)) break; } + /* Regenerate new ids */ + if (ifp->options->options & DHCPCD_IPV6RA_OWN && + ip6_use_tempaddr(ifp->name)) + ipv6_regentempifid(ifp); } else ap = NULL; @@ -1150,32 +1231,44 @@ ipv6_start(struct interface *ifp) } void -ipv6_free(struct interface *ifp) +ipv6_freedrop(struct interface *ifp, int drop) { struct ipv6_state *state; - struct ipv6_addr *ap; + struct ll_callback *cb; - if (ifp) { - ipv6_free_ll_callbacks(ifp); - state = IPV6_STATE(ifp); - if (state) { - while ((ap = TAILQ_FIRST(&state->addrs))) { - TAILQ_REMOVE(&state->addrs, ap, next); - free(ap); - } - free(state); - ifp->if_data[IF_DATA_IPV6] = NULL; + if (ifp == NULL) + return; + + if ((state = IPV6_STATE(ifp)) == NULL) + return; + + ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL); + + /* Becuase we need to cache the addresses we don't control, + * we only free the state on when NOT dropping addresses. */ + if (drop == 0) { + while ((cb = TAILQ_FIRST(&state->ll_callbacks))) { + TAILQ_REMOVE(&state->ll_callbacks, cb, next); + free(cb); } + free(state); + ifp->if_data[IF_DATA_IPV6] = NULL; + eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); } } void ipv6_ctxfree(struct dhcpcd_ctx *ctx) { + struct rt6 *rt; if (ctx->ipv6 == NULL) return; + while ((rt = TAILQ_FIRST(ctx->ipv6->routes))) { + TAILQ_REMOVE(ctx->ipv6->routes, rt, next); + free(rt); + } free(ctx->ipv6->routes); free(ctx->ipv6->ra_routers); free(ctx->ipv6); @@ -1228,6 +1321,373 @@ ipv6_handleifa_addrs(int cmd, return alldadcompleted ? found : 0; } +#ifdef IPV6_MANAGETEMPADDR +static const struct ipv6_addr * +ipv6_findaddrid(struct dhcpcd_ctx *ctx, uint8_t *addr) +{ + const struct interface *ifp; + const struct ipv6_state *state; + const struct ipv6_addr *ia; + + TAILQ_FOREACH(ifp, ctx->ifaces, next) { + if ((state = IPV6_CSTATE(ifp))) { + TAILQ_FOREACH(ia, &state->addrs, next) { + if (memcmp(&ia->addr.s6_addr[8], addr, 8) == 0) + return ia; + } + } + } + return NULL; +} + +static const uint8_t nullid[8]; +static const uint8_t anycastid[8] = { + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 }; +static const uint8_t isatapid[4] = { 0x00, 0x00, 0x5e, 0xfe }; + +static void +ipv6_regen_desync(struct interface *ifp, int force) +{ + struct ipv6_state *state; + time_t max; + + state = IPV6_STATE(ifp); + + /* RFC4941 Section 5 states that DESYNC_FACTOR must never be + * greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE. + * I believe this is an error and it should be never be greateter than + * TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */ + max = ip6_temp_preferred_lifetime(ifp->name) - REGEN_ADVANCE; + if (state->desync_factor && !force && state->desync_factor < max) + return; + if (state->desync_factor == 0) + state->desync_factor = + (time_t)arc4random_uniform(MIN(MAX_DESYNC_FACTOR, + (uint32_t)max)); + max = ip6_temp_preferred_lifetime(ifp->name) - + state->desync_factor - REGEN_ADVANCE; + eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempifid, ifp); +} + +void +ipv6_gentempifid(struct interface *ifp) +{ + struct ipv6_state *state; + MD5_CTX md5; + uint8_t seed[16], digest[16]; + int retry; + + state = IPV6_STATE(ifp); + retry = 0; + if (memcmp(nullid, state->randomseed0, sizeof(nullid)) == 0) { + uint32_t r; + + r = arc4random(); + memcpy(seed, &r, sizeof(r)); + r = arc4random(); + memcpy(seed + sizeof(r), &r, sizeof(r)); + } else + memcpy(seed, state->randomseed0, sizeof(state->randomseed0)); + + memcpy(seed + sizeof(state->randomseed0), + state->randomseed1, sizeof(state->randomseed1)); + +again: + /* RFC4941 Section 3.2.1.1 + * Take the left-most 64bits and set bit 6 to zero */ + MD5Init(&md5); + MD5Update(&md5, seed, sizeof(seed)); + MD5Final(digest, &md5); + + /* RFC4941 Section 3.2.1.1 + * Take the left-most 64bits and set bit 6 to zero */ + memcpy(state->randomid, digest, sizeof(state->randomid)); + state->randomid[0] &= ~EUI64_UBIT; + + /* RFC4941 Section 3.2.1.4 + * Reject reserved or existing id's */ + if (memcmp(nullid, state->randomid, sizeof(nullid)) == 0 || + (memcmp(anycastid, state->randomid, 7) == 0 && + (anycastid[7] & state->randomid[7]) == anycastid[7]) || + memcmp(isatapid, state->randomid, sizeof(isatapid)) == 0 || + ipv6_findaddrid(ifp->ctx, state->randomid)) + { + if (++retry < GEN_TEMPID_RETRY_MAX) { + memcpy(seed, digest + 8, 8); + goto again; + } + memset(state->randomid, 0, sizeof(state->randomid)); + } + + /* RFC4941 Section 3.2.1.6 + * Save the right-most 64bits of the digest */ + memcpy(state->randomseed0, digest + 8, + sizeof(state->randomseed0)); +} + +/* RFC4941 Section 3.3.7 */ +static void +ipv6_tempdadcallback(void *arg) +{ + struct ipv6_addr *ia = arg; + + if (ia->flags & IPV6_AF_DUPLICATED) { + struct ipv6_addr *ia1; + struct timeval tv; + + if (++ia->dadcounter == TEMP_IDGEN_RETRIES) { + syslog(LOG_ERR, + "%s: too many duplicate temporary addresses", + ia->iface->name); + return; + } + get_monotonic(&tv); + if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL) + syslog(LOG_ERR, "ipv6_createtempaddr: %m"); + else + ia1->dadcounter = ia->dadcounter; + ipv6_deleteaddr(ia); + if (ia1) + ipv6_addaddr(ia1, &ia1->acquired); + } +} + +struct ipv6_addr * +ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timeval *now) +{ + struct ipv6_state *state; + const struct ipv6_state *cstate; + int genid; + struct in6_addr addr, mask; + uint32_t randid[2]; + const struct interface *ifp; + const struct ipv6_addr *ap; + struct ipv6_addr *ia; + uint32_t i, trylimit; + char buf[INET6_ADDRSTRLEN]; + const char *cbp; + + trylimit = TEMP_IDGEN_RETRIES; + state = IPV6_STATE(ia0->iface); + genid = 0; + + addr = ia0->addr; + ipv6_mask(&mask, ia0->prefix_len); + /* clear the old ifid */ + for (i = 0; i < 4; i++) + addr.s6_addr32[i] &= mask.s6_addr32[i]; + +again: + if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) + genid = 1; + if (genid) { + memcpy(state->randomseed1, &ia0->addr.s6_addr[8], + sizeof(state->randomseed1)); + ipv6_gentempifid(ia0->iface); + if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) { + errno = EFAULT; + return NULL; + } + } + memcpy(&randid[0], state->randomid, sizeof(randid[0])); + memcpy(&randid[1], state->randomid + sizeof(randid[1]), + sizeof(randid[2])); + addr.s6_addr32[2] |= randid[0] & ~mask.s6_addr32[2]; + addr.s6_addr32[3] |= randid[1] & ~mask.s6_addr32[3]; + + /* Ensure we don't already have it */ + TAILQ_FOREACH(ifp, ia0->iface->ctx->ifaces, next) { + cstate = IPV6_CSTATE(ifp); + if (cstate) { + TAILQ_FOREACH(ap, &cstate->addrs, next) { + if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr)) { + if (--trylimit == 0) { + errno = EEXIST; + return NULL; + } + genid = 1; + goto again; + } + } + } + } + + if ((ia = calloc(1, sizeof(*ia))) == NULL) + return NULL; + + ia->iface = ia0->iface; + ia->addr = addr; + /* Must be made tentative, for our DaD to work */ + ia->addr_flags = IN6_IFF_TENTATIVE; + ia->dadcallback = ipv6_tempdadcallback; + ia->flags = IPV6_AF_NEW | IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY; + ia->prefix = ia0->prefix; + ia->prefix_len = ia0->prefix_len; + ia->created = ia->acquired = now ? *now : ia0->acquired; + + /* Ensure desync is still valid */ + ipv6_regen_desync(ia->iface, 0); + + /* RFC4941 Section 3.3.4 */ + i = (uint32_t)(ip6_temp_preferred_lifetime(ia0->iface->name) - + state->desync_factor); + ia->prefix_pltime = MIN(ia0->prefix_pltime, i); + i = (uint32_t)ip6_temp_valid_lifetime(ia0->iface->name); + ia->prefix_vltime = MIN(ia0->prefix_vltime, i); + if (ia->prefix_pltime <= REGEN_ADVANCE || + ia->prefix_pltime > ia0->prefix_vltime) + { + errno = EINVAL; + free(ia); + return NULL; + } + + cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf)); + if (cbp) + snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", + cbp, ia->prefix_len); + else + ia->saddr[0] = '\0'; + + TAILQ_INSERT_TAIL(&state->addrs, ia, next); + return ia; +} + +void +ipv6_settempstale(struct interface *ifp) +{ + struct ipv6_state *state; + struct ipv6_addr *ia; + + state = IPV6_STATE(ifp); + TAILQ_FOREACH(ia, &state->addrs, next) { + if (ia->flags & IPV6_AF_TEMPORARY) + ia->flags |= IPV6_AF_STALE; + } +} + +struct ipv6_addr * +ipv6_settemptime(struct ipv6_addr *ia, int flags) +{ + struct ipv6_state *state; + struct ipv6_addr *ap, *first; + + state = IPV6_STATE(ia->iface); + first = NULL; + TAILQ_FOREACH_REVERSE(ap, &state->addrs, ipv6_addrhead, next) { + if (ap->flags & IPV6_AF_TEMPORARY && + ap->prefix_pltime && + IN6_ARE_ADDR_EQUAL(&ia->prefix, &ap->prefix)) + { + time_t max, ext; + + if (flags == 0) { + if (ap->prefix_pltime - + (uint32_t)(ia->acquired.tv_sec - + ap->acquired.tv_sec) + < REGEN_ADVANCE) + continue; + + return ap; + } + + if (!(ap->flags & IPV6_AF_ADDED)) + ap->flags |= IPV6_AF_NEW | IPV6_AF_AUTOCONF; + ap->flags &= ~IPV6_AF_STALE; + + /* RFC4941 Section 3.4 + * Deprecated prefix, deprecate the temporary address */ + if (ia->prefix_pltime == 0) { + ap->prefix_pltime = 0; + goto valid; + } + + /* Ensure desync is still valid */ + ipv6_regen_desync(ap->iface, 0); + + /* RFC4941 Section 3.3.2 + * Extend temporary times, but ensure that they + * never last beyond the system limit. */ + ext = ia->acquired.tv_sec + (time_t)ia->prefix_pltime; + max = ap->created.tv_sec + + ip6_temp_preferred_lifetime(ap->iface->name) - + state->desync_factor; + if (ext < max) + ap->prefix_pltime = ia->prefix_pltime; + else + ap->prefix_pltime = + (uint32_t)(max - ia->acquired.tv_sec); + +valid: + ext = ia->acquired.tv_sec + (time_t)ia->prefix_vltime; + max = ap->created.tv_sec + + ip6_temp_valid_lifetime(ap->iface->name); + if (ext < max) + ap->prefix_vltime = ia->prefix_vltime; + else + ap->prefix_vltime = + (uint32_t)(max - ia->acquired.tv_sec); + + /* Just extend the latest matching prefix */ + ap->acquired = ia->acquired; + + /* If extending return the last match as + * it's the most current. + * If deprecating, deprecate any other addresses we + * may have, although this should not be needed */ + if (ia->prefix_pltime) + return ap; + if (first == NULL) + first = ap; + } + } + return first; +} + +void +ipv6_addtempaddrs(struct interface *ifp, const struct timeval *now) +{ + struct ipv6_state *state; + struct ipv6_addr *ia; + + state = IPV6_STATE(ifp); + TAILQ_FOREACH(ia, &state->addrs, next) { + if (ia->flags & IPV6_AF_TEMPORARY && + !(ia->flags & IPV6_AF_STALE)) + ipv6_addaddr(ia, now); + } +} + +static void +ipv6_regentempaddr(void *arg) +{ + struct ipv6_addr *ia = arg, *ia1; + struct timeval tv; + + syslog(LOG_DEBUG, "%s: regen temp addr %s", + ia->iface->name, ia->saddr); + get_monotonic(&tv); + ia1 = ipv6_createtempaddr(ia, &tv); + if (ia1) + ipv6_addaddr(ia1, &tv); + else + syslog(LOG_ERR, "ipv6_createtempaddr: %m"); +} + +static void +ipv6_regentempifid(void *arg) +{ + struct interface *ifp = arg; + struct ipv6_state *state; + + state = IPV6_STATE(ifp); + if (memcmp(state->randomid, nullid, sizeof(state->randomid))) + ipv6_gentempifid(ifp); + + ipv6_regen_desync(ifp, 1); +} +#endif /* IPV6_MANAGETEMPADDR */ + static struct rt6 * find_route6(struct rt6_head *rts, const struct rt6 *r) { diff --git a/external/bsd/dhcpcd/dist/ipv6.h b/external/bsd/dhcpcd/dist/ipv6.h index 3f600fa56aca..42fd7e7d2651 100644 --- a/external/bsd/dhcpcd/dist/ipv6.h +++ b/external/bsd/dhcpcd/dist/ipv6.h @@ -1,8 +1,8 @@ -/* $NetBSD: ipv6.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */ +/* $NetBSD: ipv6.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -56,6 +56,15 @@ # define ND6_INFINITE_LIFETIME ((uint32_t)~0) #endif +/* RFC4941 constants */ +#define TEMP_VALID_LIFETIME 604800 /* 1 week */ +#define TEMP_PREFERRED_LIFETIME 86400 /* 1 day */ +#define REGEN_ADVANCE 5 /* seconds */ +#define MAX_DESYNC_FACTOR 600 /* 10 minutes */ + +#define TEMP_IDGEN_RETRIES 3 +#define GEN_TEMPID_RETRY_MAX 5 + /* RFC7217 constants */ #define IDGEN_RETRIES 3 #define IDGEN_DELAY 1 /* second */ @@ -78,6 +87,13 @@ # undef IPV6_POLLADDRFLAG #endif +/* Linux-3.18 can manage temporary addresses even with RA + * processing disabled. */ +//#undef IFA_F_MANAGETEMPADDR +#ifndef IFA_F_MANAGETEMPADDR +#define IPV6_MANAGETEMPADDR +#endif + struct ipv6_addr { TAILQ_ENTRY(ipv6_addr) next; struct interface *iface; @@ -85,6 +101,7 @@ struct ipv6_addr { uint8_t prefix_len; uint32_t prefix_vltime; uint32_t prefix_pltime; + struct timeval created; struct timeval acquired; struct in6_addr addr; int addr_flags; @@ -115,6 +132,7 @@ TAILQ_HEAD(ipv6_addrhead, ipv6_addr); #define IPV6_AF_DELEGATEDPFX 0x0100 #define IPV6_AF_DELEGATEDZERO 0x0200 #define IPV6_AF_REQUEST 0x0400 +#define IPV6_AF_TEMPORARY 0X0800 struct rt6 { TAILQ_ENTRY(rt6) next; @@ -138,6 +156,13 @@ TAILQ_HEAD(ll_callback_head, ll_callback); struct ipv6_state { struct ipv6_addrhead addrs; struct ll_callback_head ll_callbacks; + +#ifdef IPV6_MANAGETEMPADDR + time_t desync_factor; + uint8_t randomseed0[8]; /* upper 64 bits of MD5 digest */ + uint8_t randomseed1[8]; /* lower 64 bits */ + uint8_t randomid[8]; +#endif }; #define IPV6_STATE(ifp) \ @@ -145,6 +170,21 @@ struct ipv6_state { #define IPV6_CSTATE(ifp) \ ((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6]) +/* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */ +#ifdef __QNX__ +#undef CMSG_SPACE +#endif + +#ifndef ALIGNBYTES +#define ALIGNBYTES (sizeof(int) - 1) +#endif +#ifndef ALIGN +#define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES) +#endif +#ifndef CMSG_SPACE +#define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len)) +#endif + #define IP6BUFLEN (CMSG_SPACE(sizeof(struct in6_pktinfo)) + \ CMSG_SPACE(sizeof(int))) @@ -188,7 +228,7 @@ ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs); void ipv6_freedrop_addrs(struct ipv6_addrhead *, int, const struct interface *); void ipv6_handleifa(struct dhcpcd_ctx *ctx, int, struct if_head *, - const char *, const struct in6_addr *, int); + const char *, const struct in6_addr *, uint8_t, int); int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, const struct in6_addr *, int); const struct ipv6_addr *ipv6_iffindaddr(const struct interface *, @@ -197,20 +237,35 @@ struct ipv6_addr *ipv6_findaddr(struct dhcpcd_ctx *, const struct in6_addr *, short); #define ipv6_linklocal(ifp) (ipv6_iffindaddr((ifp), NULL)) int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *); -void ipv6_free_ll_callbacks(struct interface *); +void ipv6_freedrop(struct interface *, int); +#define ipv6_free(ifp) ipv6_freedrop(ifp, 0) +#define ipv6_drop(ifp) ipv6_freedrop(ifp, 2) + +#ifdef IPV6_MANAGETEMPADDR +void ipv6_gentempifid(struct interface *); +void ipv6_settempstale(struct interface *); +struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *, + const struct timeval *); +struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int); +void ipv6_addtempaddrs(struct interface *, const struct timeval *); +#else +#define ipv6_gentempifid(a) {} +#define ipv6_settempstale(a) {} +#endif + int ipv6_start(struct interface *); -void ipv6_free(struct interface *); void ipv6_ctxfree(struct dhcpcd_ctx *); int ipv6_routedeleted(struct dhcpcd_ctx *, const struct rt6 *); int ipv6_removesubnet(struct interface *, struct ipv6_addr *); void ipv6_buildroutes(struct dhcpcd_ctx *); #else -#define ipv6_init(a) NULL +#define ipv6_init(a) (NULL) #define ipv6_start(a) (-1) -#define ipv6_free_ll_callbacks(a) -#define ipv6_free(a) -#define ipv6_ctxfree(a) +#define ipv6_free_ll_callbacks(a) {} +#define ipv6_free(a) {} +#define ipv6_drop(a) {} +#define ipv6_ctxfree(a) {} #endif #endif diff --git a/external/bsd/dhcpcd/dist/ipv6nd.c b/external/bsd/dhcpcd/dist/ipv6nd.c index 330881f42b27..2604ab440c28 100644 --- a/external/bsd/dhcpcd/dist/ipv6nd.c +++ b/external/bsd/dhcpcd/dist/ipv6nd.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: ipv6nd.c,v 1.19 2014/12/17 20:50:08 roy Exp $"); + __RCSID("$NetBSD: ipv6nd.c,v 1.20 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -497,8 +497,8 @@ ipv6nd_scriptrun(struct ra *rap) hasaddress = 0; /* If all addresses have completed DAD run the script */ TAILQ_FOREACH(ap, &rap->addrs, next) { - if ((ap->flags & (IPV6_AF_ONLINK | IPV6_AF_AUTOCONF)) == - (IPV6_AF_ONLINK | IPV6_AF_AUTOCONF)) + if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) == + (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) { hasaddress = 1; if (!(ap->flags & IPV6_AF_DADCOMPLETED) && @@ -566,8 +566,9 @@ ipv6nd_dadcompleted(const struct interface *ifp) continue; TAILQ_FOREACH(ap, &rap->addrs, next) { if (ap->flags & IPV6_AF_AUTOCONF && + ap->flags & IPV6_AF_ADDED && !(ap->flags & IPV6_AF_DADCOMPLETED)) - return 0; + return 0; } } return 1; @@ -650,6 +651,7 @@ try_script: found = 0; TAILQ_FOREACH(rapap, &rap->addrs, next) { if (rapap->flags & IPV6_AF_AUTOCONF && + rapap->flags & IPV6_AF_ADDED && (rapap->flags & IPV6_AF_DADCOMPLETED) == 0) { wascompleted = 0; @@ -693,6 +695,9 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, char *opt, *opt2, *tmp; struct timeval expire; uint8_t new_rap, new_data; +#ifdef IPV6_MANAGETEMPADDR + uint8_t new_ap; +#endif if (len < sizeof(struct nd_router_advert)) { syslog(LOG_ERR, "IPv6 RA packet too short from %s", ctx->sfrom); @@ -728,6 +733,12 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, return; } + if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr)) { + syslog(LOG_DEBUG, "%s: ignoring RA from ourself %s", + ifp->name, ctx->sfrom); + return; + } + TAILQ_FOREACH(rap, ctx->ra_routers, next) { if (ifp == rap->iface && IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr)) @@ -794,6 +805,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, if (rap->lifetime) rap->expired = 0; + ipv6_settempstale(ifp); TAILQ_FOREACH(ap, &rap->addrs, next) { ap->flags |= IPV6_AF_STALE; } @@ -867,7 +879,9 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, ap->prefix_len = pi->nd_opt_pi_prefix_len; ap->prefix = pi->nd_opt_pi_prefix; if (pi->nd_opt_pi_flags_reserved & - ND_OPT_PI_FLAG_AUTO) + ND_OPT_PI_FLAG_AUTO && + ap->iface->options->options & + DHCPCD_IPV6RA_AUTOCONF) { ap->flags |= IPV6_AF_AUTOCONF; ap->dadcounter = @@ -893,13 +907,31 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, ap->saddr[0] = '\0'; } ap->dadcallback = ipv6nd_dadcallback; + ap->created = ap->acquired = rap->received; TAILQ_INSERT_TAIL(&rap->addrs, ap, next); - } else + +#ifdef IPV6_MANAGETEMPADDR + /* New address to dhcpcd RA handling. + * If the address already exists and a valid + * temporary address also exists then + * extend the existing one rather than + * create a new one */ + if (ipv6_iffindaddr(ifp, &ap->addr) && + ipv6_settemptime(ap, 0)) + new_ap = 0; + else + new_ap = 1; +#endif + } else { +#ifdef IPV6_MANAGETEMPADDR + new_ap = 0; +#endif ap->flags &= ~IPV6_AF_STALE; + ap->acquired = rap->received; + } if (pi->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) ap->flags |= IPV6_AF_ONLINK; - ap->acquired = rap->received; ap->prefix_vltime = ntohl(pi->nd_opt_pi_valid_time); ap->prefix_pltime = @@ -915,6 +947,26 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp, opt2 = strdup(ap->saddr); } } + +#ifdef IPV6_MANAGETEMPADDR + /* RFC4941 Section 3.3.3 */ + if (ap->flags & IPV6_AF_AUTOCONF && + ap->iface->options->options & DHCPCD_IPV6RA_OWN && + ip6_use_tempaddr(ap->iface->name)) + { + if (!new_ap) { + if (ipv6_settemptime(ap, 1) == NULL) + new_ap = 1; + } + if (new_ap && ap->prefix_pltime) { + if (ipv6_createtempaddr(ap, + &ap->acquired) == NULL) + syslog(LOG_ERR, + "ipv6_createtempaddr: %m"); + } + } +#endif + lifetime = ap->prefix_vltime; break; @@ -1066,6 +1118,9 @@ extra_opt: goto handle_flag; } ipv6_addaddrs(&rap->addrs); +#ifdef IPV6_MANAGETEMPADDR + ipv6_addtempaddrs(ifp, &rap->received); +#endif ipv6_buildroutes(ifp->ctx); if (ipv6nd_scriptrun(rap)) return; diff --git a/external/bsd/dhcpcd/dist/ipv6nd.h b/external/bsd/dhcpcd/dist/ipv6nd.h index ba3683988cef..211792f0255d 100644 --- a/external/bsd/dhcpcd/dist/ipv6nd.h +++ b/external/bsd/dhcpcd/dist/ipv6nd.h @@ -1,8 +1,8 @@ -/* $NetBSD: ipv6nd.h,v 1.8 2014/12/17 20:50:08 roy Exp $ */ +/* $NetBSD: ipv6nd.h,v 1.9 2015/01/30 09:47:05 roy Exp $ */ /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -103,10 +103,10 @@ void ipv6nd_neighbour(struct dhcpcd_ctx *, struct in6_addr *, int); #else #define ipv6nd_startrs(a) {} #define ipv6nd_findaddr(a, b, c) (0) -#define ipv6nd_free(a) +#define ipv6nd_free(a) {} #define ipv6nd_hasra(a) (0) #define ipv6nd_dadcompleted(a) (0) -#define ipv6nd_drop(a) +#define ipv6nd_drop(a) {} #endif #endif diff --git a/external/bsd/dhcpcd/dist/script.c b/external/bsd/dhcpcd/dist/script.c index ad7bf3e0c56c..13e4320d3e02 100644 --- a/external/bsd/dhcpcd/dist/script.c +++ b/external/bsd/dhcpcd/dist/script.c @@ -1,9 +1,9 @@ #include - __RCSID("$NetBSD: script.c,v 1.16 2014/12/09 20:21:05 roy Exp $"); + __RCSID("$NetBSD: script.c,v 1.17 2015/01/30 09:47:05 roy Exp $"); /* * dhcpcd - DHCP client daemon - * Copyright (c) 2006-2014 Roy Marples + * Copyright (c) 2006-2015 Roy Marples * All rights reserved * Redistribution and use in source and binary forms, with or without @@ -232,7 +232,9 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) { char **env, **nenv, *p; size_t e, elen, l; +#if defined(INET) || defined(INET6) ssize_t n; +#endif const struct if_options *ifo = ifp->options; const struct interface *ifp2; #ifdef INET @@ -277,7 +279,9 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) strcmp(reason, "UNKNOWN") == 0 || strcmp(reason, "DEPARTED") == 0 || strcmp(reason, "STOPPED") == 0) - ; + { + /* This space left intentionally blank */ + } #ifdef INET else dhcp = 1;