From: Roy Marples Date: Mon, 13 Feb 2012 08:37:54 +0000 (+0000) Subject: Store the RA data for the interface so we can do a comparison. X-Git-Tag: v5.5.5~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46caaa5ee45a851f9995a625d8ab3c01eabcc1bd;p=thirdparty%2Fdhcpcd.git 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. --- 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);