diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in index 93232840..a30f3232 100644 --- a/src/dhcpcd.8.in +++ b/src/dhcpcd.8.in @@ -51,6 +51,7 @@ .Op Fl S , Fl Fl static Ar value .Op Fl s , Fl Fl inform Ar address Ns Op Ar /cidr Ns Op Ar /broadcast_address .Op Fl Fl inform6 +.Op Fl Fl ipv6ll-external .Op Fl t , Fl Fl timeout Ar seconds .Op Fl u , Fl Fl userclass Ar class .Op Fl v , Fl Fl vendor Ar code , Ar value @@ -631,6 +632,11 @@ option to specify which protocol(s) to configure before exiting. Configure IPv4 only. .It Fl 6 , Fl Fl ipv6only Configure IPv6 only. +.It Fl Fl ipv6ll-external +Don't create an IPv6 link-local address. +.Nm +waits for a usable link-local address to be created by another entity before +continuing IPv6 operations that require it. .It Fl A , Fl Fl noarp Don't request or claim the address by ARP. This also disables IPv4LL. diff --git a/src/if-options.c b/src/if-options.c index 94e8b03e..6cf0e4e6 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -165,6 +165,7 @@ const struct option cf_options[] = { {"noup", no_argument, NULL, O_NOUP}, {"lastleaseextend", no_argument, NULL, O_LASTLEASE_EXTEND}, {"inactive", no_argument, NULL, O_INACTIVE}, + {"ipv6ll-external", no_argument, NULL, O_IPV6LL_EXTERNAL}, {"mudurl", required_argument, NULL, O_MUDURL}, {"link_rcvbuf", required_argument, NULL, O_LINK_RCVBUF}, {"configure", no_argument, NULL, O_CONFIGURE}, @@ -2316,6 +2317,9 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, case O_INACTIVE: ifo->options |= DHCPCD_INACTIVE; break; + case O_IPV6LL_EXTERNAL: + ifo->ipv6ll_external = true; + break; case O_MUDURL: ARG_REQUIRED; s = parse_string((char *)ifo->mudurl + 1, MUDURL_MAX_LEN, arg); @@ -2398,6 +2402,12 @@ parse_config_line(struct dhcpcd_ctx *ctx, const char *ifname, { unsigned int i; + if (strcmp(opt, "ipv6ll-external") == 0) { + logerrx("option can only be used on the command line -- %s", + opt); + return -1; + } + for (i = 0; i < sizeof(cf_options) / sizeof(cf_options[0]); i++) { if (!cf_options[i].name || strcmp(cf_options[i].name, opt) != 0) diff --git a/src/if-options.h b/src/if-options.h index 9b3fd5b9..7c0713a6 100644 --- a/src/if-options.h +++ b/src/if-options.h @@ -188,6 +188,7 @@ #define O_ROUTING_TABLE_ID O_BASE + 53 #define O_MAX_BACKOFF_TIMER O_BASE + 54 #define O_DHCPV4_COS O_BASE + 55 +#define O_IPV6LL_EXTERNAL O_BASE + 56 extern const struct option cf_options[]; @@ -240,6 +241,7 @@ struct if_options { uint32_t timeout; uint32_t reboot; unsigned long long options; + bool ipv6ll_external; bool randomise_hwaddr; struct in_addr req_addr; diff --git a/src/ipv6.c b/src/ipv6.c index 5224921e..00a2c152 100644 --- a/src/ipv6.c +++ b/src/ipv6.c @@ -1558,6 +1558,8 @@ ipv6_tryaddlinklocal(struct interface *ifp) #endif return 0; } + if (ifp->options->ipv6ll_external) + return 0; if (!CAN_ADD_LLADDR(ifp)) return 0;