From 16e56a14321c0690178816353373adac02d2c0b2 Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Mon, 27 Jul 2015 07:56:25 +0200 Subject: [PATCH] ospfd: Fast OSPF convergence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When considering small networks that have extreme requirements on availability and thus convergence delay, the timers given in the OSPF RFC seem a little “conservative”, i.e., the delay between accepted LSAs and the rate at which LSAs are sent. Cisco introduced two commands 'timers throttle lsa all’ and 'timers lsa arrival’, which allow operators to tune these parameters. I have been writing a patch to also support 'timers lsa arrival’ fully and ‘timers throttle lsa all’ (without the throttling part) also in quagga. --- ospfd/ospf_flood.c | 2 +- ospfd/ospf_lsa.c | 18 +++++++++--------- ospfd/ospf_lsa.h | 2 +- ospfd/ospf_packet.c | 2 +- ospfd/ospfd.c | 8 ++++---- ospfd/ospfd.h | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index d0d446f7a6e4..e9f443111a2f 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -284,7 +284,7 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, ; /* Accept this LSA for quick LSDB resynchronization. */ } else if (tv_cmp (tv_sub (recent_relative_time (), current->tv_recv), - intms2tv (ospf->min_ls_arrival)) < 0) + msec2tv (ospf->min_ls_arrival)) < 0) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("LSA[Flooding]: LSA is received recently."); diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 62c455e77440..ec0eab5f0a3e 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -97,25 +97,25 @@ tv_floor (struct timeval a) } struct timeval -intms2tv (int a) +int2tv (int a) { struct timeval ret; - ret.tv_sec = a/1000; - ret.tv_usec = (a%1000)*1000; + ret.tv_sec = a; + ret.tv_usec = 0; return ret; } struct timeval -int2tv (int a) +msec2tv (int a) { struct timeval ret; - ret.tv_sec = a; - ret.tv_usec = 0; + ret.tv_sec = a/1000; + ret.tv_usec = (a%1000) * 1000; - return ret; + return tv_adjust (ret); } struct timeval @@ -156,9 +156,9 @@ ospf_lsa_refresh_delay (struct ospf_lsa *lsa) quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); delta = tv_sub (now, lsa->tv_orig); - if (tv_cmp (delta, intms2tv (OSPF_MIN_LS_INTERVAL)) < 0) + if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0) { - delay = tv_ceil (tv_sub (intms2tv (OSPF_MIN_LS_INTERVAL), delta)); + delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta)); if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds", diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 0700d0d54657..f2c08b1b9356 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -236,8 +236,8 @@ struct as_external_lsa extern struct timeval tv_adjust (struct timeval); extern int tv_ceil (struct timeval); extern int tv_floor (struct timeval); -extern struct timeval intms2tv (int); extern struct timeval int2tv (int); +extern struct timeval msec2tv (int); extern struct timeval tv_add (struct timeval, struct timeval); extern struct timeval tv_sub (struct timeval, struct timeval); extern int tv_cmp (struct timeval, struct timeval); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 4b9f1c651a5a..a714683b06f3 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2080,7 +2080,7 @@ ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh, quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); if (tv_cmp (tv_sub (now, current->tv_orig), - intms2tv (oi->ospf->min_ls_arrival)) >= 0) + msec2tv (ospf->min_ls_arrival)) >= 0) /* Trap NSSA type later.*/ ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT); DISCARD_LSA (lsa, 8); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 050cbad19611..5b5014eec8c1 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -248,16 +248,16 @@ ospf_new (u_short instance) new->default_metric = -1; new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH; + /* LSA timers */ + new->min_ls_interval = OSPF_MIN_LS_INTERVAL; + new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + /* SPF timer value init. */ new->spf_delay = OSPF_SPF_DELAY_DEFAULT; new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT; new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; new->spf_hold_multiplier = 1; - /* LSA timers value init */ - new->min_ls_interval = OSPF_MIN_LS_INTERVAL; - new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; - /* MaxAge init. */ new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT; new->maxage_lsa = route_table_init(); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 0dc90c8ae01e..95809306d6e0 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -181,16 +181,16 @@ struct ospf #define OSPF_STUB_MAX_METRIC_SUMMARY_COST 0x00ff0000 + /* LSA timers */ + unsigned int min_ls_interval; /* minimum delay between LSAs (in msec) */ + unsigned int min_ls_arrival; /* minimum interarrival time between LSAs (in msec) */ + /* SPF parameters */ unsigned int spf_delay; /* SPF delay time. */ unsigned int spf_holdtime; /* SPF hold time. */ unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ - /* LSA timer parameters */ - unsigned int min_ls_interval; /* mininum delay between LSAs (in msec) */ - unsigned int min_ls_arrival; /* LSA minimum arrival in milliseconds. */ - int default_originate; /* Default information originate. */ #define DEFAULT_ORIGINATE_NONE 0 #define DEFAULT_ORIGINATE_ZEBRA 1