On Sat, Mar 14, 2020 at 12:54:20PM -0300, Fernando Gont wrote:
> Folks,
>
> This improves IPv6 SLAAC handling of renumbering scenarios. At the time of
> this writing, this doesn't follow the spec, but is the right thing.
>
> Essentially, PIOs will employ these default values:
> Preferred Lifetime = Router Lifetime (as sent by router, defaulting to 1800)
> Valid Lifetime= 48 * Preferred Lifetime
>
> (unless you manually set them to something else)
>
> The problem statement for this is in this IETF I-D (v6ops wg item):
> https://tools.ietf.org/html/draft-ietf-v6ops-slaac-renum
>
> And the changes are described Section 4.1.1 of this (*individual* I-D):
> https://tools.ietf.org/html/draft-gont-6man-slaac-renum-04
>
> Note: More is needed... but this is at least something. If you like the
> patch, I may implement the rest of the proposal.
>
> Thoughts?
>
>
> ---- cut here ----
> diff --git frontend.c frontend.c
> index c932c3dfca3..80c16f953ea 100644
> --- frontend.c
> +++ frontend.c
> @@ -128,7 +128,8 @@ struct ra_iface_conf *find_ra_iface_conf(struct
> ra_iface_conf_head *,
> struct ra_prefix_conf *find_ra_prefix_conf(struct
> ra_prefix_conf_head*,
> struct in6_addr *, int);
> void add_new_prefix_to_ra_iface(struct ra_iface *r,
> - struct in6_addr *, int, struct ra_prefix_conf *);
> + struct in6_addr *, int, struct ra_prefix_conf *,
> + struct ra_iface_conf *);
> void free_ra_iface(struct ra_iface *);
> int in6_mask2prefixlen(struct in6_addr *);
> void get_interface_prefixes(struct ra_iface *,
> @@ -858,16 +859,16 @@ merge_ra_interfaces(void)
> continue;
> }
>
> - ra_iface_conf = find_ra_iface_conf(
> - &frontend_conf->ra_iface_list, ra_iface->conf_name);
> + ra_iface_conf =
> find_ra_iface_conf(&frontend_conf->ra_iface_list,
> + ra_iface->name);
>
> log_debug("add static prefixes for %s", ra_iface->name);
>
> SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface_conf->ra_prefix_list,
> entry) {
> add_new_prefix_to_ra_iface(ra_iface,
> - &ra_prefix_conf->prefix,
> - ra_prefix_conf->prefixlen, ra_prefix_conf);
> + &ra_prefix_conf->prefix, ra_prefix_conf->prefixlen,
> + ra_prefix_conf, ra_iface_conf);
> }
>
> if (ra_iface_conf->autoprefix)
> @@ -926,6 +927,7 @@ get_interface_prefixes(struct ra_iface *ra_iface, struct
> ra_prefix_conf
> struct ifaddrs *ifap, *ifa;
> struct sockaddr_in6 *sin6;
> int prefixlen;
> + struct ra_iface_conf *ra_iface_conf;
>
> log_debug("%s: %s", __func__, ra_iface->name);
>
> @@ -959,8 +961,11 @@ get_interface_prefixes(struct ra_iface *ra_iface,
> struct ra_prefix_conf
>
> mask_prefix(&sin6->sin6_addr, prefixlen);
>
> + ra_iface_conf =
> find_ra_iface_conf(&frontend_conf->ra_iface_list,
> + ra_iface->name);
> +
> add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr,
> - prefixlen, autoprefix);
> + prefixlen, autoprefix, ra_iface_conf);
> }
> freeifaddrs(ifap);
> }
> @@ -982,7 +987,8 @@ find_ra_prefix_conf(struct ra_prefix_conf_head* head,
> struct in6_addr *prefix,
>
> void
> add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr
> *addr,
> - int prefixlen, struct ra_prefix_conf *ra_prefix_conf)
> + int prefixlen, struct ra_prefix_conf *ra_prefix_conf,
> + struct ra_iface_conf *ra_iface_conf)
> {
> struct ra_prefix_conf *new_ra_prefix_conf;
>
> @@ -992,6 +998,9 @@ add_new_prefix_to_ra_iface(struct ra_iface *ra_iface,
> struct in6_addr *addr,
> return;
> }
>
> + ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list,
> + ra_iface->name);
> +
> log_debug("adding %s/%d prefix", in6_to_str(addr), prefixlen);
>
> if ((new_ra_prefix_conf = calloc(1, sizeof(*ra_prefix_conf))) == NULL)
> @@ -999,7 +1008,18 @@ add_new_prefix_to_ra_iface(struct ra_iface *ra_iface,
> struct in6_addr *addr,
> new_ra_prefix_conf->prefix = *addr;
> new_ra_prefix_conf->prefixlen = prefixlen;
> new_ra_prefix_conf->vltime = ra_prefix_conf->vltime;
I guess this line ^^ can be removed.
> - new_ra_prefix_conf->pltime = ra_prefix_conf->pltime;
> +
> + if(ra_prefix_conf->pltime == DEFAULT_PIO_PLTIME &&
> + ra_iface_conf->ra_options.router_lifetime > DEFAULT_PIO_PLTIME) {
> + new_ra_prefix_conf->pltime =
> + ra_iface_conf->ra_options.router_lifetime;
> + new_ra_prefix_conf->vltime = new_ra_prefix_conf->pltime * 48;
> + }
> + else{
> + new_ra_prefix_conf->pltime = ra_prefix_conf->pltime;
> + new_ra_prefix_conf->vltime = ra_prefix_conf->vltime;
> + }
> +
> new_ra_prefix_conf->aflag = ra_prefix_conf->aflag;
> new_ra_prefix_conf->lflag = ra_prefix_conf->lflag;
> SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry);
> diff --git parse.y parse.y
> index bb18c3d9c9c..5c45ced6147 100644
> --- parse.y
> +++ parse.y
> @@ -964,8 +964,8 @@ conf_get_ra_prefix(struct in6_addr *addr, int prefixlen)
> if (prefix == NULL)
> errx(1, "%s: calloc", __func__);
> prefix->prefixlen = prefixlen;
> - prefix->vltime = 2592000; /* 30 days */
> - prefix->pltime = 604800; /* 7 days */
> + prefix->vltime = DEFAULT_PIO_VLTIME;
> + prefix->pltime = DEFAULT_PIO_PLTIME;
> prefix->lflag = 1;
> prefix->aflag = 1;
>
> diff --git rad.h rad.h
> index 2bbf7c8ed5c..e77e8f38c4c 100644
> --- rad.h
> +++ rad.h
> @@ -31,7 +31,8 @@
> #define MIN_RTR_ADV_INTERVAL 200
> #define MAX_SEARCH 1025 /* same as MAXDNAME in arpa/nameser.h */
> #define DEFAULT_RDNS_LIFETIME 600 * 1.5
> -
> +#define DEFAULT_PIO_PLTIME 1800
> +#define DEFAULT_PIO_VLTIME 1800 * 48
> #define IMSG_DATA_SIZE(imsg) ((imsg).hdr.len - IMSG_HEADER_SIZE)
>
> enum {
It reads good and builds (a pain to apply though).
Not tested further.