Hi,
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. Do you
see any chance to get this upstream? If so, what needs to be still done?
Warnings that the RFC compliance is gone?
Best regards
Michael
------
diff --git a/lib/libospf.h b/lib/libospf.h
index 2796209..e8db5c1 100644
--- a/lib/libospf.h
+++ b/lib/libospf.h
@@ -39,8 +39,8 @@
#else
#define OSPF_LS_REFRESH_TIME 1800
#endif
-#define OSPF_MIN_LS_INTERVAL 5
-#define OSPF_MIN_LS_ARRIVAL 1
+#define OSPF_MIN_LS_INTERVAL 5000 /* msec */
+#define OSPF_MIN_LS_ARRIVAL 1000 /* msec */
#define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */
#define OSPF_LSA_MAXAGE 3600
#define OSPF_CHECK_AGE 300
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 0e42ff5..df19adf 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -266,7 +266,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),
- int2tv (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 f032601..e62a4e7 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -108,6 +108,17 @@ int2tv (int a)
}
struct timeval
+msec2tv (int a)
+{
+ struct timeval ret;
+
+ ret.tv_sec = 0;
+ ret.tv_usec = a * 1000;
+
+ return tv_adjust (ret);
+}
+
+struct timeval
tv_add (struct timeval a, struct timeval b)
{
struct timeval ret;
@@ -145,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, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0)
{
- delay = tv_ceil (tv_sub (int2tv (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 c71877d..dd3b91a 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -237,6 +237,7 @@ extern struct timeval tv_adjust (struct timeval);
extern int tv_ceil (struct timeval);
extern int tv_floor (struct timeval);
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_opaque.c b/ospfd/ospf_opaque.c
index f584fc7..d8f7e04 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -1334,7 +1334,7 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface
*oi, int *delay0)
zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d sec later.",
delay);
oi->t_opaque_lsa_self =
thread_add_timer (master, ospf_opaque_type9_lsa_originate, oi, delay);
- delay += OSPF_MIN_LS_INTERVAL;
+ delay += top->min_ls_interval / 1000;
}
if (! list_isempty (ospf_opaque_type10_funclist)
@@ -1351,7 +1351,7 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface
*oi, int *delay0)
area->t_opaque_lsa_self =
thread_add_timer (master, ospf_opaque_type10_lsa_originate,
area, delay);
- delay += OSPF_MIN_LS_INTERVAL;
+ delay += top->min_ls_interval / 1000;
}
if (! list_isempty (ospf_opaque_type11_funclist)
@@ -1368,7 +1368,7 @@ ospf_opaque_lsa_originate_schedule (struct ospf_interface
*oi, int *delay0)
top->t_opaque_lsa_self =
thread_add_timer (master, ospf_opaque_type11_lsa_originate,
top, delay);
- delay += OSPF_MIN_LS_INTERVAL;
+ delay += top->min_ls_interval / 1000;
}
/*
@@ -1794,7 +1794,7 @@ 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 / 1000; /* XXX */
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d"
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 587484f..e96b0dc 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -1703,7 +1703,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;
@@ -2046,7 +2046,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),
- int2tv (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);
@@ -2932,7 +2932,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 9d04892..e5e5631 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -2233,6 +2233,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>",
@@ -7289,6 +7366,14 @@ ospf_config_write (struct vty *vty)
ospf->ref_bandwidth / 1000, VTY_NEWLINE);
}
+ /* LSA timers */
+ 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 arrival %d%s",
+ ospf->min_ls_arrival, VTY_NEWLINE);
+
/* SPF timers print. */
if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT ||
ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT ||
@@ -7700,6 +7785,12 @@ ospf_vty_init (void)
install_element (OSPF_NODE, &ospf_area_import_list_cmd);
install_element (OSPF_NODE, &no_ospf_area_import_list_cmd);
+ /* LSA timer 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);
+
/* SPF timer commands */
install_element (OSPF_NODE, &ospf_timers_spf_cmd);
install_element (OSPF_NODE, &no_ospf_timers_spf_cmd);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index fe1f45d..f1fcd77 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -1006,8 +1006,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)
@@ -1024,8 +1022,8 @@ 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);
+ thread_add_timer_msec (master, ospf_distribute_list_update_timer,
+ (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 c55bdae..2df6e8a 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -193,6 +193,10 @@ ospf_new (void)
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;
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 06841b8..c50e615 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -147,6 +147,10 @@ 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. */
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev