aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/rtadvd/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/rtadvd/config.c')
-rw-r--r--usr.sbin/rtadvd/config.c146
1 files changed, 78 insertions, 68 deletions
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
index 1b37d53c8b91..8b7079c17822 100644
--- a/usr.sbin/rtadvd/config.c
+++ b/usr.sbin/rtadvd/config.c
@@ -291,6 +291,7 @@ rm_rainfo(struct rainfo *rai)
struct rdnss *rdn;
struct rdnss_addr *rdna;
struct dnssl *dns;
+ struct pref64 *prf64;
struct rtinfo *rti;
syslog(LOG_DEBUG, "<%s>: enter", __func__);
@@ -325,6 +326,10 @@ rm_rainfo(struct rainfo *rai)
TAILQ_REMOVE(&rai->rai_route, rti, rti_next);
free(rti);
}
+ while ((prf64 = TAILQ_FIRST(&rai->rai_pref64)) != NULL) {
+ TAILQ_REMOVE(&rai->rai_pref64, prf64, p64_next);
+ free(prf64);
+ }
free(rai);
syslog(LOG_DEBUG, "<%s>: leave", __func__);
@@ -369,6 +374,7 @@ getconfig(struct ifinfo *ifi)
TAILQ_INIT(&rai->rai_route);
TAILQ_INIT(&rai->rai_rdnss);
TAILQ_INIT(&rai->rai_dnssl);
+ TAILQ_INIT(&rai->rai_pref64);
TAILQ_INIT(&rai->rai_soliciter);
rai->rai_ifinfo = ifi;
@@ -436,10 +442,6 @@ getconfig(struct ifinfo *ifi)
}
val |= ND_RA_FLAG_RTPREF_LOW;
}
-#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
- if (strchr(flagstr, 'S'))
- val |= ND_RA_FLAG_IPV6_ONLY;
-#endif
} else
MAYHAVE(val, "raflags", 0);
@@ -455,9 +457,6 @@ getconfig(struct ifinfo *ifi)
__func__, rai->rai_rtpref, ifi->ifi_ifname);
goto getconfig_free_rai;
}
-#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
- rai->rai_ipv6onlyflg = val & ND_RA_FLAG_IPV6_ONLY;
-#endif
MAYHAVE(val, "rltime", rai->rai_maxinterval * 3);
if ((uint16_t)val && ((uint16_t)val < rai->rai_maxinterval ||
@@ -613,7 +612,7 @@ getconfig_free_pfx:
get_prefix(rai);
MAYHAVE(val64, "mtu", 0);
- if (val < 0 || val64 > 0xffffffff) {
+ if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR,
"<%s> mtu (%" PRIu64 ") on %s out of range",
__func__, val64, ifi->ifi_ifname);
@@ -916,52 +915,62 @@ getconfig_free_dns:
/*
* handle pref64
*/
- rai->rai_pref64.p64_enabled = false;
+ for (i = -1; i < MAXPREF64 ; i++) {
+ struct pref64 *prf64;
- if ((addr = (char *)agetstr("pref64", &bp))) {
- if (inet_pton(AF_INET6, addr, &rai->rai_pref64.p64_prefix) != 1) {
+ makeentry(entbuf, sizeof(entbuf), i, "pref64");
+ addr = (char *)agetstr(entbuf, &bp);
+ if (addr == NULL)
+ continue;
+ ELM_MALLOC(prf64, exit(1));
+
+ if (inet_pton(AF_INET6, addr, &prf64->p64_prefix) != 1) {
syslog(LOG_ERR, "<%s> inet_pton failed for %s",
__func__, addr);
- } else {
- rai->rai_pref64.p64_enabled = true;
-
- switch (val64 = agetnum("pref64len")) {
- case -1:
- case 96:
- rai->rai_pref64.p64_plc = 0;
- break;
- case 64:
- rai->rai_pref64.p64_plc = 1;
- break;
- case 56:
- rai->rai_pref64.p64_plc = 2;
- break;
- case 48:
- rai->rai_pref64.p64_plc = 3;
- break;
- case 40:
- rai->rai_pref64.p64_plc = 4;
- break;
- case 32:
- rai->rai_pref64.p64_plc = 5;
- break;
- default:
- syslog(LOG_ERR, "prefix length %" PRIi64
- "on %s is invalid; disabling PREF64",
- val64, ifi->ifi_ifname);
- rai->rai_pref64.p64_enabled = 0;
- break;
- }
+ goto getconfig_free_prf64;
+ }
- /* This logic is from RFC 8781 section 4.1. */
- val64 = agetnum("pref64lifetime");
- if (val64 == -1)
- val64 = rai->rai_lifetime * 3;
- if (val64 > 65528)
- val64 = 65528;
- val64 = (val64 + 7) / 8;
- rai->rai_pref64.p64_sl = (uint16_t) (uint64_t) val64;
+ makeentry(entbuf, sizeof(entbuf), i, "pref64len");
+ MAYHAVE(val64, entbuf, 96);
+ switch (val64) {
+ case 96:
+ prf64->p64_plc = 0;
+ break;
+ case 64:
+ prf64->p64_plc = 1;
+ break;
+ case 56:
+ prf64->p64_plc = 2;
+ break;
+ case 48:
+ prf64->p64_plc = 3;
+ break;
+ case 40:
+ prf64->p64_plc = 4;
+ break;
+ case 32:
+ prf64->p64_plc = 5;
+ break;
+ default:
+ syslog(LOG_ERR, "PREF64 prefix length %" PRIi64
+ "on %s is invalid; skipping",
+ val64, ifi->ifi_ifname);
+ goto getconfig_free_prf64;
}
+
+ makeentry(entbuf, sizeof(entbuf), i, "pref64lifetime");
+ MAYHAVE(val64, entbuf, (rai->rai_lifetime * 3));
+ /* This logic is from RFC 8781 section 4.1. */
+ if (val64 > 65528)
+ val64 = 65528;
+ val64 = (val64 + 7) / 8;
+ prf64->p64_sl = (uint16_t)val64;
+
+ /* link into chain */
+ TAILQ_INSERT_TAIL(&rai->rai_pref64, prf64, p64_next);
+ continue;
+getconfig_free_prf64:
+ free(prf64);
}
/* construct the sending packet */
@@ -1012,12 +1021,15 @@ getconfig_free_dns:
} else {
struct rdnss *rdn;
struct dnssl *dns;
+ struct rtinfo *rti;
rai_old->rai_lifetime = 0;
TAILQ_FOREACH(rdn, &rai_old->rai_rdnss, rd_next)
rdn->rd_ltime = 0;
TAILQ_FOREACH(dns, &rai_old->rai_dnssl, dn_next)
dns->dn_ltime = 0;
+ TAILQ_FOREACH(rti, &rai_old->rai_route, rti_next)
+ rti->rti_ltime = 0;
ifi->ifi_rainfo_trans = rai_old;
ifi->ifi_state = IFI_STATE_TRANSITIVE;
@@ -1386,6 +1398,7 @@ make_packet(struct rainfo *rai)
struct rdnss *rdn;
struct nd_opt_dnssl *ndopt_dnssl;
struct dnssl *dns;
+ struct pref64 *prf64;
struct nd_opt_pref64 *ndopt_pref64;
size_t len;
struct prefix *pfx;
@@ -1408,8 +1421,6 @@ make_packet(struct rainfo *rai)
packlen += sizeof(struct nd_opt_prefix_info) * rai->rai_pfxs;
if (rai->rai_linkmtu)
packlen += sizeof(struct nd_opt_mtu);
- if (rai->rai_pref64.p64_enabled)
- packlen += sizeof(struct nd_opt_pref64);
TAILQ_FOREACH(rti, &rai->rai_route, rti_next)
packlen += sizeof(struct nd_opt_route_info) +
@@ -1436,6 +1447,9 @@ make_packet(struct rainfo *rai)
packlen += len;
}
+ TAILQ_FOREACH(prf64, &rai->rai_pref64, p64_next)
+ packlen += sizeof(struct nd_opt_pref64);
+
/* allocate memory for the packet */
if ((buf = malloc(packlen)) == NULL) {
syslog(LOG_ERR,
@@ -1467,10 +1481,6 @@ make_packet(struct rainfo *rai)
rai->rai_managedflg ? ND_RA_FLAG_MANAGED : 0;
ra->nd_ra_flags_reserved |=
rai->rai_otherflg ? ND_RA_FLAG_OTHER : 0;
-#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
- ra->nd_ra_flags_reserved |=
- rai->rai_ipv6onlyflg ? ND_RA_FLAG_IPV6_ONLY : 0;
-#endif
ra->nd_ra_router_lifetime = htons(rai->rai_lifetime);
ra->nd_ra_reachable = htonl(rai->rai_reachabletime);
ra->nd_ra_retransmit = htonl(rai->rai_retranstimer);
@@ -1490,19 +1500,6 @@ make_packet(struct rainfo *rai)
buf += sizeof(struct nd_opt_mtu);
}
- if (rai->rai_pref64.p64_enabled) {
- ndopt_pref64 = (struct nd_opt_pref64 *)buf;
- ndopt_pref64->nd_opt_pref64_type = ND_OPT_PREF64;
- ndopt_pref64->nd_opt_pref64_len = 2;
- ndopt_pref64->nd_opt_pref64_sl_plc =
- (htons(rai->rai_pref64.p64_sl << 3)) |
- htons((rai->rai_pref64.p64_plc & 0x7));
- memcpy(&ndopt_pref64->nd_opt_prefix[0],
- &rai->rai_pref64.p64_prefix,
- sizeof(ndopt_pref64->nd_opt_prefix));
- buf += sizeof(struct nd_opt_pref64);
- }
-
TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
uint32_t vltime, pltime;
struct timespec now;
@@ -1616,4 +1613,17 @@ make_packet(struct rainfo *rai)
syslog(LOG_DEBUG, "<%s>: nd_opt_dnssl_len = %d", __func__,
ndopt_dnssl->nd_opt_dnssl_len);
}
+
+ TAILQ_FOREACH(prf64, &rai->rai_pref64, p64_next) {
+ ndopt_pref64 = (struct nd_opt_pref64 *)buf;
+ ndopt_pref64->nd_opt_pref64_type = ND_OPT_PREF64;
+ ndopt_pref64->nd_opt_pref64_len = 2;
+ ndopt_pref64->nd_opt_pref64_sl_plc =
+ (htons(prf64->p64_sl << 3)) |
+ htons((prf64->p64_plc & 0x7));
+ memcpy(&ndopt_pref64->nd_opt_prefix[0],
+ &prf64->p64_prefix,
+ sizeof(ndopt_pref64->nd_opt_prefix));
+ buf += sizeof(struct nd_opt_pref64);
+ }
}