if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"ospf_flood_through_interface(): "
- "considering int %s, INBR(%s), LSA[%s]",
+ "considering int %s, INBR(%s), LSA[%s] AGE %u",
IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL",
- dump_lsa_key(lsa));
+ dump_lsa_key(lsa), ntohs(lsa->data->ls_age));
if (!ospf_if_is_enable(oi))
return 0;
more time for the ACK to be received and avoid
retransmissions */
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: MAXAGE set to LSA %s", __PRETTY_FUNCTION__,
+ inet_ntoa(lsa->data->id));
monotime(&lsa->tv_recv);
lsa->tv_orig = lsa->tv_recv;
ospf_flood_through_area(area, NULL, lsa);
}
if (listcount(update) > 0)
- ospf_ls_upd_send(nbr, update, OSPF_SEND_PACKET_DIRECT);
+ ospf_ls_upd_send(nbr, update,
+ OSPF_SEND_PACKET_DIRECT, 0);
list_delete_and_null(&update);
}
if (length + ntohs(find->data->length) > ospf_packet_max(oi)) {
if (oi->type == OSPF_IFTYPE_NBMA)
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_DIRECT);
+ OSPF_SEND_PACKET_DIRECT, 0);
else
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_INDIRECT);
+ OSPF_SEND_PACKET_INDIRECT, 0);
/* Only remove list contents. Keep ls_upd. */
list_delete_all_node(ls_upd);
/* Send rest of Link State Update. */
if (listcount(ls_upd) > 0) {
if (oi->type == OSPF_IFTYPE_NBMA)
- ospf_ls_upd_send(nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
+ ospf_ls_upd_send(nbr, ls_upd,
+ OSPF_SEND_PACKET_DIRECT, 0);
else
ospf_ls_upd_send(nbr, ls_upd,
- OSPF_SEND_PACKET_INDIRECT);
+ OSPF_SEND_PACKET_INDIRECT, 0);
list_delete_and_null(&ls_upd);
} else
update = list_new();
listnode_add(update, lsa);
- ospf_ls_upd_send(nbr, update, flag);
+
+ /*ospf instance is going down, send self originated
+ * MAXAGE LSA update to neighbors to remove from LSDB */
+ if (nbr->oi->ospf->inst_shutdown && IS_LSA_MAXAGE(lsa))
+ ospf_ls_upd_send(nbr, update, flag, 1);
+ else
+ ospf_ls_upd_send(nbr, update, flag, 0);
list_delete_and_null(&update);
}
}
static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
- struct list *update, struct in_addr addr)
+ struct list *update, struct in_addr addr,
+ int send_lsupd_now)
{
struct ospf_packet *op;
u_int16_t length = OSPF_HEADER_SIZE;
/* Add packet to the interface output queue. */
ospf_packet_add(oi, op);
-
- /* Hook thread to write packet. */
- OSPF_ISM_WRITE_ON(oi->ospf);
+ /* Call ospf_write() right away to send ospf packets to neighbors */
+ if (send_lsupd_now) {
+ struct thread os_packet_thd;
+
+ os_packet_thd.arg = (void *)oi->ospf;
+ if (oi->on_write_q == 0) {
+ listnode_add(oi->ospf->oi_write_q, oi);
+ oi->on_write_q = 1;
+ }
+ ospf_write(&os_packet_thd);
+ } else {
+ /* Hook thread to write packet. */
+ OSPF_ISM_WRITE_ON(oi->ospf);
+ }
}
static int ospf_ls_upd_send_queue_event(struct thread *thread)
update = (struct list *)rn->info;
- ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4);
+ ospf_ls_upd_queue_send(oi, update, rn->p.u.prefix4, 0);
/* list might not be empty. */
if (listcount(update) == 0) {
return 0;
}
-void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
+void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag,
+ int send_lsupd_now)
{
struct ospf_interface *oi;
struct ospf_lsa *lsa;
for (ALL_LIST_ELEMENTS_RO(update, node, lsa))
listnode_add(rn->info,
ospf_lsa_lock(lsa)); /* oi->ls_upd_queue */
+ if (send_lsupd_now) {
+ struct list *send_update_list;
+ struct route_node *rn, *rnext;
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ for (rn = route_top(oi->ls_upd_queue); rn; rn = rnext) {
+ rnext = route_next(rn);
+
+ if (rn->info == NULL)
+ continue;
+
+ send_update_list = (struct list *)rn->info;
+
+ ospf_ls_upd_queue_send(oi, send_update_list,
+ rn->p.u.prefix4, 1);
+
+ }
+ } else
+ thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
&oi->t_ls_upd_event);
}