aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPouria Mousavizadeh Tehrani <pouria@FreeBSD.org>2026-04-01 13:29:15 +0000
committerPouria Mousavizadeh Tehrani <pouria@FreeBSD.org>2026-04-16 19:03:08 +0000
commit4dc6522d57c748cdaddd8327909574360a3de517 (patch)
tree09a04613d70caa4a9e025a25c141df91419c18e1
parentc8d25804f56ae7c35eaa492b6110807a2675d41a (diff)
rtadvd(8): Set route info lifetime to 0 during shutdown
RFC 4191 section 3.1: if the received route's lifetime is zero, the route is removed from the Routing Table if present. Also, do not tell route information option is unknown. PR: 263982 Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D55448
-rw-r--r--usr.sbin/rtadvd/config.c3
-rw-r--r--usr.sbin/rtadvd/rtadvd.c17
2 files changed, 18 insertions, 2 deletions
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c
index 70fb2ed7dc28..8b7079c17822 100644
--- a/usr.sbin/rtadvd/config.c
+++ b/usr.sbin/rtadvd/config.c
@@ -1021,12 +1021,15 @@ getconfig_free_prf64:
} 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;
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
index 2e9bced7c00e..b772f78845d8 100644
--- a/usr.sbin/rtadvd/rtadvd.c
+++ b/usr.sbin/rtadvd/rtadvd.c
@@ -138,6 +138,7 @@ union nd_opt {
#define NDOPT_FLAG_RDNSS (1 << 5)
#define NDOPT_FLAG_DNSSL (1 << 6)
#define NDOPT_FLAG_PREF64 (1 << 7)
+#define NDOPT_FLAG_ROUTEINFO (1 << 8)
static uint32_t ndopt_flags[] = {
[ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
@@ -148,6 +149,7 @@ static uint32_t ndopt_flags[] = {
[ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
[ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
[ND_OPT_PREF64] = NDOPT_FLAG_PREF64,
+ [ND_OPT_ROUTE_INFO] = NDOPT_FLAG_ROUTEINFO,
};
static void rtadvd_shutdown(void);
@@ -372,6 +374,7 @@ rtadvd_shutdown(void)
struct rainfo *rai;
struct rdnss *rdn;
struct dnssl *dns;
+ struct rtinfo *rti;
if (wait_shutdown) {
syslog(LOG_INFO,
@@ -416,6 +419,8 @@ rtadvd_shutdown(void)
rdn->rd_ltime = 0;
TAILQ_FOREACH(dns, &rai->rai_dnssl, dn_next)
dns->dn_ltime = 0;
+ TAILQ_FOREACH(rti, &rai->rai_route, rti_next)
+ rti->rti_ltime = 0;
}
TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
if (!ifi->ifi_persist)
@@ -1085,7 +1090,8 @@ ra_input(int len, struct nd_router_advert *nra,
error = nd6_options((struct nd_opt_hdr *)(nra + 1),
len - sizeof(struct nd_router_advert), &ndopts,
NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
- NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL | NDOPT_FLAG_PREF64);
+ NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL | NDOPT_FLAG_PREF64 |
+ NDOPT_FLAG_ROUTEINFO);
if (error) {
syslog(LOG_INFO,
"<%s> ND option check failed for an RA from %s on %s",
@@ -1418,7 +1424,8 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
if (hdr->nd_opt_type > ND_OPT_MTU &&
hdr->nd_opt_type != ND_OPT_RDNSS &&
hdr->nd_opt_type != ND_OPT_DNSSL &&
- hdr->nd_opt_type != ND_OPT_PREF64) {
+ hdr->nd_opt_type != ND_OPT_PREF64 &&
+ hdr->nd_opt_type != ND_OPT_ROUTE_INFO) {
syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
__func__, hdr->nd_opt_type);
continue;
@@ -1452,6 +1459,11 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
case ND_OPT_PREFIX_INFORMATION:
if (optlen == sizeof(struct nd_opt_prefix_info))
break;
+ goto skip;
+ case ND_OPT_ROUTE_INFO:
+ if (optlen >= 8 && optlen <= 24 &&
+ (optlen - sizeof(struct nd_opt_route_info)) % 8 == 0)
+ break;
skip:
syslog(LOG_INFO, "<%s> invalid option length",
__func__);
@@ -1464,6 +1476,7 @@ skip:
case ND_OPT_RDNSS:
case ND_OPT_DNSSL:
case ND_OPT_PREF64:
+ case ND_OPT_ROUTE_INFO:
break; /* we don't care about these options */
case ND_OPT_SOURCE_LINKADDR:
case ND_OPT_MTU: