summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2012-02-13 08:37:54 +0000
committerRoy Marples <roy@marples.name>2012-02-13 08:37:54 +0000
commit46caaa5ee45a851f9995a625d8ab3c01eabcc1bd (patch)
tree6cac96aced587ef135e996c312b12cced40ddb7f
parent9b769f0ec46a0983d24f5fc5c44e4b3fc6fe2ba5 (diff)
downloaddhcpcd-46caaa5ee45a851f9995a625d8ab3c01eabcc1bd.tar.xz
Store the RA data for the interface so we can do a comparison.
Only log the fact we received an RA if the new RA is different or any part of the old one has expired.
-rw-r--r--dhcpcd.h3
-rw-r--r--ipv6rs.c31
-rw-r--r--net.c2
3 files changed, 31 insertions, 5 deletions
diff --git a/dhcpcd.h b/dhcpcd.h
index 0ca4b68b..b3cee6f9 100644
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -92,6 +92,8 @@ struct ra_opt {
struct ra {
struct in6_addr from;
char sfrom[INET6_ADDRSTRLEN];
+ unsigned char *data;
+ ssize_t data_len;
struct timeval received;
uint32_t lifetime;
struct in6_addr prefix;
@@ -100,6 +102,7 @@ struct ra {
uint32_t prefix_pltime;
char sprefix[INET6_ADDRSTRLEN];
struct ra_opt *options;
+ int expired;
struct ra *next;
};
diff --git a/ipv6rs.c b/ipv6rs.c
index 69838e9d..d37ff897 100644
--- a/ipv6rs.c
+++ b/ipv6rs.c
@@ -335,15 +335,27 @@ ipv6rs_handledata(_unused void *arg)
sfrom);
return;
}
-
- syslog(LOG_INFO, "%s: Router Advertisement from %s", ifp->name, sfrom);
- delete_timeouts(ifp, NULL);
-
for (rap = ifp->ras; rap; rap = rap->next) {
if (memcmp(rap->from.s6_addr, from.sin6_addr.s6_addr,
sizeof(rap->from.s6_addr)) == 0)
break;
}
+
+ /* We don't want to spam the log with the fact we got an RA every
+ * 30 seconds or so, so only spam the log if it's different. */
+ if (options & DHCPCD_DEBUG || rap == NULL ||
+ (rap->expired || rap->data_len != len ||
+ memcmp(rap->data, (unsigned char *)icp, rap->data_len) != 0))
+ {
+ if (rap) {
+ free(rap->data);
+ rap->data_len = 0;
+ }
+ syslog(LOG_INFO, "%s: Router Advertisement from %s",
+ ifp->name, sfrom);
+ }
+ delete_timeouts(ifp, NULL);
+
if (rap == NULL) {
rap = xmalloc(sizeof(*rap));
rap->next = ifp->ras;
@@ -352,11 +364,18 @@ ipv6rs_handledata(_unused void *arg)
memcpy(rap->from.s6_addr, from.sin6_addr.s6_addr,
sizeof(rap->from.s6_addr));
strlcpy(rap->sfrom, sfrom, sizeof(rap->sfrom));
+ rap->data_len = 0;
+ }
+ if (rap->data_len == 0) {
+ rap->data = xmalloc(len);
+ memcpy(rap->data, icp, len);
+ rap->data_len = len;
}
get_monotonic(&rap->received);
nd_ra = (struct nd_router_advert *)icp;
rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
+ rap->expired = 0;
len -= sizeof(struct nd_router_advert);
p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
@@ -622,6 +641,7 @@ ipv6rs_free(struct interface *ifp)
for (rap = ifp->ras; rap && (ran = rap->next, 1); rap = ran) {
ipv6rs_free_opts(rap);
+ free(rap->data);
free(rap);
}
}
@@ -652,7 +672,7 @@ ipv6rs_expire(void *arg)
if (timercmp(&now, &expire, >)) {
syslog(LOG_INFO, "%s: %s: expired Router Advertisement",
ifp->name, rap->sfrom);
- expired = 1;
+ rap->expired = expired = 1;
if (ral)
ral->next = ran;
else
@@ -675,6 +695,7 @@ ipv6rs_expire(void *arg)
syslog(LOG_INFO,
"%s: %s: expired option %d",
ifp->name, rap->sfrom, rao->type);
+ rap->expired = expired = 1;
if (raol)
raol = raon;
else
diff --git a/net.c b/net.c
index e87c9c84..8e35adca 100644
--- a/net.c
+++ b/net.c
@@ -66,6 +66,7 @@
#include "common.h"
#include "dhcp.h"
#include "if-options.h"
+#include "ipv6rs.h"
#include "net.h"
#include "signals.h"
@@ -233,6 +234,7 @@ free_interface(struct interface *iface)
{
if (!iface)
return;
+ ipv6rs_free(iface);
if (iface->state) {
free_options(iface->state->options);
free(iface->state->old);