rtadvd: add multi pref64 support
Add support for multi pref64 in rtadvd and rtadvctl Reviewed By: zlei, bz Differential Revision: https://reviews.freebsd.org/D54636
This commit is contained in:
@@ -89,6 +89,7 @@ static int action_show_prefix(struct prefix *);
|
|||||||
static int action_show_rtinfo(struct rtinfo *);
|
static int action_show_rtinfo(struct rtinfo *);
|
||||||
static int action_show_rdnss(void *);
|
static int action_show_rdnss(void *);
|
||||||
static int action_show_dnssl(void *);
|
static int action_show_dnssl(void *);
|
||||||
|
static void action_show_pref64(void *);
|
||||||
|
|
||||||
static int csock_client_open(struct sockinfo *);
|
static int csock_client_open(struct sockinfo *);
|
||||||
static size_t dname_labeldec(char *, size_t, const char *);
|
static size_t dname_labeldec(char *, size_t, const char *);
|
||||||
@@ -414,6 +415,7 @@ action_show(int argc, char **argv)
|
|||||||
char argv_ifi_ra_timer[IFNAMSIZ + sizeof(":ifi_ra_timer=")];
|
char argv_ifi_ra_timer[IFNAMSIZ + sizeof(":ifi_ra_timer=")];
|
||||||
char argv_rdnss[IFNAMSIZ + sizeof(":rdnss=")];
|
char argv_rdnss[IFNAMSIZ + sizeof(":rdnss=")];
|
||||||
char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")];
|
char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")];
|
||||||
|
char argv_pref64[IFNAMSIZ + sizeof(":pref64=")];
|
||||||
char ssbuf[SSBUFLEN];
|
char ssbuf[SSBUFLEN];
|
||||||
|
|
||||||
struct timespec now, ts0, ts;
|
struct timespec now, ts0, ts;
|
||||||
@@ -691,6 +693,21 @@ action_show(int argc, char **argv)
|
|||||||
action_show_dnssl(cp.cp_val);
|
action_show_dnssl(cp.cp_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PREF64 information */
|
||||||
|
sprintf(argv_pref64, "%s:pref64=", ifi->ifi_ifname);
|
||||||
|
action_argv = argv_pref64;
|
||||||
|
|
||||||
|
error = action_propget(action_argv, &cp);
|
||||||
|
if (error)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
len = *((uint16_t *)cp.cp_val);
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
printf("\tPREF64:\n");
|
||||||
|
action_show_pref64(cp.cp_val);
|
||||||
|
}
|
||||||
|
|
||||||
if (vflag < LOG_NOTICE)
|
if (vflag < LOG_NOTICE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -896,6 +913,35 @@ action_show_dnssl(void *msg)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
action_show_pref64(void *msg)
|
||||||
|
{
|
||||||
|
struct pref64 *prf64;
|
||||||
|
uint16_t *prf64_cnt;
|
||||||
|
char ntopbuf[INET6_ADDRSTRLEN];
|
||||||
|
char ssbuf[SSBUFLEN];
|
||||||
|
char *p;
|
||||||
|
int i;
|
||||||
|
uint16_t prf64len;
|
||||||
|
|
||||||
|
p = msg;
|
||||||
|
prf64_cnt = (uint16_t *)p;
|
||||||
|
p += sizeof(*prf64_cnt);
|
||||||
|
|
||||||
|
for (i = 0; i < *prf64_cnt; i++) {
|
||||||
|
prf64 = (struct pref64 *)p;
|
||||||
|
|
||||||
|
/* RFC 8781 Section 4: Map PLC values to prefix lengths */
|
||||||
|
prf64len = (prf64->p64_plc == 0) ? 96 : 72 - (8 * prf64->p64_plc);
|
||||||
|
printf("\t %s/%d (ltime: %s)\n",
|
||||||
|
inet_ntop(AF_INET6, &prf64->p64_prefix,
|
||||||
|
ntopbuf, sizeof(ntopbuf)),
|
||||||
|
prf64len, sec2str(prf64->p64_sl, ssbuf));
|
||||||
|
|
||||||
|
p += sizeof(*prf64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Decode domain name label encoding in RFC 1035 Section 3.1 */
|
/* Decode domain name label encoding in RFC 1035 Section 3.1 */
|
||||||
static size_t
|
static size_t
|
||||||
dname_labeldec(char *dst, size_t dlen, const char *src)
|
dname_labeldec(char *dst, size_t dlen, const char *src)
|
||||||
|
|||||||
+75
-57
@@ -291,6 +291,7 @@ rm_rainfo(struct rainfo *rai)
|
|||||||
struct rdnss *rdn;
|
struct rdnss *rdn;
|
||||||
struct rdnss_addr *rdna;
|
struct rdnss_addr *rdna;
|
||||||
struct dnssl *dns;
|
struct dnssl *dns;
|
||||||
|
struct pref64 *prf64;
|
||||||
struct rtinfo *rti;
|
struct rtinfo *rti;
|
||||||
|
|
||||||
syslog(LOG_DEBUG, "<%s>: enter", __func__);
|
syslog(LOG_DEBUG, "<%s>: enter", __func__);
|
||||||
@@ -325,6 +326,10 @@ rm_rainfo(struct rainfo *rai)
|
|||||||
TAILQ_REMOVE(&rai->rai_route, rti, rti_next);
|
TAILQ_REMOVE(&rai->rai_route, rti, rti_next);
|
||||||
free(rti);
|
free(rti);
|
||||||
}
|
}
|
||||||
|
while ((prf64 = TAILQ_FIRST(&rai->rai_pref64)) != NULL) {
|
||||||
|
TAILQ_REMOVE(&rai->rai_pref64, prf64, p64_next);
|
||||||
|
free(prf64);
|
||||||
|
}
|
||||||
free(rai);
|
free(rai);
|
||||||
syslog(LOG_DEBUG, "<%s>: leave", __func__);
|
syslog(LOG_DEBUG, "<%s>: leave", __func__);
|
||||||
|
|
||||||
@@ -369,6 +374,7 @@ getconfig(struct ifinfo *ifi)
|
|||||||
TAILQ_INIT(&rai->rai_route);
|
TAILQ_INIT(&rai->rai_route);
|
||||||
TAILQ_INIT(&rai->rai_rdnss);
|
TAILQ_INIT(&rai->rai_rdnss);
|
||||||
TAILQ_INIT(&rai->rai_dnssl);
|
TAILQ_INIT(&rai->rai_dnssl);
|
||||||
|
TAILQ_INIT(&rai->rai_pref64);
|
||||||
TAILQ_INIT(&rai->rai_soliciter);
|
TAILQ_INIT(&rai->rai_soliciter);
|
||||||
rai->rai_ifinfo = ifi;
|
rai->rai_ifinfo = ifi;
|
||||||
|
|
||||||
@@ -916,52 +922,62 @@ getconfig(struct ifinfo *ifi)
|
|||||||
/*
|
/*
|
||||||
* handle pref64
|
* handle pref64
|
||||||
*/
|
*/
|
||||||
rai->rai_pref64.p64_enabled = false;
|
for (i = -1; i < MAXPREF64 ; i++) {
|
||||||
|
struct pref64 *prf64;
|
||||||
|
|
||||||
if ((addr = (char *)agetstr("pref64", &bp))) {
|
makeentry(entbuf, sizeof(entbuf), i, "pref64");
|
||||||
if (inet_pton(AF_INET6, addr, &rai->rai_pref64.p64_prefix) != 1) {
|
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",
|
syslog(LOG_ERR, "<%s> inet_pton failed for %s",
|
||||||
__func__, addr);
|
__func__, addr);
|
||||||
} else {
|
goto getconfig_free_prf64;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
/* construct the sending packet */
|
||||||
@@ -1386,6 +1402,7 @@ make_packet(struct rainfo *rai)
|
|||||||
struct rdnss *rdn;
|
struct rdnss *rdn;
|
||||||
struct nd_opt_dnssl *ndopt_dnssl;
|
struct nd_opt_dnssl *ndopt_dnssl;
|
||||||
struct dnssl *dns;
|
struct dnssl *dns;
|
||||||
|
struct pref64 *prf64;
|
||||||
struct nd_opt_pref64 *ndopt_pref64;
|
struct nd_opt_pref64 *ndopt_pref64;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct prefix *pfx;
|
struct prefix *pfx;
|
||||||
@@ -1408,8 +1425,6 @@ make_packet(struct rainfo *rai)
|
|||||||
packlen += sizeof(struct nd_opt_prefix_info) * rai->rai_pfxs;
|
packlen += sizeof(struct nd_opt_prefix_info) * rai->rai_pfxs;
|
||||||
if (rai->rai_linkmtu)
|
if (rai->rai_linkmtu)
|
||||||
packlen += sizeof(struct nd_opt_mtu);
|
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)
|
TAILQ_FOREACH(rti, &rai->rai_route, rti_next)
|
||||||
packlen += sizeof(struct nd_opt_route_info) +
|
packlen += sizeof(struct nd_opt_route_info) +
|
||||||
@@ -1436,6 +1451,9 @@ make_packet(struct rainfo *rai)
|
|||||||
|
|
||||||
packlen += len;
|
packlen += len;
|
||||||
}
|
}
|
||||||
|
TAILQ_FOREACH(prf64, &rai->rai_pref64, p64_next)
|
||||||
|
packlen += sizeof(struct nd_opt_pref64);
|
||||||
|
|
||||||
/* allocate memory for the packet */
|
/* allocate memory for the packet */
|
||||||
if ((buf = malloc(packlen)) == NULL) {
|
if ((buf = malloc(packlen)) == NULL) {
|
||||||
syslog(LOG_ERR,
|
syslog(LOG_ERR,
|
||||||
@@ -1490,19 +1508,6 @@ make_packet(struct rainfo *rai)
|
|||||||
buf += sizeof(struct nd_opt_mtu);
|
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) {
|
TAILQ_FOREACH(pfx, &rai->rai_prefix, pfx_next) {
|
||||||
uint32_t vltime, pltime;
|
uint32_t vltime, pltime;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
@@ -1616,4 +1621,17 @@ make_packet(struct rainfo *rai)
|
|||||||
syslog(LOG_DEBUG, "<%s>: nd_opt_dnssl_len = %d", __func__,
|
syslog(LOG_DEBUG, "<%s>: nd_opt_dnssl_len = %d", __func__,
|
||||||
ndopt_dnssl->nd_opt_dnssl_len);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,3 +52,4 @@ extern void get_prefix(struct rainfo *);
|
|||||||
#define MAXROUTE 100
|
#define MAXROUTE 100
|
||||||
#define MAXRDNSSENT 100
|
#define MAXRDNSSENT 100
|
||||||
#define MAXDNSSLENT 100
|
#define MAXDNSSLENT 100
|
||||||
|
#define MAXPREF64 100
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ static int cm_getprop_rai(struct ctrl_msg_pl *);
|
|||||||
static int cm_getprop_pfx(struct ctrl_msg_pl *);
|
static int cm_getprop_pfx(struct ctrl_msg_pl *);
|
||||||
static int cm_getprop_rdnss(struct ctrl_msg_pl *);
|
static int cm_getprop_rdnss(struct ctrl_msg_pl *);
|
||||||
static int cm_getprop_dnssl(struct ctrl_msg_pl *);
|
static int cm_getprop_dnssl(struct ctrl_msg_pl *);
|
||||||
|
static int cm_getprop_pref64(struct ctrl_msg_pl *);
|
||||||
static int cm_getprop_rti(struct ctrl_msg_pl *);
|
static int cm_getprop_rti(struct ctrl_msg_pl *);
|
||||||
|
|
||||||
static int cm_setprop_reload(struct ctrl_msg_pl *);
|
static int cm_setprop_reload(struct ctrl_msg_pl *);
|
||||||
@@ -101,6 +102,7 @@ static struct dispatch_table {
|
|||||||
DEF_PL_HANDLER(pfx),
|
DEF_PL_HANDLER(pfx),
|
||||||
DEF_PL_HANDLER(rdnss),
|
DEF_PL_HANDLER(rdnss),
|
||||||
DEF_PL_HANDLER(dnssl),
|
DEF_PL_HANDLER(dnssl),
|
||||||
|
DEF_PL_HANDLER(pref64),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -516,6 +518,60 @@ cm_getprop_dnssl(struct ctrl_msg_pl *cp)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cm_getprop_pref64(struct ctrl_msg_pl *cp)
|
||||||
|
{
|
||||||
|
struct ifinfo *ifi;
|
||||||
|
struct rainfo *rai;
|
||||||
|
struct pref64 *prf64;
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
uint16_t *prf64_cnt;
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "<%s> enter", __func__);
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
TAILQ_FOREACH(ifi, &ifilist, ifi_next) {
|
||||||
|
if (strcmp(cp->cp_ifname, ifi->ifi_ifname) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ifi == NULL) {
|
||||||
|
syslog(LOG_ERR, "<%s> %s not found", __func__,
|
||||||
|
cp->cp_ifname);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
if (ifi->ifi_rainfo == NULL) {
|
||||||
|
syslog(LOG_ERR, "<%s> %s has no rainfo", __func__,
|
||||||
|
cp->cp_ifname);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
rai = ifi->ifi_rainfo;
|
||||||
|
|
||||||
|
len = sizeof(*prf64_cnt);
|
||||||
|
TAILQ_FOREACH(prf64, &rai->rai_pref64, p64_next)
|
||||||
|
len += sizeof(*prf64);
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "<%s> len = %zu", __func__, len);
|
||||||
|
|
||||||
|
p = malloc(len);
|
||||||
|
if (p == NULL)
|
||||||
|
exit(1);
|
||||||
|
memset(p, 0, len);
|
||||||
|
cp->cp_val = p;
|
||||||
|
|
||||||
|
prf64_cnt = (uint16_t *)cp->cp_val;
|
||||||
|
p += sizeof(*prf64_cnt);
|
||||||
|
TAILQ_FOREACH(prf64, &rai->rai_pref64, p64_next) {
|
||||||
|
(*prf64_cnt)++;
|
||||||
|
memcpy(p, prf64, sizeof(*prf64));
|
||||||
|
p += sizeof(*prf64);
|
||||||
|
}
|
||||||
|
cp->cp_val_len = p - cp->cp_val;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
cm_getprop(struct ctrl_msg_pl *cp)
|
cm_getprop(struct ctrl_msg_pl *cp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ union nd_opt {
|
|||||||
#define NDOPT_FLAG_MTU (1 << 4)
|
#define NDOPT_FLAG_MTU (1 << 4)
|
||||||
#define NDOPT_FLAG_RDNSS (1 << 5)
|
#define NDOPT_FLAG_RDNSS (1 << 5)
|
||||||
#define NDOPT_FLAG_DNSSL (1 << 6)
|
#define NDOPT_FLAG_DNSSL (1 << 6)
|
||||||
|
#define NDOPT_FLAG_PREF64 (1 << 7)
|
||||||
|
|
||||||
static uint32_t ndopt_flags[] = {
|
static uint32_t ndopt_flags[] = {
|
||||||
[ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
|
[ND_OPT_SOURCE_LINKADDR] = NDOPT_FLAG_SRCLINKADDR,
|
||||||
@@ -146,6 +147,7 @@ static uint32_t ndopt_flags[] = {
|
|||||||
[ND_OPT_MTU] = NDOPT_FLAG_MTU,
|
[ND_OPT_MTU] = NDOPT_FLAG_MTU,
|
||||||
[ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
|
[ND_OPT_RDNSS] = NDOPT_FLAG_RDNSS,
|
||||||
[ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
|
[ND_OPT_DNSSL] = NDOPT_FLAG_DNSSL,
|
||||||
|
[ND_OPT_PREF64] = NDOPT_FLAG_PREF64,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rtadvd_shutdown(void);
|
static void rtadvd_shutdown(void);
|
||||||
@@ -1083,7 +1085,7 @@ ra_input(int len, struct nd_router_advert *nra,
|
|||||||
error = nd6_options((struct nd_opt_hdr *)(nra + 1),
|
error = nd6_options((struct nd_opt_hdr *)(nra + 1),
|
||||||
len - sizeof(struct nd_router_advert), &ndopts,
|
len - sizeof(struct nd_router_advert), &ndopts,
|
||||||
NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
|
NDOPT_FLAG_SRCLINKADDR | NDOPT_FLAG_PREFIXINFO | NDOPT_FLAG_MTU |
|
||||||
NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL);
|
NDOPT_FLAG_RDNSS | NDOPT_FLAG_DNSSL | NDOPT_FLAG_PREF64);
|
||||||
if (error) {
|
if (error) {
|
||||||
syslog(LOG_INFO,
|
syslog(LOG_INFO,
|
||||||
"<%s> ND option check failed for an RA from %s on %s",
|
"<%s> ND option check failed for an RA from %s on %s",
|
||||||
@@ -1428,7 +1430,8 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
|
|||||||
|
|
||||||
if (hdr->nd_opt_type > ND_OPT_MTU &&
|
if (hdr->nd_opt_type > ND_OPT_MTU &&
|
||||||
hdr->nd_opt_type != ND_OPT_RDNSS &&
|
hdr->nd_opt_type != ND_OPT_RDNSS &&
|
||||||
hdr->nd_opt_type != ND_OPT_DNSSL) {
|
hdr->nd_opt_type != ND_OPT_DNSSL &&
|
||||||
|
hdr->nd_opt_type != ND_OPT_PREF64) {
|
||||||
syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
|
syslog(LOG_INFO, "<%s> unknown ND option(type %d)",
|
||||||
__func__, hdr->nd_opt_type);
|
__func__, hdr->nd_opt_type);
|
||||||
continue;
|
continue;
|
||||||
@@ -1473,6 +1476,7 @@ nd6_options(struct nd_opt_hdr *hdr, int limit,
|
|||||||
case ND_OPT_REDIRECTED_HEADER:
|
case ND_OPT_REDIRECTED_HEADER:
|
||||||
case ND_OPT_RDNSS:
|
case ND_OPT_RDNSS:
|
||||||
case ND_OPT_DNSSL:
|
case ND_OPT_DNSSL:
|
||||||
|
case ND_OPT_PREF64:
|
||||||
break; /* we don't care about these options */
|
break; /* we don't care about these options */
|
||||||
case ND_OPT_SOURCE_LINKADDR:
|
case ND_OPT_SOURCE_LINKADDR:
|
||||||
case ND_OPT_MTU:
|
case ND_OPT_MTU:
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd June 4, 2011
|
.Dd January 14, 2026
|
||||||
.Dt RTADVD.CONF 5
|
.Dt RTADVD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -435,6 +435,21 @@ These items are optional.
|
|||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Cm \&pref64
|
.It Cm \&pref64
|
||||||
(str) The prefix to advertise in the PREF64 option.
|
(str) The prefix to advertise in the PREF64 option.
|
||||||
|
Multiple PREF64 prefixes can be specified by seperating entries using
|
||||||
|
.Cm pref64 ,
|
||||||
|
.Cm pref640 ,
|
||||||
|
.Cm pref641 ,
|
||||||
|
.Cm pref642 ...
|
||||||
|
options with corresponding
|
||||||
|
.Cm pref64len ,
|
||||||
|
.Cm pref64len0 ,
|
||||||
|
.Cm pref64len1 ,
|
||||||
|
.Cm pref64len2 ...
|
||||||
|
entries.
|
||||||
|
This is also true for the
|
||||||
|
.Cm pref64lifetime
|
||||||
|
option.
|
||||||
|
Note that the maximum number of prefixes depends on the receiver side.
|
||||||
.It Cm \&pref64len
|
.It Cm \&pref64len
|
||||||
(num) The length of the PREF64 prefix.
|
(num) The length of the PREF64 prefix.
|
||||||
This must be 96, 64, 56, 48, 40, or 32.
|
This must be 96, 64, 56, 48, 40, or 32.
|
||||||
@@ -484,13 +499,15 @@ ef0:\\
|
|||||||
.Pp
|
.Pp
|
||||||
The following example configures the
|
The following example configures the
|
||||||
.Li wlan0
|
.Li wlan0
|
||||||
interface and adds two DNS servers and a DNS domain search options
|
interface and adds two DNS servers, a DNS domain search,
|
||||||
|
and a PREF64 prefix,
|
||||||
using the default option lifetime values.
|
using the default option lifetime values.
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
wlan0:\\
|
wlan0:\\
|
||||||
:addr="2001:db8:ffff:1000::":prefixlen#64:\\
|
:addr="2001:db8:ffff:1000::":prefixlen#64:\\
|
||||||
:rdnss="2001:db8:ffff::10,2001:db8:ffff::2:43":\\
|
:rdnss="2001:db8:ffff::10,2001:db8:ffff::2:43":\\
|
||||||
:dnssl="example.com":
|
:dnssl="example.com":\\
|
||||||
|
:pref64="64:ff9b::":
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The following example presents the default values in an explicit manner.
|
The following example presents the default values in an explicit manner.
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ struct rdnss {
|
|||||||
|
|
||||||
struct pref64 {
|
struct pref64 {
|
||||||
TAILQ_ENTRY(pref64) p64_next;
|
TAILQ_ENTRY(pref64) p64_next;
|
||||||
bool p64_enabled;
|
|
||||||
uint16_t p64_plc; /* prefix length code */
|
uint16_t p64_plc; /* prefix length code */
|
||||||
uint16_t p64_sl; /* scaled lifetime */
|
uint16_t p64_sl; /* scaled lifetime */
|
||||||
struct in6_addr p64_prefix;
|
struct in6_addr p64_prefix;
|
||||||
@@ -227,7 +226,7 @@ struct rainfo {
|
|||||||
/* actual RA packet data and its length */
|
/* actual RA packet data and its length */
|
||||||
size_t rai_ra_datalen;
|
size_t rai_ra_datalen;
|
||||||
char *rai_ra_data;
|
char *rai_ra_data;
|
||||||
struct pref64 rai_pref64; /* PREF64 option */
|
TAILQ_HEAD(, pref64) rai_pref64; /* PREF64 option */
|
||||||
|
|
||||||
/* info about soliciter */
|
/* info about soliciter */
|
||||||
TAILQ_HEAD(, soliciter) rai_soliciter; /* recent solication source */
|
TAILQ_HEAD(, soliciter) rai_soliciter; /* recent solication source */
|
||||||
|
|||||||
Reference in New Issue
Block a user