summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtsold/rtsold.c
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2011-06-08 16:03:29 +0000
committerhrs <hrs@FreeBSD.org>2011-06-08 16:03:29 +0000
commit1eefc7ab06b30aec595b347e288fa4afd1535a39 (patch)
treed51f3ada57d0885094e28644af3dc20fefe35f40 /usr.sbin/rtsold/rtsold.c
parent724e938247a1f61f3cd1e8db0e998c3ad7490198 (diff)
downloadFreeBSD-src-1eefc7ab06b30aec595b347e288fa4afd1535a39.zip
FreeBSD-src-1eefc7ab06b30aec595b347e288fa4afd1535a39.tar.gz
- Accumulate RA options instead of replacing old ones when a new RA arrived.
RFC 4861 6.3.4 clearly defines handling multiple RAs in this way. - RDNSS/DNSSL options from multiple RAs on a single link will be gathered and sent to resolvconf(8). - Call "resolvconf -d" only after at least one RDNSS or DNSSL option is received and then all of them are expired. - The rtsold.dump output now supports displaying a list of the RA options. - Use more human-readable expression for logging values of struct timeval. Discussed with: ume
Diffstat (limited to 'usr.sbin/rtsold/rtsold.c')
-rw-r--r--usr.sbin/rtsold/rtsold.c92
1 files changed, 59 insertions, 33 deletions
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index a0eb593..94046a1 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -44,6 +44,7 @@
#include <netinet/in.h>
#include <netinet/icmp6.h>
#include <netinet/in_var.h>
+#include <arpa/inet.h>
#include <netinet6/nd6.h>
@@ -408,7 +409,9 @@ ifconfig(char *ifname)
}
memset(ifi, 0, sizeof(*ifi));
ifi->sdl = sdl;
-
+ ifi->ifi_rdnss = IFI_DNSOPT_STATE_NOINFO;
+ ifi->ifi_dnssl = IFI_DNSOPT_STATE_NOINFO;
+ TAILQ_INIT(&ifi->ifi_rainfo);
strlcpy(ifi->ifname, ifname, sizeof(ifi->ifname));
/* construct a router solicitation message */
@@ -500,6 +503,19 @@ ifreconfig(char *ifname)
}
#endif
+struct rainfo *
+find_rainfo(struct ifinfo *ifi, struct sockaddr_in6 *sin6)
+{
+ struct rainfo *rai;
+
+ TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next)
+ if (memcmp(&rai->rai_saddr.sin6_addr, &sin6->sin6_addr,
+ sizeof(rai->rai_saddr.sin6_addr)) == 0)
+ return (rai);
+
+ return (NULL);
+}
+
struct ifinfo *
find_ifinfo(int ifindex)
{
@@ -556,6 +572,7 @@ rtsol_check_timer(void)
static struct timeval returnval;
struct timeval now, rtsol_timer;
struct ifinfo *ifi;
+ struct rainfo *rai;
struct ra_opt *rao;
int flags;
@@ -565,18 +582,21 @@ rtsol_check_timer(void)
TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) {
if (timercmp(&ifi->expire, &now, <=)) {
- if (dflag > 1)
- warnmsg(LOG_DEBUG, __func__,
- "timer expiration on %s, "
- "state = %d", ifi->ifname,
- ifi->state);
-
- /* Remove all RA options. */
- while ((rao = TAILQ_FIRST(&ifi->ifi_ra_opt)) != NULL) {
- if (rao->rao_msg != NULL)
- free(rao->rao_msg);
- TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next);
- free(rao);
+ warnmsg(LOG_DEBUG, __func__, "timer expiration on %s, "
+ "state = %d", ifi->ifname, ifi->state);
+
+ while((rai = TAILQ_FIRST(&ifi->ifi_rainfo)) != NULL) {
+ /* Remove all RA options. */
+ TAILQ_REMOVE(&ifi->ifi_rainfo, rai, rai_next);
+ while ((rao = TAILQ_FIRST(&rai->rai_ra_opt)) !=
+ NULL) {
+ TAILQ_REMOVE(&rai->rai_ra_opt, rao,
+ rao_next);
+ if (rao->rao_msg != NULL)
+ free(rao->rao_msg);
+ free(rao);
+ }
+ free(rai);
}
switch (ifi->state) {
case IFS_DOWN:
@@ -645,21 +665,27 @@ rtsol_check_timer(void)
rtsol_timer_update(ifi);
} else {
/* Expiration check for RA options. */
- struct ra_opt *rao_tmp;
int expire = 0;
- TAILQ_FOREACH_SAFE(rao, &ifi->ifi_ra_opt, rao_next, rao_tmp) {
- warnmsg(LOG_DEBUG, __func__,
- "RA expiration timer: "
- "type=%d, msg=%s, timer=%ld:%08ld",
- rao->rao_type, (char *)rao->rao_msg,
- (long)rao->rao_expire.tv_sec,
- (long)rao->rao_expire.tv_usec);
- if (timercmp(&now, &rao->rao_expire, >=)) {
+ TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) {
+ TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) {
warnmsg(LOG_DEBUG, __func__,
- "RA expiration timer: expired.");
- TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next);
- expire = 1;
+ "RA expiration timer: "
+ "type=%d, msg=%s, expire=%s",
+ rao->rao_type, (char *)rao->rao_msg,
+ sec2str(&rao->rao_expire));
+ if (timercmp(&now, &rao->rao_expire,
+ >=)) {
+ warnmsg(LOG_DEBUG, __func__,
+ "RA expiration timer: "
+ "expired.");
+ TAILQ_REMOVE(&rai->rai_ra_opt,
+ rao, rao_next);
+ if (rao->rao_msg != NULL)
+ free(rao->rao_msg);
+ free(rao);
+ expire = 1;
+ }
}
}
if (expire)
@@ -678,9 +704,10 @@ rtsol_check_timer(void)
else
timersub(&rtsol_timer, &now, &returnval);
- if (dflag > 1)
- warnmsg(LOG_DEBUG, __func__, "New timer is %ld:%08ld",
- (long)returnval.tv_sec, (long)returnval.tv_usec);
+ now.tv_sec += returnval.tv_sec;
+ now.tv_usec += returnval.tv_usec;
+ warnmsg(LOG_DEBUG, __func__, "New timer is %s",
+ sec2str(&now));
return (&returnval);
}
@@ -751,11 +778,10 @@ rtsol_timer_update(struct ifinfo *ifi)
gettimeofday(&now, NULL);
timeradd(&now, &ifi->timer, &ifi->expire);
- if (dflag > 1)
- warnmsg(LOG_DEBUG, __func__,
- "set timer for %s to %d:%d", ifi->ifname,
- (int)ifi->timer.tv_sec,
- (int)ifi->timer.tv_usec);
+ now.tv_sec += ifi->timer.tv_sec;
+ now.tv_usec += ifi->timer.tv_usec;
+ warnmsg(LOG_DEBUG, __func__, "set timer for %s to %s",
+ ifi->ifname, sec2str(&now));
}
#undef MILLION
OpenPOWER on IntegriCloud