From ac7424f9dec0d49d891e0b457afa8e31c2b854fe Mon Sep 17 00:00:00 2001 From: Michael Rossberg Date: Mon, 27 Jul 2015 21:05:44 +0200 Subject: [PATCH] configuration options for faster OSPF convergence Allow configuration of faster OSPF convergence via the min_ls_interval and min_ls_arrival timer lengths. This patch was originated by Michael, and cross-ported to Cumulus's Quagga. Signed-off-by: Michael Rossberg Signed-off-by: Donald Sharp --- lib/libospf.h | 2 +- ospfd/ospf_flood.c | 2 +- ospfd/ospf_lsa.c | 4 +- ospfd/ospf_opaque.c | 32 +++++++------- ospfd/ospf_packet.c | 6 +-- ospfd/ospf_vty.c | 101 +++++++++++++++++++++++++++++++++++++++++--- ospfd/ospf_zebra.c | 4 +- ospfd/ospfd.c | 3 +- ospfd/ospfd.h | 3 +- 9 files changed, 122 insertions(+), 35 deletions(-) diff --git a/lib/libospf.h b/lib/libospf.h index 5dc14fa932..a8fbaaf563 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -39,7 +39,7 @@ #else #define OSPF_LS_REFRESH_TIME 1800 #endif -#define OSPF_MIN_LS_INTERVAL 5 +#define OSPF_MIN_LS_INTERVAL 5000 /* msec */ #define OSPF_MIN_LS_ARRIVAL 1000 /* in milliseconds */ #define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */ #define OSPF_LSA_MAXAGE 3600 diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 36fc4650e0..4e6b7348e5 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -281,7 +281,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->lsa_minarrival)) < 0) + intms2tv (ospf->min_ls_interval)) < 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 732496d9a8..fc862966b2 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -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, int2tv (OSPF_MIN_LS_INTERVAL)) < 0) + if (tv_cmp (delta, intms2tv (OSPF_MIN_LS_INTERVAL)) < 0) { - delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta)); + delay = tv_ceil (tv_sub (intms2tv (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_opaque.c b/ospfd/ospf_opaque.c index 999893ff1f..48e12cecbd 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1343,10 +1343,10 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0) && oi->t_opaque_lsa_self == NULL) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay); oi->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type9_lsa_originate, oi, delay); - delay += OSPF_MIN_LS_INTERVAL; + thread_add_timer_msec (master, ospf_opaque_type9_lsa_originate, oi, delay); + delay += top->min_ls_interval; } if (! list_isempty (ospf_opaque_type10_funclist) @@ -1359,11 +1359,11 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0) * again and again. */ if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay); area->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type10_lsa_originate, - area, delay); - delay += OSPF_MIN_LS_INTERVAL; + thread_add_timer_msec (master, ospf_opaque_type10_lsa_originate, + area, delay); + delay += top->min_ls_interval; } if (! list_isempty (ospf_opaque_type11_funclist) @@ -1376,11 +1376,11 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0) * again and again. */ if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d sec later.", delay); + zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay); top->t_opaque_lsa_self = - thread_add_timer (master, ospf_opaque_type11_lsa_originate, - top, delay); - delay += OSPF_MIN_LS_INTERVAL; + thread_add_timer_msec (master, ospf_opaque_type11_lsa_originate, + top, delay); + delay += top->min_ls_interval; } /* @@ -1658,7 +1658,7 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa) #define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \ if (!(T)) \ - (T) = thread_add_timer (master, (F), (L), (V)) + (T) = thread_add_timer_msec (master, (F), (L), (V)) static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type); static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t); @@ -1812,15 +1812,15 @@ ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent, * it is highly possible that these conditions might not be satisfied * at the time of re-origination function is to be called. */ - delay = OSPF_MIN_LS_INTERVAL; /* XXX */ + delay = top->min_ls_interval; /* XXX */ if (IS_DEBUG_OSPF_EVENT) zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d" - " sec later: [opaque-type=%u]", + " ms later: [opaque-type=%u]", lsa_type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr))); - OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay); + OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay * 1000); out: return; @@ -2042,7 +2042,7 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0) zlog_debug ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr))); OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self, - ospf_opaque_lsa_refresh_timer, oipi, delay); + ospf_opaque_lsa_refresh_timer, oipi, delay * 1000); out: return; } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index ee1e99250d..5d2e82d8b7 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1736,7 +1736,7 @@ ospf_upd_list_clean (struct list *lsas) /* OSPF Link State Update message read -- RFC2328 Section 13. */ static void -ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh, +ospf_ls_upd (struct ospf *ospf, struct ip *iph, struct ospf_header *ospfh, struct stream *s, struct ospf_interface *oi, u_int16_t size) { struct ospf_neighbor *nbr; @@ -2093,7 +2093,7 @@ ospf_ls_upd (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->lsa_minarrival)) >= 0) + intms2tv (oi->ospf->min_ls_arrival)) >= 0) /* Trap NSSA type later.*/ ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT); DISCARD_LSA (lsa, 8); @@ -2986,7 +2986,7 @@ ospf_read (struct thread *thread) ospf_ls_req (iph, ospfh, ibuf, oi, length); break; case OSPF_MSG_LS_UPD: - ospf_ls_upd (iph, ospfh, ibuf, oi, length); + ospf_ls_upd (ospf, iph, ospfh, ibuf, oi, length); break; case OSPF_MSG_LS_ACK: ospf_ls_ack (iph, ospfh, ibuf, oi, length); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index b730a41298..ba50283dcd 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2430,6 +2430,83 @@ ospf_timers_spf_set (struct vty *vty, unsigned int delay, return CMD_SUCCESS; } +DEFUN (ospf_timers_min_ls_interval, + ospf_timers_min_ls_interval_cmd, + "timers throttle lsa all <0-5000>", + "Adjust routing timers\n" + "Throttling adaptive timer\n" + "LSA delay between transmissions\n" + NO_STR + "Delay (msec) between sending LSAs\n") +{ + struct ospf *ospf = vty->index; + unsigned int interval; + + if (argc != 1) + { + vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER ("LSA interval", interval, argv[0]); + + ospf->min_ls_interval = interval; + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_timers_min_ls_interval, + no_ospf_timers_min_ls_interval_cmd, + "no timers throttle lsa all", + NO_STR + "Adjust routing timers\n" + "Throttling adaptive timer\n" + "LSA delay between transmissions\n") +{ + struct ospf *ospf = vty->index; + ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL; + + return CMD_SUCCESS; +} + +DEFUN (ospf_timers_min_ls_arrival, + ospf_timers_min_ls_arrival_cmd, + "timers lsa arrival <0-1000>", + "Adjust routing timers\n" + "Throttling link state advertisement delays\n" + "OSPF minimum arrival interval delay\n" + "Delay (msec) between accepted LSAs\n") +{ + struct ospf *ospf = vty->index; + unsigned int arrival; + + if (argc != 1) + { + vty_out (vty, "Insufficient arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER_RANGE ("minimum LSA inter-arrival time", arrival, argv[0], 0, 1000); + + ospf->min_ls_arrival = arrival; + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_timers_min_ls_arrival, + no_ospf_timers_min_ls_arrival_cmd, + "no timers lsa arrival", + NO_STR + "Adjust routing timers\n" + "Throttling link state advertisement delays\n" + "OSPF minimum arrival interval delay\n") +{ + struct ospf *ospf = vty->index; + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; + + return CMD_SUCCESS; +} + DEFUN (ospf_timers_throttle_spf, ospf_timers_throttle_spf_cmd, "timers throttle spf <0-600000> <0-600000> <0-600000>", @@ -2540,7 +2617,7 @@ DEFUN (ospf_timers_lsa, VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); - ospf->lsa_minarrival = minarrival; + ospf->min_ls_arrival = minarrival; return CMD_SUCCESS; } @@ -2563,12 +2640,12 @@ DEFUN (no_ospf_timers_lsa, { VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); - if (ospf->lsa_minarrival != minarrival || + if (ospf->min_ls_arrival != minarrival || minarrival == OSPF_MIN_LS_ARRIVAL) return CMD_SUCCESS; } - ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL; return CMD_SUCCESS; } @@ -3350,7 +3427,8 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) json_object_int_add(json, "spfTimerDueInMsecs", time_store); } - json_object_int_add(json, "lsaMinArrivalMsecs", ospf->lsa_minarrival); + json_object_int_add(json, "lsaMinIntervalMsecs", ospf->min_ls_interval); + json_object_int_add(json, "lsaMinArrivalMsecs", ospf->min_ls_arrival); /* Show write multiplier values */ json_object_int_add(json, "writeMultiplier", ospf->write_oi_count); /* Show refresh parameters. */ @@ -3363,8 +3441,10 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf, u_char use_json) ospf_timer_dump (ospf->t_spf_calc, timebuf, sizeof (timebuf)), VTY_NEWLINE); + vty_out (vty, " LSA minimum interval %d msecs%s", + ospf->min_ls_interval, VTY_NEWLINE); vty_out (vty, " LSA minimum arrival %d msecs%s", - ospf->lsa_minarrival, VTY_NEWLINE); + ospf->min_ls_arrival, VTY_NEWLINE); /* Show write multiplier values */ vty_out (vty, " Write Multiplier set to %d %s", @@ -9203,9 +9283,12 @@ ospf_config_write (struct vty *vty) ospf->spf_max_holdtime, VTY_NEWLINE); /* LSA timers print. */ - if (ospf->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL) + vty_out (vty, " timers throttle lsa all %d%s", + ospf->min_ls_interval, VTY_NEWLINE); + if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL) vty_out (vty, " timers lsa min-arrival %d%s", - ospf->lsa_minarrival, VTY_NEWLINE); + ospf->min_ls_arrival, VTY_NEWLINE); /* Write multiplier print. */ if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) @@ -9724,6 +9807,10 @@ ospf_vty_init (void) install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_val_cmd); /* LSA timers commands */ + install_element (OSPF_NODE, &ospf_timers_min_ls_interval_cmd); + install_element (OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd); + install_element (OSPF_NODE, &ospf_timers_min_ls_arrival_cmd); + install_element (OSPF_NODE, &no_ospf_timers_min_ls_arrival_cmd); install_element (OSPF_NODE, &ospf_timers_lsa_cmd); install_element (OSPF_NODE, &no_ospf_timers_lsa_cmd); install_element (OSPF_NODE, &no_ospf_timers_lsa_val_cmd); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 58e55564f4..2bc46ca878 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -1220,8 +1220,6 @@ ospf_distribute_list_update_timer (struct thread *thread) return 0; } -#define OSPF_DISTRIBUTE_UPDATE_DELAY 5 - /* Update distribute-list and set timer to apply access-list. */ void ospf_distribute_list_update (struct ospf *ospf, uintptr_t type, @@ -1242,7 +1240,7 @@ ospf_distribute_list_update (struct ospf *ospf, uintptr_t type, /* Set timer. */ ospf->t_distribute_update = thread_add_timer (master, ospf_distribute_list_update_timer, - (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY); + (void *) type, ospf->min_ls_interval); } /* If access-list is updated, apply some check. */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 721d389509..75d823c91a 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -248,7 +248,8 @@ ospf_new (u_short instance) new->spf_hold_multiplier = 1; /* LSA timers value init */ - new->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + 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; diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index a51e5674c0..93610b1218 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -191,7 +191,8 @@ struct ospf unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ /* LSA timer parameters */ - unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */ + 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 -- 2.39.5