zebra: Make Router Advertisement warnings show up once every 6 hours

RA packets are pretty chatty and when there is a warning from
a missconfiguration on the network, the log file gets filed
up with warnings.  Modify the code in rtadv.c to only spit
out the warning in these cases at most every 6 hours.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
Donald Sharp 2022-01-21 12:03:04 -05:00
parent 7a90d91586
commit 637f95bf2d
3 changed files with 48 additions and 11 deletions

View File

@ -158,6 +158,16 @@ static int if_zebra_new_hook(struct interface *ifp)
rtadv->AdvReachableTime = 0; rtadv->AdvReachableTime = 0;
rtadv->AdvRetransTimer = 0; rtadv->AdvRetransTimer = 0;
rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
memset(&rtadv->lastadvcurhoplimit, 0,
sizeof(rtadv->lastadvcurhoplimit));
memset(&rtadv->lastadvmanagedflag, 0,
sizeof(rtadv->lastadvmanagedflag));
memset(&rtadv->lastadvotherconfigflag, 0,
sizeof(rtadv->lastadvotherconfigflag));
memset(&rtadv->lastadvreachabletime, 0,
sizeof(rtadv->lastadvreachabletime));
memset(&rtadv->lastadvretranstimer, 0,
sizeof(rtadv->lastadvretranstimer));
rtadv->AdvDefaultLifetime = rtadv->AdvDefaultLifetime =
-1; /* derive from MaxRtrAdvInterval */ -1; /* derive from MaxRtrAdvInterval */
rtadv->HomeAgentPreference = 0; rtadv->HomeAgentPreference = 0;

View File

@ -81,6 +81,7 @@ struct rtadvconf {
Default: false */ Default: false */
int AdvManagedFlag; int AdvManagedFlag;
struct timeval lastadvmanagedflag;
/* The true/false value to be placed in the "Other stateful /* The true/false value to be placed in the "Other stateful
@ -89,6 +90,7 @@ struct rtadvconf {
Default: false */ Default: false */
int AdvOtherConfigFlag; int AdvOtherConfigFlag;
struct timeval lastadvotherconfigflag;
/* The value to be placed in MTU options sent by the router. A /* The value to be placed in MTU options sent by the router. A
value of zero indicates that no MTU options are sent. value of zero indicates that no MTU options are sent.
@ -105,6 +107,7 @@ struct rtadvconf {
Default: 0 */ Default: 0 */
uint32_t AdvReachableTime; uint32_t AdvReachableTime;
#define RTADV_MAX_REACHABLE_TIME 3600000 #define RTADV_MAX_REACHABLE_TIME 3600000
struct timeval lastadvreachabletime;
/* The value to be placed in the Retrans Timer field in the Router /* The value to be placed in the Retrans Timer field in the Router
Advertisement messages sent by the router. The value zero means Advertisement messages sent by the router. The value zero means
@ -112,6 +115,7 @@ struct rtadvconf {
Default: 0 */ Default: 0 */
int AdvRetransTimer; int AdvRetransTimer;
struct timeval lastadvretranstimer;
/* The default value to be placed in the Cur Hop Limit field in the /* The default value to be placed in the Cur Hop Limit field in the
Router Advertisement messages sent by the router. The value Router Advertisement messages sent by the router. The value
@ -121,6 +125,8 @@ struct rtadvconf {
Default: The value specified in the "Assigned Numbers" RFC Default: The value specified in the "Assigned Numbers" RFC
[ASSIGNED] that was in effect at the time of implementation. */ [ASSIGNED] that was in effect at the time of implementation. */
int AdvCurHopLimit; int AdvCurHopLimit;
struct timeval lastadvcurhoplimit;
#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */ #define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */
/* The value to be placed in the Router Lifetime field of Router /* The value to be placed in the Router Lifetime field of Router

View File

@ -632,45 +632,66 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
radvert = (struct nd_router_advert *)msg; radvert = (struct nd_router_advert *)msg;
if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) #define SIXHOUR2USEC (int64_t)6 * 60 * 60 * 1000000
&& (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) {
if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
(radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit) &&
(monotime_since(&zif->rtadv.lastadvcurhoplimit, NULL) >
SIXHOUR2USEC ||
zif->rtadv.lastadvcurhoplimit.tv_sec == 0)) {
flog_warn( flog_warn(
EC_ZEBRA_RA_PARAM_MISMATCH, EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s", "%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str); ifp->name, ifp->ifindex, addr_str);
monotime(&zif->rtadv.lastadvcurhoplimit);
} }
if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
&& !zif->rtadv.AdvManagedFlag) { !zif->rtadv.AdvManagedFlag &&
(monotime_since(&zif->rtadv.lastadvmanagedflag, NULL) >
SIXHOUR2USEC ||
zif->rtadv.lastadvmanagedflag.tv_sec == 0)) {
flog_warn( flog_warn(
EC_ZEBRA_RA_PARAM_MISMATCH, EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s", "%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str); ifp->name, ifp->ifindex, addr_str);
monotime(&zif->rtadv.lastadvmanagedflag);
} }
if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
&& !zif->rtadv.AdvOtherConfigFlag) { !zif->rtadv.AdvOtherConfigFlag &&
(monotime_since(&zif->rtadv.lastadvotherconfigflag, NULL) >
SIXHOUR2USEC ||
zif->rtadv.lastadvotherconfigflag.tv_sec == 0)) {
flog_warn( flog_warn(
EC_ZEBRA_RA_PARAM_MISMATCH, EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s", "%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str); ifp->name, ifp->ifindex, addr_str);
monotime(&zif->rtadv.lastadvotherconfigflag);
} }
if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
&& (ntohl(radvert->nd_ra_reachable) (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime) &&
!= zif->rtadv.AdvReachableTime)) { (monotime_since(&zif->rtadv.lastadvreachabletime, NULL) >
SIXHOUR2USEC ||
zif->rtadv.lastadvreachabletime.tv_sec == 0)) {
flog_warn( flog_warn(
EC_ZEBRA_RA_PARAM_MISMATCH, EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s", "%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str); ifp->name, ifp->ifindex, addr_str);
monotime(&zif->rtadv.lastadvreachabletime);
} }
if ((ntohl(radvert->nd_ra_retransmit) if ((ntohl(radvert->nd_ra_retransmit) !=
!= (unsigned int)zif->rtadv.AdvRetransTimer)) { (unsigned int)zif->rtadv.AdvRetransTimer) &&
(monotime_since(&zif->rtadv.lastadvretranstimer, NULL) >
SIXHOUR2USEC ||
zif->rtadv.lastadvretranstimer.tv_sec == 0)) {
flog_warn( flog_warn(
EC_ZEBRA_RA_PARAM_MISMATCH, EC_ZEBRA_RA_PARAM_MISMATCH,
"%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s", "%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
ifp->name, ifp->ifindex, addr_str); ifp->name, ifp->ifindex, addr_str);
monotime(&zif->rtadv.lastadvretranstimer);
} }
/* Create entry for neighbor if not known. */ /* Create entry for neighbor if not known. */