Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/rtadvd Unicast solicited RA's as per R...
details: https://anonhg.NetBSD.org/src/rev/22e31dca3ce7
branches: trunk
changeset: 318390:22e31dca3ce7
user: roy <roy%NetBSD.org@localhost>
date: Fri Apr 20 15:57:23 2018 +0000
description:
Unicast solicited RA's as per RFC 7772.
This is done by having a secondary timer against rainfo so we
can delay unicasting by the required randomised amount of time
without affecting the unsolicited RA timer.
diffstat:
usr.sbin/rtadvd/config.c | 6 +-
usr.sbin/rtadvd/rtadvd.c | 128 ++++++++++++++++++++++++++++------------------
usr.sbin/rtadvd/rtadvd.h | 8 +-
3 files changed, 87 insertions(+), 55 deletions(-)
diffs (truncated from 316 to 300 lines):
diff -r 35117b047f39 -r 22e31dca3ce7 usr.sbin/rtadvd/config.c
--- a/usr.sbin/rtadvd/config.c Fri Apr 20 15:29:19 2018 +0000
+++ b/usr.sbin/rtadvd/config.c Fri Apr 20 15:57:23 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: config.c,v 1.39 2018/04/20 15:29:19 roy Exp $ */
+/* $NetBSD: config.c,v 1.40 2018/04/20 15:57:23 roy Exp $ */
/* $KAME: config.c,v 1.93 2005/10/17 14:40:02 suz Exp $ */
/*
@@ -113,6 +113,7 @@
struct dnssl_domain *dnsd;
rtadvd_remove_timer(&rai->timer);
+ rtadvd_remove_timer(&rai->timer_sol);
while ((sol = TAILQ_FIRST(&rai->soliciter))) {
TAILQ_REMOVE(&rai->soliciter, sol, next);
@@ -791,7 +792,8 @@
return;
tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
tmp, tmp);
- ra_timer_set_short_delay(tmp);
+ ra_timer_set_short_delay(tmp, tmp->timer);
+ tmp->timer_sol = rtadvd_add_timer(ra_timeout_sol, NULL, tmp, NULL);
return;
diff -r 35117b047f39 -r 22e31dca3ce7 usr.sbin/rtadvd/rtadvd.c
--- a/usr.sbin/rtadvd/rtadvd.c Fri Apr 20 15:29:19 2018 +0000
+++ b/usr.sbin/rtadvd/rtadvd.c Fri Apr 20 15:57:23 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtadvd.c,v 1.64 2018/04/20 11:31:54 roy Exp $ */
+/* $NetBSD: rtadvd.c,v 1.65 2018/04/20 15:57:23 roy Exp $ */
/* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */
/*
@@ -166,7 +166,7 @@
struct in6_pktinfo *, struct sockaddr_in6 *);
static void ra_input(int, struct nd_router_advert *,
struct in6_pktinfo *, struct sockaddr_in6 *);
-static struct rainfo *ra_output(struct rainfo *);
+static struct rainfo *ra_output(struct rainfo *, bool);
static int prefix_check(struct nd_opt_prefix_info *, struct rainfo *,
struct sockaddr_in6 *);
static int nd6_options(struct nd_opt_hdr *, int, union nd_opts *, uint32_t);
@@ -440,7 +440,7 @@
rai->mininterval = MIN_DELAY_BETWEEN_RAS;
rai->maxinterval = MIN_DELAY_BETWEEN_RAS;
rai->leaving_adv = MAX_FINAL_RTR_ADVERTISEMENTS;
- ra_output(rai);
+ ra_output(rai, false);
ra_timer_update(rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
}
@@ -698,13 +698,16 @@
ra_timer_update, rai, rai);
ra_timer_update(rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
+ rtadvd_remove_timer(&rai->timer_sol);
+ rai->timer_sol = rtadvd_add_timer(ra_timeout_sol,
+ NULL, rai, NULL);
} else if (prefixchange && rai->ifflags & IFF_UP) {
/*
* An advertised prefix has been added or invalidated.
* Will notice the change in a short delay.
*/
rai->initcounter = 0;
- ra_timer_set_short_delay(rai);
+ ra_timer_set_short_delay(rai, rai->timer);
}
}
@@ -965,12 +968,20 @@
*/
/* record sockaddr waiting for RA, if possible */
- sol = malloc(sizeof(*sol));
- if (sol) {
- sol->addr = *from;
- /* XXX RFC2553 need clarification on flowinfo */
- sol->addr.sin6_flowinfo = 0;
- TAILQ_INSERT_HEAD(&rai->soliciter, sol, next);
+ TAILQ_FOREACH(sol, &rai->soliciter, next) {
+ if (IN6_ARE_ADDR_EQUAL(&sol->addr.sin6_addr, &from->sin6_addr))
+ break;
+ }
+ if (sol == NULL) {
+ sol = malloc(sizeof(*sol));
+ if (sol == NULL) {
+ logit(LOG_ERR, "%s: malloc: %m", __func__);
+ } else {
+ sol->addr = *from;
+ /* XXX RFC2553 need clarification on flowinfo */
+ sol->addr.sin6_flowinfo = 0;
+ TAILQ_INSERT_TAIL(&rai->soliciter, sol, next);
+ }
}
/*
@@ -980,14 +991,14 @@
if (rai->waiting++)
goto done;
- ra_timer_set_short_delay(rai);
+ ra_timer_set_short_delay(rai, rai->timer_sol);
done:
free_ndopts(&ndopts);
}
void
-ra_timer_set_short_delay(struct rainfo *rai)
+ra_timer_set_short_delay(struct rainfo *rai, struct rtadvd_timer *timer)
{
long delay; /* must not be greater than 1000000 */
struct timespec interval, now, min_delay, tm_tmp, *rest;
@@ -1024,7 +1035,7 @@
timespecsub(&min_delay, &tm_tmp, &min_delay);
timespecadd(&min_delay, &interval, &interval);
}
- rtadvd_set_timer(&interval, rai->timer);
+ rtadvd_set_timer(&interval, timer);
}
static void
@@ -1503,7 +1514,8 @@
exit(EXIT_FAILURE);
}
- sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo));
+ sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
+ CMSG_SPACE(sizeof(int));
sndcmsgbuf = malloc(sndcmsgbuflen);
if (sndcmsgbuf == NULL) {
logit(LOG_ERR, "%s: malloc: %m", __func__);
@@ -1522,6 +1534,12 @@
logit(LOG_ERR, "%s: IPV6_MULTICAST_HOPS: %m", __func__);
exit(EXIT_FAILURE);
}
+ on = 255;
+ if (prog_setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &on,
+ sizeof(on)) == -1) {
+ logit(LOG_ERR, "%s: IPV6_UNICAST_HOPS: %m", __func__);
+ exit(EXIT_FAILURE);
+ }
/* specify to tell receiving interface */
on = 1;
@@ -1661,7 +1679,7 @@
}
struct rainfo *
-ra_output(struct rainfo *rai)
+ra_output(struct rainfo *rai, bool solicited)
{
int i;
struct cmsghdr *cm;
@@ -1680,8 +1698,8 @@
sndmhdr.msg_iov[0].iov_base = (void *)rai->ra_data;
sndmhdr.msg_iov[0].iov_len = rai->ra_datalen;
+ /* specify the outgoing interface */
cm = CMSG_FIRSTHDR(&sndmhdr);
- /* specify the outgoing interface */
cm->cmsg_level = IPPROTO_IPV6;
cm->cmsg_type = IPV6_PKTINFO;
cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
@@ -1693,8 +1711,32 @@
"%s: send RA on %s, # of waitings = %d",
__func__, rai->ifname, rai->waiting);
+ if (solicited) {
+ /* unicast solicited RA's as per RFC 7772 */
+ while ((sol = TAILQ_FIRST(&rai->soliciter)) != NULL) {
+ sndmhdr.msg_name = (void *)&sol->addr;
+ i = prog_sendmsg(sock, &sndmhdr, 0);
+ if (i < 0 || (size_t)i != rai->ra_datalen) {
+ if (i < 0) {
+ logit(LOG_ERR,
+ "%s: unicast sendmsg on %s: %m",
+ __func__, rai->ifname);
+ }
+ }
+ TAILQ_REMOVE(&rai->soliciter, sol, next);
+ free(sol);
+ }
+
+ /* reset waiting conter */
+ rai->waiting = 0;
+
+ /* disable timer */
+ rai->timer_sol->enabled = false;
+
+ return rai;
+ }
+
i = prog_sendmsg(sock, &sndmhdr, 0);
-
if (i < 0 || (size_t)i != rai->ra_datalen) {
if (i < 0) {
logit(LOG_ERR, "%s: sendmsg on %s: %m",
@@ -1702,27 +1744,6 @@
}
}
- /*
- * unicast advertisements
- * XXX commented out. reason: though spec does not forbit it, unicast
- * advert does not really help
- */
- while ((sol = TAILQ_FIRST(&rai->soliciter)) != NULL) {
-#if 0
- sndmhdr.msg_name = (void *)&sol->addr;
- i = sendmsg(sock, &sndmhdr, 0);
- if (i < 0 || i != rai->ra_datalen) {
- if (i < 0) {
- logit(LOG_ERR,
- "%s: unicast sendmsg on %s: %m",
- __func__, rai->ifname);
- }
- }
-#endif
- TAILQ_REMOVE(&rai->soliciter, sol, next);
- free(sol);
- }
-
if (rai->leaving_adv > 0) {
if (--(rai->leaving_adv) == 0) {
/* leaving for ourself means we're shutting down */
@@ -1738,7 +1759,7 @@
rai->leaving_for->timer = rtadvd_add_timer(ra_timeout,
ra_timer_update,
rai->leaving_for, rai->leaving_for);
- ra_timer_set_short_delay(rai->leaving_for);
+ ra_timer_set_short_delay(rai->leaving_for, rai->timer);
rai->leaving_for->leaving = NULL;
free_rainfo(rai);
return NULL;
@@ -1752,29 +1773,36 @@
/* update timestamp */
prog_clock_gettime(CLOCK_MONOTONIC, &rai->lastsent);
-
- /* reset waiting conter */
- rai->waiting = 0;
-
return rai;
}
-/* process RA timer */
+/* process unsolicited RA timer */
struct rtadvd_timer *
ra_timeout(void *data)
{
struct rainfo *rai = (struct rainfo *)data;
-#ifdef notyet
- /* if necessary, reconstruct the packet. */
-#endif
+ logit(LOG_DEBUG,
+ "%s: unsolicited RA timer on %s is expired",
+ __func__, rai->ifname);
+
+ if (ra_output(rai, false))
+ return rai->timer;
+ return NULL;
+}
+
+/* process solicited RA timer */
+struct rtadvd_timer *
+ra_timeout_sol(void *data)
+{
+ struct rainfo *rai = (struct rainfo *)data;
logit(LOG_DEBUG,
- "%s: RA timer on %s is expired",
+ "%s: solicited RA timer on %s is expired",
__func__, rai->ifname);
- if (ra_output(rai))
- return rai->timer;
+ if (ra_output(rai, true))
+ return rai->timer_sol;
return NULL;
}
diff -r 35117b047f39 -r 22e31dca3ce7 usr.sbin/rtadvd/rtadvd.h
--- a/usr.sbin/rtadvd/rtadvd.h Fri Apr 20 15:29:19 2018 +0000
+++ b/usr.sbin/rtadvd/rtadvd.h Fri Apr 20 15:57:23 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtadvd.h,v 1.16 2018/04/20 10:39:37 roy Exp $ */
+/* $NetBSD: rtadvd.h,v 1.17 2018/04/20 15:57:23 roy Exp $ */
/* $KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz Exp $ */
/*
@@ -136,7 +136,8 @@
TAILQ_ENTRY(rainfo) next;
/* timer related parameters */
- struct rtadvd_timer *timer;
Home |
Main Index |
Thread Index |
Old Index