summaryrefslogtreecommitdiff
path: root/ospfd/ospf_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_packet.c')
-rw-r--r--ospfd/ospf_packet.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 633c3deeaf..33792bbff3 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -518,7 +518,8 @@ int ospf_ls_upd_timer(struct thread *thread)
}
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);
}
@@ -1609,10 +1610,10 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
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);
@@ -1630,10 +1631,11 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
/* 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
@@ -3792,7 +3794,13 @@ void ospf_ls_upd_send_lsa(struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
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);
}
@@ -3875,7 +3883,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *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;
@@ -3908,9 +3917,20 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
/* 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)
@@ -3934,7 +3954,7 @@ 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) {
@@ -3961,7 +3981,8 @@ static int ospf_ls_upd_send_queue_event(struct thread *thread)
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;
@@ -4006,8 +4027,24 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag)
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);
}