changeset 1657:4b374dc70210 draft

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.
author Roy Marples <roy@marples.name>
date Mon, 13 Feb 2012 08:37:54 +0000
parents affe9a661be7
children 80301c098bc6
files dhcpcd.h ipv6rs.c net.c
diffstat 3 files changed, 31 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/dhcpcd.h	Sun Feb 05 20:18:04 2012 +0000
+++ b/dhcpcd.h	Mon Feb 13 08:37:54 2012 +0000
@@ -92,6 +92,8 @@
 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 @@
 	uint32_t prefix_pltime;
 	char sprefix[INET6_ADDRSTRLEN];
 	struct ra_opt *options;
+	int expired;
 	struct ra *next;
 };
 
--- a/ipv6rs.c	Sun Feb 05 20:18:04 2012 +0000
+++ b/ipv6rs.c	Mon Feb 13 08:37:54 2012 +0000
@@ -335,15 +335,27 @@
 		    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 @@
 		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 @@
 
 	for (rap = ifp->ras; rap && (ran = rap->next, 1); rap = ran) {
 		ipv6rs_free_opts(rap);
+		free(rap->data);
 		free(rap);
 	}
 }
@@ -652,7 +672,7 @@
 		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 @@
 				syslog(LOG_INFO,
 				    "%s: %s: expired option %d",
 				    ifp->name, rap->sfrom, rao->type);
+				rap->expired = expired = 1;
 				if (raol)
 					raol = raon;
 				else
--- a/net.c	Sun Feb 05 20:18:04 2012 +0000
+++ b/net.c	Mon Feb 13 08:37:54 2012 +0000
@@ -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 @@
 {
 	if (!iface)
 		return;
+	ipv6rs_free(iface);
 	if (iface->state) {
 		free_options(iface->state->options);
 		free(iface->state->old);