Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ospfd: Fix opaque LSA refresh interval and modify LSA cmds. #17118

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions doc/user/ospfd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,44 @@ To start OSPF process you have to specify the OSPF router.
This command supersedes the *timers spf* command in previous FRR
releases.

.. clicmd:: timers throttle lsa all (0-5000)

This command sets the minumum interval between originations of the
same LSA or the `minimum LSA refresh interval`. The time is specified
in milliseconds and the default is 5 seconds (5000 milliseconds) consistent
with the architectual constant MinLSInterval specified in Appendix D of
RFC 2328. When a self-originated LSA needs to be reoriginated, it may be
delayed for up to this interval.

.. code-block:: frr

router ospf
timers throttle lsa all 1000


In this example, the `mininum LSA refresh interval` is set to 1000ms. This
command reduces the delay between successive originations of a self-originated
LSA from 5000 milliseconds to 1000 milliseconds.

.. clicmd:: timers lsa min-arrival (0-60000)

This command sets the minumum interval between receptions of instances of
the same LSA or the `minimum LSA arrival interval`. The time is specified in
milliseconds and the default is 1 second (1000 milliseconds) consistent with
the architectual constant MinLSArrival specified in Appendix D of RFC 2328. If a
newer instance of the same LSA is received in less than this interval, it is
ignored.

.. code-block:: frr

router ospf
timers lsa min-arrival 50


In this example, the `minimum LSA arrival interval` is set to 50ms. This
command reduces the minimum interval required between instances of the same
LSA from 1000 milliseconds to 50 milliseconds.

.. clicmd:: max-metric router-lsa [on-startup (5-86400)|on-shutdown (5-100)]

.. clicmd:: max-metric router-lsa administrative
Expand Down
5 changes: 3 additions & 2 deletions lib/libospf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ extern "C" {
#else
#define OSPF_LS_REFRESH_TIME 1800
#endif
#define OSPF_MIN_LS_INTERVAL 5000 /* msec */
#define OSPF_MIN_LS_ARRIVAL 1000 /* in milliseconds */
#define OSPF_MIN_LS_INTERVAL 5000 /* milliseconds */
#define OSPF_MIN_LS_ARRIVAL 1000 /* milliseconds */
#define OSPF_MIN_LS_ARRIVAL_MAX 5000 /* milliseconds */
#define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */
#define OSPF_LSA_MAXAGE 3600
#define OSPF_CHECK_AGE 300
Expand Down
28 changes: 17 additions & 11 deletions ospfd/ospf_lsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,30 @@ struct timeval msec2tv(int a)
return ret;
}

int ospf_lsa_refresh_delay(struct ospf_lsa *lsa)
int tv2msec(struct timeval tv)
{
int msecs;

msecs = tv.tv_sec * 1000;
msecs += tv.tv_usec / 1000;

return msecs;
}

int ospf_lsa_refresh_delay(struct ospf *ospf, struct ospf_lsa *lsa)
{
struct timeval delta;
int delay = 0;

if (monotime_since(&lsa->tv_orig, &delta)
< OSPF_MIN_LS_INTERVAL * 1000LL) {
struct timeval minv = msec2tv(OSPF_MIN_LS_INTERVAL);
timersub(&minv, &delta, &minv);
if (monotime_since(&lsa->tv_orig, &delta) < ospf->min_ls_interval * 1000LL) {
struct timeval minv = msec2tv(ospf->min_ls_interval);

/* TBD: remove padding to full sec, return timeval instead */
delay = minv.tv_sec + !!minv.tv_usec;
timersub(&minv, &delta, &minv);
delay = tv2msec(minv);

if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
zlog_debug(
"LSA[Type%d:%pI4]: Refresh timer delay %d seconds",
lsa->data->type, &lsa->data->id,
delay);
zlog_debug("LSA[Type%d:%pI4]: Refresh timer delay %d milliseconds",
lsa->data->type, &lsa->data->id, delay);

assert(delay > 0);
}
Expand Down
4 changes: 3 additions & 1 deletion ospfd/ospf_lsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,14 @@ enum lsid_status { LSID_AVAILABLE = 0, LSID_CHANGE, LSID_NOT_AVAILABLE };
/* Prototypes. */
/* XXX: Eek, time functions, similar are in lib/thread.c */
extern struct timeval int2tv(int);

extern struct timeval msec2tv(int a);
extern int tv2msec(struct timeval tv);

extern int get_age(struct ospf_lsa *lsa);
extern uint16_t ospf_lsa_checksum(struct lsa_header *lsah);
extern int ospf_lsa_checksum_valid(struct lsa_header *lsah);
extern int ospf_lsa_refresh_delay(struct ospf_lsa *lsa);
extern int ospf_lsa_refresh_delay(struct ospf *ospf, struct ospf_lsa *lsa);

extern const char *dump_lsa_key(struct ospf_lsa *lsa);
extern uint32_t lsa_seqnum_increment(struct ospf_lsa *lsa);
Expand Down
24 changes: 11 additions & 13 deletions ospfd/ospf_opaque.c
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,7 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
struct opaque_info_per_type *oipt;
struct opaque_info_per_id *oipi;
struct ospf_lsa *lsa;
struct ospf *top;
struct ospf *ospf;
int delay;

if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
Expand All @@ -2076,35 +2076,33 @@ void ospf_opaque_lsa_refresh_schedule(struct ospf_lsa *lsa0)
goto out;
}

ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
ospf = lsa0->area->ospf;

/* Delete this lsa from neighbor retransmit-list. */
switch (lsa->data->type) {
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as(top, lsa);
ospf_ls_retransmit_delete_nbr_as(ospf, lsa);
break;
default:
flog_warn(EC_OSPF_LSA_UNEXPECTED, "%s: Unexpected LSA-type(%u)",
__func__, lsa->data->type);
goto out;
}

delay = ospf_lsa_refresh_delay(lsa);
delay = ospf_lsa_refresh_delay(ospf, lsa);

if (IS_DEBUG_OSPF_EVENT)
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)));
zlog_debug("Schedule Type-%u Opaque-LSA to REFRESH in %d msec 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 * 1000);
OSPF_OPAQUE_TIMER_ON(oipi->t_opaque_lsa_self, ospf_opaque_lsa_refresh_timer, oipi, delay);
out:
return;
}
Expand Down
79 changes: 26 additions & 53 deletions ospfd/ospf_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -2304,34 +2304,9 @@ static int ospf_timers_spf_set(struct vty *vty, unsigned int delay,
return CMD_SUCCESS;
}

DEFUN (ospf_timers_min_ls_interval,
DEFPY (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"
"All LSA types\n"
"Delay (msec) between sending LSAs\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx_number = 4;
unsigned int interval;

if (argc < 5) {
vty_out(vty, "Insufficient arguments\n");
return CMD_WARNING_CONFIG_FAILED;
}

interval = strtoul(argv[idx_number]->arg, NULL, 10);

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 [(0-5000)]",
"[no] timers throttle lsa all ![(0-5000)]$lsa_refresh_interval",
NO_STR
"Adjust routing timers\n"
"Throttling adaptive timer\n"
Expand All @@ -2340,7 +2315,11 @@ DEFUN (no_ospf_timers_min_ls_interval,
"Delay (msec) between sending LSAs\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL;

if (no)
ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL;
else
ospf->min_ls_interval = strtoul(lsa_refresh_interval_str, NULL, 10);

return CMD_SUCCESS;
}
Expand Down Expand Up @@ -2389,40 +2368,35 @@ DEFUN (no_ospf_timers_throttle_spf,
}


DEFUN (ospf_timers_lsa_min_arrival,
DEFPY (ospf_timers_lsa_min_arrival,
ospf_timers_lsa_min_arrival_cmd,
"timers lsa min-arrival (0-600000)",
"[no] timers lsa min-arrival ![(0-5000)]$min_arrival",
NO_STR
"Adjust routing timers\n"
"OSPF LSA timers\n"
"Minimum delay in receiving new version of a LSA\n"
"Minimum delay in receiving new version of an LSA\n"
"Delay in milliseconds\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
ospf->min_ls_arrival = strtoul(argv[argc - 1]->arg, NULL, 10);
if (no)
ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
else
ospf->min_ls_arrival = strtoul(min_arrival_str, NULL, 10);
return CMD_SUCCESS;
}

DEFUN (no_ospf_timers_lsa_min_arrival,
no_ospf_timers_lsa_min_arrival_cmd,
"no timers lsa min-arrival [(0-600000)]",
NO_STR
"Adjust routing timers\n"
"OSPF LSA timers\n"
"Minimum delay in receiving new version of a LSA\n"
"Delay in milliseconds\n")
DEFPY_HIDDEN (ospf_timers_lsa_min_arrival_deprecated,
ospf_timers_lsa_min_arrival_deprecated_cmd,
"timers lsa min-arrival [(5001-60000)]$min_arrival",
"Adjust routing timers\n"
"OSPF LSA timers\n"
"Minimum delay in receiving new version of an LSA\n"
"Deprecated delay in milliseconds - delays in this range default to 5000 msec\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
unsigned int minarrival;

if (argc > 4) {
minarrival = strtoul(argv[argc - 1]->arg, NULL, 10);

if (ospf->min_ls_arrival != minarrival
|| minarrival == OSPF_MIN_LS_ARRIVAL)
return CMD_SUCCESS;
}

ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
vty_out(vty, "%% OSPF `timers lsa min-arrival` set to the maximum of %u milliseconds\n",
OSPF_MIN_LS_ARRIVAL_MAX);
ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL_MAX;

return CMD_SUCCESS;
}
Expand Down Expand Up @@ -13709,9 +13683,8 @@ void ospf_vty_init(void)

/* 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_lsa_min_arrival_cmd);
install_element(OSPF_NODE, &no_ospf_timers_lsa_min_arrival_cmd);
install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_deprecated_cmd);

/* refresh timer commands */
install_element(OSPF_NODE, &ospf_refresh_timer_cmd);
Expand Down
Loading