diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 91cbbf3..e9d608f 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -269,7 +269,7 @@ ospf_flood (struct ospf *ospf, struct os ; /* Accept this LSA for quick LSDB resynchronization. */ } else if (tv_cmp (tv_sub (recent_time, current->tv_recv), - int2tv (OSPF_MIN_LS_ARRIVAL)) < 0) + msec2tv (nbr->oi->ospf->lsa_interval.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 b99b931..279a78d 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -79,7 +79,7 @@ tv_adjust (struct timeval a) return a; } -int +static int tv_ceil (struct timeval a) { a = tv_adjust (a); @@ -87,7 +87,20 @@ tv_ceil (struct timeval a) return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec); } -int +static int +tv_ceil_msec (struct timeval a) +{ + int msec; + a = tv_adjust (a); + + msec = (a.tv_sec * 1000) + (a.tv_usec / 1000); + if (a.tv_usec % 1000) + msec++; + + return msec; +} + +static int tv_floor (struct timeval a) { a = tv_adjust (a); @@ -95,6 +108,24 @@ tv_floor (struct timeval a) return a.tv_sec; } +static int +tv_floor_msec (struct timeval a) +{ + a = tv_adjust (a); + + return (a.tv_sec * 1000) + (a.tv_usec / 1000); +} + +struct timeval +msec2tv (unsigned int a) +{ + struct timeval ret; + + ret.tv_sec = 0; + ret.tv_usec = a * 1000; + return tv_adjust (ret); +} + struct timeval int2tv (int a) { @@ -136,20 +167,21 @@ tv_cmp (struct timeval a, struct timeval } int -ospf_lsa_refresh_delay (struct ospf_lsa *lsa) +ospf_lsa_refresh_delay (struct ospf *ospf, struct ospf_lsa *lsa) { - struct timeval delta, now; + struct timeval delta, refresh; int delay = 0; - gettimeofday (&now, NULL); - delta = tv_sub (now, lsa->tv_orig); + gettimeofday (&recent_time, NULL); + delta = tv_sub (recent_time, lsa->tv_orig); + refresh = msec2tv (ospf->lsa_interval.refresh); - if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0) + if (tv_cmp (delta, refresh) < 0) { - delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta)); + delay = tv_ceil_msec (tv_sub (refresh, delta)); if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds", + zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d milliseconds", lsa->data->type, inet_ntoa (lsa->data->id), delay); assert (delay > 0); @@ -219,7 +251,7 @@ ospf_lsa_checksum (struct lsa_header *ls /* Create OSPF LSA. */ struct ospf_lsa * -ospf_lsa_new () +ospf_lsa_new (void) { struct ospf_lsa *new; @@ -993,10 +1025,10 @@ ospf_router_lsa_timer_add (struct ospf_a if (lsa) { int delay; - if ((delay = ospf_lsa_refresh_delay (lsa)) > 0) + if ((delay = ospf_lsa_refresh_delay (area->ospf, lsa)) > 0) { - OSPF_AREA_TIMER_ON (area->t_router_lsa_self, - ospf_router_lsa_timer, delay); + OSPF_TIMER_MSEC_ON (area->t_router_lsa_self, + ospf_router_lsa_timer, area, delay); return; } } @@ -1231,11 +1263,11 @@ ospf_network_lsa_timer_add (struct ospf_ if (lsa) { int delay; - if ((delay = ospf_lsa_refresh_delay (lsa)) > 0) + if ((delay = ospf_lsa_refresh_delay (oi->ospf, lsa)) > 0) { - oi->t_network_lsa_self = - thread_add_timer (master, ospf_network_lsa_refresh_timer, - oi, delay); + OSPF_TIMER_MSEC_ON (oi->t_network_lsa_self, + ospf_network_lsa_refresh_timer, + oi, delay); return; } } diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 8dd054c..b540626 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -223,16 +223,15 @@ #define OSPF_LSA_UPDATE_TIMER_ON(T,F) \ /* Prototypes. */ /* XXX: Eek, time functions, similar are in lib/thread.c */ 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 (unsigned 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); extern int get_age (struct ospf_lsa *); extern u_int16_t ospf_lsa_checksum (struct lsa_header *); -extern int ospf_lsa_refresh_delay (struct ospf_lsa *); +extern int ospf_lsa_refresh_delay (struct ospf *, struct ospf_lsa *); extern const char *dump_lsa_key (struct ospf_lsa *); extern u_int32_t lsa_seqnum_increment (struct ospf_lsa *); diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 0b6ac4c..d4c5445 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1313,7 +1313,7 @@ ospf_opaque_lsa_originate_schedule (stru } if (delay0 != NULL) - delay = *delay0; + delay = *delay0 * 1000; /* * There might be some entries that have been waiting for triggering @@ -1333,8 +1333,9 @@ ospf_opaque_lsa_originate_schedule (stru if (IS_DEBUG_OSPF_EVENT) 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; + thread_add_timer_msec (master, ospf_opaque_type9_lsa_originate, + oi, delay); + delay += oi->ospf->lsa_interval.refresh; } if (! list_isempty (ospf_opaque_type10_funclist) @@ -1349,9 +1350,9 @@ ospf_opaque_lsa_originate_schedule (stru if (IS_DEBUG_OSPF_EVENT) zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d sec 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 += area->ospf->lsa_interval.refresh; } if (! list_isempty (ospf_opaque_type11_funclist) @@ -1366,9 +1367,9 @@ ospf_opaque_lsa_originate_schedule (stru if (IS_DEBUG_OSPF_EVENT) zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d sec 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->lsa_interval.refresh; } /* @@ -1436,7 +1437,7 @@ ospf_opaque_lsa_originate_schedule (stru } if (delay0 != NULL) - *delay0 = delay; + *delay0 = delay / 1000; out: return; @@ -1643,10 +1644,6 @@ ospf_opaque_lsa_refresh (struct ospf_lsa * triggered by external interventions (vty session, signaling, etc). *------------------------------------------------------------------------*/ -#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \ - if (!(T)) \ - (T) = thread_add_timer (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); static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t); @@ -1799,7 +1796,7 @@ ospf_opaque_lsa_reoriginate_schedule (vo * 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->lsa_interval.refresh; /* XXX */ if (IS_DEBUG_OSPF_EVENT) zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d" @@ -1807,7 +1804,7 @@ ospf_opaque_lsa_reoriginate_schedule (vo 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_TIMER_MSEC_ON (oipt->t_opaque_lsa_self, func, oipt, delay); out: return; @@ -2014,21 +2011,23 @@ ospf_opaque_lsa_refresh_schedule (struct case OSPF_OPAQUE_LINK_LSA: case OSPF_OPAQUE_AREA_LSA: ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa); + delay = ospf_lsa_refresh_delay (lsa->area->ospf, lsa); break; case OSPF_OPAQUE_AS_LSA: + /* XXX: This is broken. lsa->area not valid for AS-scope. */ ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa); + /*delay = ospf_lsa_refresh_delay (lsa->ospf, lsa);*/ + delay = OSPF_MIN_LS_INTERVAL_DEFAULT; break; default: zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type); goto out; } - delay = ospf_lsa_refresh_delay (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))); - OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self, + OSPF_TIMER_MSEC_ON (oipi->t_opaque_lsa_self, ospf_opaque_lsa_refresh_timer, oipi, delay); out: return; @@ -2318,7 +2317,7 @@ ospf_opaque_ls_ack_received (struct ospf return; /* Opaque capability condition must have changed. */ /* Ok, let's start origination of Opaque-LSAs. */ - delay = OSPF_MIN_LS_INTERVAL; + delay = top->lsa_interval.refresh; for (ALL_LIST_ELEMENTS (top->oiflist, node, nnode, oi)) { diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 44dca18..e964586 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1924,7 +1924,7 @@ #endif /* HAVE_OPAQUE_LSA */ gettimeofday (&now, NULL); if (tv_cmp (tv_sub (now, current->tv_orig), - int2tv (OSPF_MIN_LS_ARRIVAL)) > 0) + msec2tv (oi->ospf->lsa_interval.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/ospf_vty.c b/ospfd/ospf_vty.c index 912f1d0..eafb2eb 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2379,8 +2379,8 @@ ALIAS (no_ospf_neighbor, DEFUN (ospf_refresh_timer, ospf_refresh_timer_cmd, "refresh timer <10-1800>", - "Adjust refresh parameters\n" - "Set refresh timer\n" + "Adjust LSA refresh parameters\n" + "Set refresh timer interval\n" "Timer value in seconds\n") { struct ospf *ospf = vty->index; @@ -2396,8 +2396,9 @@ DEFUN (ospf_refresh_timer, ospf_refresh_ DEFUN (no_ospf_refresh_timer, no_ospf_refresh_timer_val_cmd, "no refresh timer <10-1800>", - "Adjust refresh parameters\n" - "Unset refresh timer\n" + NO_STR + "Adjust LSA refresh parameters\n" + "Unset LSA refresh timer\n" "Timer value in seconds\n") { struct ospf *ospf = vty->index; @@ -2420,9 +2421,118 @@ DEFUN (no_ospf_refresh_timer, no_ospf_re ALIAS (no_ospf_refresh_timer, no_ospf_refresh_timer_cmd, "no refresh timer", - "Adjust refresh parameters\n" - "Unset refresh timer\n") + NO_STR + "Adjust LSA refresh parameters\n" + "Unset LSA refresh timer\n") + +DEFUN (ospf_timers_lsa_interval, + ospf_timers_lsa_interval_cmd, + "timers lsa (refresh|arrival) <1-600000>", + "Adjust routing timers\n" + "Adjust LSA parameters\n" + "Set minimum interval between refresh of self-originated LSA\n" + "Set minimum interval between arrival of received LSAs\n" + "Timer value in milliseconds\n") +{ + struct ospf *ospf = vty->index; + static const char refr_str[] = "lsa minimum refresh interval"; + static const char arr_str[] = "lsa minimum arrival interval"; + const char *str; + unsigned int *interval; + + if (argc < 2) + { + vty_out (vty, "%% Two arguments are needed%s", VTY_NEWLINE); + return CMD_WARNING; + } + + switch (*argv[0]) + { + case 'r': + str = refr_str; + interval = &ospf->lsa_interval.refresh; + break; + case 'a': + str = arr_str; + interval = &ospf->lsa_interval.arrival; + break; + default: + vty_out (vty, "%% Must specify one of arrival or refresh%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER_RANGE (str, *interval, argv[1], 1, 600000); + + return CMD_SUCCESS; +} + +DEFUN (no_timers_lsa_interval, + no_timers_lsa_interval_val_cmd, + "no timers lsa (arrival|refresh) <1-600000>", + NO_STR + "Adjust routing timers\n" + "Adjust LSA parameters\n" + "Unset minimum interval between refresh of self-originated LSA\n" + "Unset minimum interval between arrival of received LSAs\n" + "Timer value in milliseconds\n") +{ + struct ospf *ospf = vty->index; + static const char refr_str[] = "lsa minimum refresh interval"; + static const char arr_str[] = "lsa minimum arrival interval"; + const char *str; + unsigned int interval; + unsigned int *ospf_interval; + unsigned int default_interval; + + if (argc < 1) + { + vty_out (vty, "%% At least one argument is needed%s", VTY_NEWLINE); + return CMD_WARNING; + } + + switch (*argv[0]) + { + case 'r': + str = refr_str; + ospf_interval = &ospf->lsa_interval.refresh; + default_interval = OSPF_MIN_LS_INTERVAL_DEFAULT; + break; + case 'a': + str = arr_str; + ospf_interval = &ospf->lsa_interval.arrival; + default_interval = OSPF_MIN_LS_ARRIVAL_DEFAULT; + break; + default: + vty_out (vty, "%% Must specify one of arrival or refresh%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if (argc == 2) + { + VTY_GET_INTEGER_RANGE ("lsa minimum interval", interval, + argv[1], 1, 600000); + + if (*ospf_interval != interval + || *ospf_interval == default_interval) + return CMD_SUCCESS; + } + + *ospf_interval = default_interval; + + return CMD_SUCCESS; +} +ALIAS (no_timers_lsa_interval, + no_timers_lsa_interval_cmd, + "no timers lsa (arrival|refresh)", + NO_STR + "Adjust routing timers\n" + "Adjust LSA parameters\n" + "Unset minimum interval between refresh of self-originated LSA\n" + "Unset minimum interval between arrival of received LSAs\n") + DEFUN (ospf_auto_cost_reference_bandwidth, ospf_auto_cost_reference_bandwidth_cmd, "auto-cost reference-bandwidth <1-4294967>", @@ -2706,7 +2816,14 @@ #endif /* HAVE_OPAQUE_LSA */ /* Show refresh parameters. */ vty_out (vty, " Refresh timer %d secs%s", ospf->lsa_refresh_interval, VTY_NEWLINE); - + + /* Show LSA interval parameters */ + vty_out (vty, " LSA intervals:%s", VTY_NEWLINE); + vty_out (vty, " Minimum time between refresh of an LSA: %u ms%s", + ospf->lsa_interval.refresh, VTY_NEWLINE); + vty_out (vty, " Minimum time between arrival of LSA: %u ms%s", + ospf->lsa_interval.arrival, VTY_NEWLINE); + /* Show ABR/ASBR flags. */ if (CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR)) vty_out (vty, " This router is an ABR, ABR type is: %s%s", @@ -5394,39 +5511,27 @@ ALIAS (no_ip_ospf_priority, DEFUN (ip_ospf_retransmit_interval, ip_ospf_retransmit_interval_addr_cmd, - "ip ospf retransmit-interval <3-65535> A.B.C.D", + "ip ospf retransmit-interval <1-65535> A.B.C.D", "IP Information\n" "OSPF interface commands\n" "Time between retransmitting lost link state advertisements\n" + "Link state transmit delay\n" "Seconds\n" "Address of interface") { struct interface *ifp = vty->index; u_int32_t seconds; struct in_addr addr; - int ret; struct ospf_if_params *params; params = IF_DEF_PARAMS (ifp); - seconds = strtol (argv[0], NULL, 10); - - /* Retransmit Interval range is <3-65535>. */ - if (seconds < 3 || seconds > 65535) - { - vty_out (vty, "Retransmit Interval is invalid%s", VTY_NEWLINE); - return CMD_WARNING; - } - + + /* Retransmit Interval range is <1-65535>. */ + VTY_GET_INTEGER_RANGE("retransmit interval", seconds, argv[0], 1, 65535); if (argc == 2) { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } + VTY_GET_IPV4_ADDRESS ("interface address", addr, argv[1]); params = ospf_get_if_params (ifp, addr); ospf_if_update_params (ifp, addr); @@ -5440,7 +5545,7 @@ DEFUN (ip_ospf_retransmit_interval, ALIAS (ip_ospf_retransmit_interval, ip_ospf_retransmit_interval_cmd, - "ip ospf retransmit-interval <3-65535>", + "ip ospf retransmit-interval <1-65535>", "IP Information\n" "OSPF interface commands\n" "Time between retransmitting lost link state advertisements\n" @@ -5448,7 +5553,7 @@ ALIAS (ip_ospf_retransmit_interval, ALIAS (ip_ospf_retransmit_interval, ospf_retransmit_interval_cmd, - "ospf retransmit-interval <3-65535>", + "ospf retransmit-interval <1-65535>", "OSPF interface commands\n" "Time between retransmitting lost link state advertisements\n" "Seconds\n") @@ -5524,28 +5629,16 @@ DEFUN (ip_ospf_transmit_delay, struct interface *ifp = vty->index; u_int32_t seconds; struct in_addr addr; - int ret; struct ospf_if_params *params; params = IF_DEF_PARAMS (ifp); - seconds = strtol (argv[0], NULL, 10); /* Transmit Delay range is <1-65535>. */ - if (seconds < 1 || seconds > 65535) - { - vty_out (vty, "Transmit Delay is invalid%s", VTY_NEWLINE); - return CMD_WARNING; - } + VTY_GET_INTEGER_RANGE("Transmit Delay", seconds, argv[0], 1, 65535); if (argc == 2) { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } + VTY_GET_IPV4_ADDRESS ("interface address", addr, argv[1]); params = ospf_get_if_params (ifp, addr); ospf_if_update_params (ifp, addr); @@ -7854,6 +7947,14 @@ ospf_config_write (struct vty *vty) ospf->spf_delay, ospf->spf_holdtime, ospf->spf_max_holdtime, VTY_NEWLINE); + /* LSA timers */ + if (ospf->lsa_interval.refresh != OSPF_MIN_LS_INTERVAL_DEFAULT) + vty_out (vty, " timers lsa refresh %d%s", + ospf->lsa_interval.refresh, VTY_NEWLINE); + if (ospf->lsa_interval.arrival != OSPF_MIN_LS_ARRIVAL_DEFAULT) + vty_out (vty, " timers lsa arrival %d%s", + ospf->lsa_interval.arrival, VTY_NEWLINE); + /* Max-metric router-lsa print */ config_write_stub_router (vty, ospf); @@ -8312,6 +8413,11 @@ ospf_vty_init (void) install_element (OSPF_NODE, &no_ospf_refresh_timer_val_cmd); install_element (OSPF_NODE, &no_ospf_refresh_timer_cmd); + /* lsa timer commands */ + install_element (OSPF_NODE, &ospf_timers_lsa_interval_cmd); + install_element (OSPF_NODE, &no_timers_lsa_interval_val_cmd); + install_element (OSPF_NODE, &no_timers_lsa_interval_cmd); + /* max-metric commands */ install_element (OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd); install_element (OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 95615e4..208de59 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -189,6 +189,10 @@ ospf_new (void) new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; new->spf_hold_multiplier = 1; + /* LSA Interval init */ + new->lsa_interval.refresh = OSPF_MIN_LS_INTERVAL_DEFAULT; + new->lsa_interval.arrival = OSPF_MIN_LS_ARRIVAL_DEFAULT; + /* MaxAge init. */ new->maxage_lsa = list_new (); new->t_maxage_walker = diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index c15b4d3..990e781 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -204,6 +204,14 @@ #define OSPF_STUB_ROUTER_UNCONFIGURED unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ + /* LSA Interval parameters, milliseconds */ + struct { + unsigned int refresh; /* LSA Min Refresh Interval */ + unsigned int arrival; /* LSA Min Arrival Interval */ + } lsa_interval; +#define OSPF_MIN_LS_INTERVAL_DEFAULT (OSPF_MIN_LS_INTERVAL * 1000) +#define OSPF_MIN_LS_ARRIVAL_DEFAULT (OSPF_MIN_LS_ARRIVAL * 1000) + int default_originate; /* Default information originate. */ #define DEFAULT_ORIGINATE_NONE 0 #define DEFAULT_ORIGINATE_ZEBRA 1 @@ -502,6 +510,12 @@ #define LSA_OPTIONS_GET(area) \ #define LSA_OPTIONS_NSSA_GET(area) \ (((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0) +#define OSPF_TIMER_MSEC_ON(T,F,V,D) \ + do { \ + if (!(T)) \ + (T) = thread_add_timer (master, (F), (V), (D)); \ + } while (0) + #define OSPF_TIMER_ON(T,F,V) \ do { \ if (!(T)) \