diff --git a/lib/libospf.h b/lib/libospf.h index 8762dfb259..76feaa82e6 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -40,7 +40,7 @@ #define OSPF_LS_REFRESH_TIME 1800 #endif #define OSPF_MIN_LS_INTERVAL 5 -#define OSPF_MIN_LS_ARRIVAL 1 +#define OSPF_MIN_LS_ARRIVAL 1000 /* in milliseconds */ #define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */ #define OSPF_LSA_MAXAGE 3600 #define OSPF_CHECK_AGE 300 diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 5fe4cda8a4..b17406f247 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -760,6 +760,7 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL; int ismore_recent; int is_debug = 0; + int time_delta_ms; ismore_recent = 1; assert (from); @@ -863,10 +864,12 @@ ospf6_receive_lsa (struct ospf6_neighbor *from, struct timeval now, res; quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); timersub (&now, &old->installed, &res); - if (res.tv_sec < OSPF_MIN_LS_ARRIVAL) + time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000); + if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) { if (is_debug) - zlog_debug ("LSA can't be updated within MinLSArrival, discard"); + zlog_debug ("LSA can't be updated within MinLSArrival, %dms < %dms, discard", + time_delta_ms, from->ospf6_if->area->ospf6->lsa_minarrival); ospf6_lsa_delete (new); return; /* examin next lsa */ } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index b24bf73ccf..424902fff5 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -135,6 +135,9 @@ ospf6_create (void) o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; o->spf_hold_multiplier = 1; + /* LSA timers value init */ + o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + o->route_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, ROUTES); o->route_table->scope = o; o->route_table->hook_add = ospf6_top_route_hook_add; @@ -402,6 +405,70 @@ DEFUN (no_ospf6_log_adjacency_changes_detail, return CMD_SUCCESS; } +DEFUN (ospf6_timers_lsa, + ospf6_timers_lsa_cmd, + "timers lsa min-arrival <0-600000>", + "Adjust routing timers\n" + "OSPF6 LSA timers\n" + "Minimum delay in receiving new version of a LSA\n" + "Delay in milliseconds\n") +{ + unsigned int minarrival; + struct ospf6 *ospf = vty->index; + + if (!ospf) + return CMD_SUCCESS; + + if (argc != 1) + { + vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); + + ospf->lsa_minarrival = minarrival; + + return CMD_SUCCESS; +} + +DEFUN (no_ospf6_timers_lsa, + no_ospf6_timers_lsa_cmd, + "no timers lsa min-arrival", + NO_STR + "Adjust routing timers\n" + "OSPF6 LSA timers\n" + "Minimum delay in receiving new version of a LSA\n") +{ + unsigned int minarrival; + struct ospf6 *ospf = vty->index; + + if (!ospf) + return CMD_SUCCESS; + + if (argc) + { + VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); + + if (ospf->lsa_minarrival != minarrival || + minarrival == OSPF_MIN_LS_ARRIVAL) + return CMD_SUCCESS; + } + + ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + + return CMD_SUCCESS; +} + +ALIAS (no_ospf6_timers_lsa, + no_ospf6_timers_lsa_val_cmd, + "no timers lsa min-arrival <0-600000>", + NO_STR + "Adjust routing timers\n" + "OSPF6 LSA timers\n" + "Minimum delay in receiving new version of a LSA\n" + "Delay in milliseconds\n") + DEFUN (ospf6_interface_area, ospf6_interface_area_cmd, "interface IFNAME area A.B.C.D", @@ -650,6 +717,9 @@ ospf6_show (struct vty *vty, struct ospf6 *o) /* Redistribute configuration */ /* XXX */ + vty_out (vty, " LSA minimum arrival %d msecs%s", o->lsa_minarrival, + VTY_NEWLINE); + /* Show SPF parameters */ vty_out(vty, " Initial SPF scheduling delay %d millisec(s)%s" " Minimum hold time between consecutive SPFs %d millsecond(s)%s" @@ -906,6 +976,11 @@ config_write_ospf6 (struct vty *vty) vty_out (vty, " auto-cost reference-bandwidth %d%s", ospf6->ref_bandwidth / 1000, VNL); + /* LSA timers print. */ + if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + vty_out (vty, " timers lsa min-arrival %d%s", ospf6->lsa_minarrival, + VTY_NEWLINE); + ospf6_stub_router_config_write (vty); ospf6_redistribute_config_write (vty); ospf6_area_config_write (vty); @@ -964,6 +1039,12 @@ ospf6_top_init (void) install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd); install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd); install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd); + + /* LSA timers commands */ + install_element (OSPF6_NODE, &ospf6_timers_lsa_cmd); + install_element (OSPF6_NODE, &no_ospf6_timers_lsa_cmd); + install_element (OSPF6_NODE, &no_ospf6_timers_lsa_val_cmd); + install_element (OSPF6_NODE, &ospf6_interface_area_cmd); install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd); install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index d6f4bf0f3d..518db3860c 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -65,6 +65,9 @@ struct ospf6 #define OSPF6_LOG_ADJACENCY_CHANGES (1 << 0) #define OSPF6_LOG_ADJACENCY_DETAIL (1 << 1) + /* LSA timer parameters */ + unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */ + /* SPF parameters */ unsigned int spf_delay; /* SPF delay time. */ unsigned int spf_holdtime; /* SPF hold time. */ diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index bc41454287..9ab46b9c9e 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -280,7 +280,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) + intms2tv (ospf->lsa_minarrival)) < 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 ebdb390abb..732496d9a8 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -96,6 +96,17 @@ tv_floor (struct timeval a) return a.tv_sec; } +struct timeval +intms2tv (int a) +{ + struct timeval ret; + + ret.tv_sec = a/1000; + ret.tv_usec = (a%1000)*1000; + + return ret; +} + struct timeval int2tv (int a) { diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index ef6bf88c9b..0700d0d546 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -236,6 +236,7 @@ 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 tv_add (struct timeval, struct timeval); extern struct timeval tv_sub (struct timeval, struct timeval); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 8f0d8537fa..44ee806e3f 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2100,7 +2100,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) + intms2tv (oi->ospf->lsa_minarrival)) >= 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 c3bbccda22..aa22a9eed9 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2505,6 +2505,71 @@ ALIAS_DEPRECATED (no_ospf_timers_throttle_spf, "Adjust routing timers\n" "OSPF SPF timers\n") +DEFUN (ospf_timers_lsa, + ospf_timers_lsa_cmd, + "timers lsa min-arrival <0-600000>", + "Adjust routing timers\n" + "OSPF LSA timers\n" + "Minimum delay in receiving new version of a LSA\n" + "Delay in milliseconds\n") +{ + unsigned int minarrival; + struct ospf *ospf = vty->index; + + if (!ospf) + return CMD_SUCCESS; + + if (argc != 1) + { + vty_out (vty, "Insufficient number of arguments%s", VTY_NEWLINE); + return CMD_WARNING; + } + + VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); + + ospf->lsa_minarrival = minarrival; + + return CMD_SUCCESS; +} + +DEFUN (no_ospf_timers_lsa, + no_ospf_timers_lsa_cmd, + "no timers lsa min-arrival", + NO_STR + "Adjust routing timers\n" + "OSPF LSA timers\n" + "Minimum delay in receiving new version of a LSA\n") +{ + unsigned int minarrival; + struct ospf *ospf = vty->index; + + if (!ospf) + return CMD_SUCCESS; + + if (argc) + { + VTY_GET_INTEGER ("LSA min-arrival", minarrival, argv[0]); + + if (ospf->lsa_minarrival != minarrival || + minarrival == OSPF_MIN_LS_ARRIVAL) + return CMD_SUCCESS; + } + + ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL; + + return CMD_SUCCESS; +} + +ALIAS (no_ospf_timers_lsa, + no_ospf_timers_lsa_val_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") + + DEFUN (ospf_neighbor, ospf_neighbor_cmd, "neighbor A.B.C.D", @@ -3031,6 +3096,9 @@ show_ip_ospf_common (struct vty *vty, struct ospf *ospf) ospf_timer_dump (ospf->t_spf_calc, timebuf, sizeof (timebuf)), VTY_NEWLINE); + vty_out (vty, " LSA minimum arrival %d msecs%s", + ospf->lsa_minarrival, VTY_NEWLINE); + /* Show write multiplier values */ vty_out (vty, " Write Multiplier set to %d %s", ospf->write_oi_count, VTY_NEWLINE); @@ -8403,7 +8471,12 @@ ospf_config_write (struct vty *vty) vty_out (vty, " timers throttle spf %d %d %d%s", ospf->spf_delay, ospf->spf_holdtime, ospf->spf_max_holdtime, VTY_NEWLINE); - + + /* LSA timers print. */ + if (ospf->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + vty_out (vty, " timers lsa min-arrival %d%s", + ospf->lsa_minarrival, VTY_NEWLINE); + /* Write multiplier print. */ if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT) vty_out (vty, " ospf write-multiplier %d%s", @@ -8919,6 +8992,11 @@ ospf_vty_init (void) install_element (OSPF_NODE, &ospf_timers_throttle_spf_cmd); install_element (OSPF_NODE, &no_ospf_timers_throttle_spf_cmd); + /* LSA timers commands */ + 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); + /* refresh timer commands */ install_element (OSPF_NODE, &ospf_refresh_timer_cmd); install_element (OSPF_NODE, &no_ospf_refresh_timer_val_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 73a86c2180..ff9a82c37a 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -247,6 +247,9 @@ ospf_new (u_short instance) new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT; new->spf_hold_multiplier = 1; + /* LSA timers value init */ + new->lsa_minarrival = 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 d3dba184aa..a51e5674c0 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -190,6 +190,9 @@ struct ospf unsigned int spf_max_holdtime; /* SPF maximum-holdtime */ unsigned int spf_hold_multiplier; /* Adaptive multiplier for hold time */ + /* LSA timer parameters */ + unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */ + int default_originate; /* Default information originate. */ #define DEFAULT_ORIGINATE_NONE 0 #define DEFAULT_ORIGINATE_ZEBRA 1