+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2003 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "log.h"
-#include "thread.h"
+#include "frrevent.h"
#include "linklist.h"
#include "vty.h"
#include "command.h"
lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
- THREAD_OFF(lsa->refresh);
- thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
- &lsa->refresh);
+ EVENT_OFF(lsa->refresh);
+ event_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
+ &lsa->refresh);
if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
|| IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
lsa->header->adv_router, lsdb_self);
if (self) {
- THREAD_OFF(self->expire);
- THREAD_OFF(self->refresh);
+ EVENT_OFF(self->expire);
+ EVENT_OFF(self->refresh);
ospf6_lsdb_remove(self, lsdb_self);
}
lsa->name);
lsa->external_lsa_id = old->external_lsa_id;
}
- THREAD_OFF(old->expire);
- THREAD_OFF(old->refresh);
+ EVENT_OFF(old->expire);
+ EVENT_OFF(old->refresh);
ospf6_flood_clear(old);
}
monotime(&now);
if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
- thread_add_timer(master, ospf6_lsa_expire, lsa,
- OSPF_LSA_MAXAGE + lsa->birth.tv_sec
- - now.tv_sec,
- &lsa->expire);
+ event_add_timer(master, ospf6_lsa_expire, lsa,
+ OSPF_LSA_MAXAGE + lsa->birth.tv_sec -
+ now.tv_sec,
+ &lsa->expire);
} else
lsa->expire = NULL;
ospf6_lsdb_add(ospf6_lsa_copy(lsa),
on->retrans_list);
- thread_add_timer(
- master, ospf6_lsupdate_send_neighbor,
- on, on->ospf6_if->rxmt_interval,
- &on->thread_send_lsupdate);
+ event_add_timer(master,
+ ospf6_lsupdate_send_neighbor,
+ on, on->ospf6_if->rxmt_interval,
+ &on->thread_send_lsupdate);
retrans_added++;
}
}
if ((oi->type == OSPF_IFTYPE_BROADCAST)
|| (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
- thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
- &oi->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
+ &oi->thread_send_lsupdate);
} else {
/* reschedule retransmissions to all neighbors */
for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
- THREAD_OFF(on->thread_send_lsupdate);
- thread_add_event(master, ospf6_lsupdate_send_neighbor,
- on, 0, &on->thread_send_lsupdate);
+ EVENT_OFF(on->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor,
+ on, 0, &on->thread_send_lsupdate);
}
}
}
"Delayed acknowledgement (BDR & MoreRecent & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi,
- 3, &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi,
+ 3, &oi->thread_send_lsack);
} else {
if (is_debug)
zlog_debug(
"Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi,
- 3, &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi,
+ 3, &oi->thread_send_lsack);
} else {
if (is_debug)
zlog_debug(
if (is_debug)
zlog_debug("Direct acknowledgement (BDR & Duplicate)");
ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
"Delayed acknowledgement (AllOther & MoreRecent)");
/* Delayed acknowledgement */
ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
- thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
- &oi->thread_send_lsack);
+ event_add_timer(master, ospf6_lsack_send_interface, oi, 3,
+ &oi->thread_send_lsack);
return;
}
zlog_debug(
"Direct acknowledgement (AllOther & Duplicate)");
ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
return;
}
return 0;
}
+static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa,
+ struct ospf6_neighbor *from)
+{
+ struct timeval now, res;
+ unsigned int time_delta_ms;
+
+ monotime(&now);
+ timersub(&now, &lsa->installed, &res);
+ 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_OSPF6_DEBUG_FLOODING ||
+ IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
+ zlog_debug(
+ "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
+ time_delta_ms,
+ from->ospf6_if->area->ospf6->lsa_minarrival);
+ return true;
+ }
+ return false;
+}
+
/* RFC2328 section 13 The Flooding Procedure */
void ospf6_receive_lsa(struct ospf6_neighbor *from,
struct ospf6_lsa_header *lsa_header)
struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
int ismore_recent;
int is_debug = 0;
- unsigned int time_delta_ms;
ismore_recent = 1;
assert(from);
/* (1) LSA Checksum */
if (!ospf6_lsa_checksum_valid(new->header)) {
if (is_debug)
- zlog_debug("Wrong LSA Checksum, discard");
+ zlog_debug(
+ "Wrong LSA Checksum %s (Router-ID: %pI4) [Type:%s Checksum:%#06hx), discard",
+ from->name, &from->router_id,
+ ospf6_lstype_name(new->header->type),
+ ntohs(new->header->checksum));
ospf6_lsa_delete(new);
return;
}
/* a) Acknowledge back to neighbor (Direct acknowledgement,
* 13.5) */
ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
- thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
- &from->thread_send_lsack);
+ event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
+ &from->thread_send_lsack);
/* b) Discard */
ospf6_lsa_delete(new);
/* (a) MinLSArrival check */
if (old) {
- struct timeval now, res;
- monotime(&now);
- timersub(&now, &old->installed, &res);
- 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, %dms < %dms, discard",
- time_delta_ms,
- from->ospf6_if->area->ospf6
- ->lsa_minarrival);
+ if (ospf6_lsa_check_min_arrival(old, from)) {
ospf6_lsa_delete(new);
return; /* examin next lsa */
}
"Newer instance of the self-originated LSA");
zlog_debug("Schedule reorigination");
}
- thread_add_event(master, ospf6_lsa_refresh, new, 0,
- &new->refresh);
+ event_add_event(master, ospf6_lsa_refresh, new, 0,
+ &new->refresh);
}
+ /* GR: check for network topology change. */
struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
struct ospf6_area *area = from->ospf6_if->area;
- if (ospf6->gr_info.restart_in_progress)
+ if (ospf6->gr_info.restart_in_progress &&
+ (new->header->type == ntohs(OSPF6_LSTYPE_ROUTER) ||
+ new->header->type == ntohs(OSPF6_LSTYPE_NETWORK)))
ospf6_gr_check_lsdb_consistency(ospf6, area);
return;
new->name);
/* BadLSReq */
- thread_add_event(master, bad_lsreq, from, 0, NULL);
+ event_add_event(master, bad_lsreq, from, 0, NULL);
ospf6_lsa_delete(new);
return;
__PRETTY_FUNCTION__, old->name);
}
- /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
+ /* MinLSArrival check as per RFC 2328 13 (8) */
+ if (ospf6_lsa_check_min_arrival(old, from)) {
+ ospf6_lsa_delete(new);
+ return; /* examin next lsa */
+ }
ospf6_lsdb_add(ospf6_lsa_copy(old),
from->lsupdate_list);
- thread_add_event(master, ospf6_lsupdate_send_neighbor,
- from, 0, &from->thread_send_lsupdate);
+ event_add_event(master, ospf6_lsupdate_send_neighbor,
+ from, 0, &from->thread_send_lsupdate);
ospf6_lsa_delete(new);
return;