diff options
Diffstat (limited to 'ospf6d/ospf6_message.c')
| -rw-r--r-- | ospf6d/ospf6_message.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 032988a91f..07da9a5ec1 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -535,9 +535,9 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst, oi->hello_in++; /* Execute neighbor events */ - event_execute(master, hello_received, on, 0); + event_execute(master, hello_received, on, 0, NULL); if (twoway) - event_execute(master, twoway_received, on, 0); + event_execute(master, twoway_received, on, 0, NULL); else { if (OSPF6_GR_IS_ACTIVE_HELPER(on)) { if (IS_DEBUG_OSPF6_GR) @@ -553,7 +553,7 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst, * receives one_way hellow when it acts as HELPER for * that specific neighbor. */ - event_execute(master, oneway_received, on, 0); + event_execute(master, oneway_received, on, 0, NULL); } } @@ -624,7 +624,7 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh, return; case OSPF6_NEIGHBOR_INIT: - event_execute(master, twoway_received, on, 0); + event_execute(master, twoway_received, on, 0, NULL); if (on->state != OSPF6_NEIGHBOR_EXSTART) { if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR)) zlog_debug( @@ -640,7 +640,7 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh, && !CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT) && ntohl(dbdesc->seqnum) == on->dbdesc_seqnum) { /* execute NegotiationDone */ - event_execute(master, negotiation_done, on, 0); + event_execute(master, negotiation_done, on, 0, NULL); /* Record neighbor options */ memcpy(on->options, dbdesc->options, @@ -828,7 +828,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh, return; case OSPF6_NEIGHBOR_INIT: - event_execute(master, twoway_received, on, 0); + event_execute(master, twoway_received, on, 0, NULL); if (on->state != OSPF6_NEIGHBOR_EXSTART) { if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR)) zlog_debug( @@ -855,7 +855,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh, on->dbdesc_seqnum = ntohl(dbdesc->seqnum); /* schedule NegotiationDone */ - event_execute(master, negotiation_done, on, 0); + event_execute(master, negotiation_done, on, 0, NULL); /* Record neighbor options */ memcpy(on->options, dbdesc->options, @@ -2248,6 +2248,17 @@ void ospf6_hello_send(struct event *thread) if (oi->gr.hello_delay.t_grace_send) return; + /* Check if config is still being processed */ + if (event_is_scheduled(t_ospf6_cfg)) { + if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND)) + zlog_debug( + "Suppressing Hello on interface %s during config load", + oi->interface->name); + event_add_timer(master, ospf6_hello_send, oi, + oi->hello_interval, &oi->thread_send_hello); + return; + } + if (oi->state <= OSPF6_INTERFACE_DOWN) { if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND_HDR)) zlog_debug("Unable to send Hello on down interface %s", @@ -2324,9 +2335,9 @@ static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s) if ((length + sizeof(struct ospf6_lsa_header) + OSPF6_HEADER_SIZE) > ospf6_packet_max(on->ospf6_if)) { - ospf6_lsa_unlock(lsa); + ospf6_lsa_unlock(&lsa); if (lsanext) - ospf6_lsa_unlock(lsanext); + ospf6_lsa_unlock(&lsanext); break; } stream_put(s, lsa->header, @@ -2404,9 +2415,9 @@ void ospf6_dbdesc_send_newone(struct event *thread) if (size + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { - ospf6_lsa_unlock(lsa); + ospf6_lsa_unlock(&lsa); if (lsanext) - ospf6_lsa_unlock(lsanext); + ospf6_lsa_unlock(&lsanext); break; } @@ -2425,7 +2436,7 @@ void ospf6_dbdesc_send_newone(struct event *thread) event_add_event(master, exchange_done, on, 0, &on->thread_exchange_done); - event_execute(master, ospf6_dbdesc_send, on, 0); + event_execute(master, ospf6_dbdesc_send, on, 0, NULL); } static uint16_t ospf6_make_lsreq(struct ospf6_neighbor *on, struct stream *s) @@ -2436,9 +2447,9 @@ static uint16_t ospf6_make_lsreq(struct ospf6_neighbor *on, struct stream *s) for (ALL_LSDB(on->request_list, lsa, lsanext)) { if ((length + OSPF6_HEADER_SIZE) > ospf6_packet_max(on->ospf6_if)) { - ospf6_lsa_unlock(lsa); + ospf6_lsa_unlock(&lsa); if (lsanext) - ospf6_lsa_unlock(lsanext); + ospf6_lsa_unlock(&lsanext); break; } stream_putw(s, 0); /* reserved */ @@ -2451,7 +2462,7 @@ static uint16_t ospf6_make_lsreq(struct ospf6_neighbor *on, struct stream *s) if (last_req != NULL) { if (on->last_ls_req != NULL) - on->last_ls_req = ospf6_lsa_unlock(on->last_ls_req); + ospf6_lsa_unlock(&on->last_ls_req); ospf6_lsa_lock(last_req); on->last_ls_req = last_req; @@ -2522,7 +2533,8 @@ void ospf6_lsreq_send(struct event *thread) /* schedule loading_done if request list is empty */ if (on->request_list->count == 0) { - event_add_event(master, loading_done, on, 0, NULL); + event_add_event(master, loading_done, on, 0, + &on->event_loading_done); return; } @@ -2565,9 +2577,7 @@ static void ospf6_send_lsupdate(struct ospf6_neighbor *on, struct ospf6_interface *oi, struct ospf6_packet *op) { - if (on) { - if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) || (on->ospf6_if->state == OSPF6_INTERFACE_DR) || (on->ospf6_if->state == OSPF6_INTERFACE_BDR)) @@ -2584,6 +2594,8 @@ static void ospf6_send_lsupdate(struct ospf6_neighbor *on, op->dst = alldrouters6; } if (oi) { + struct ospf6 *ospf6; + ospf6_fill_hdr_checksum(oi, op); ospf6_packet_add(oi, op); /* If ospf instance is being deleted, send the packet @@ -2591,12 +2603,27 @@ static void ospf6_send_lsupdate(struct ospf6_neighbor *on, */ if ((oi->area == NULL) || (oi->area->ospf6 == NULL)) return; - if (oi->area->ospf6->inst_shutdown) { + + ospf6 = oi->area->ospf6; + if (ospf6->inst_shutdown) { if (oi->on_write_q == 0) { - listnode_add(oi->area->ospf6->oi_write_q, oi); + listnode_add(ospf6->oi_write_q, oi); oi->on_write_q = 1; } - event_execute(master, ospf6_write, oi->area->ospf6, 0); + /* + * When ospf6d immediately calls event_execute + * for items in the oi_write_q. The event_execute + * will call ospf6_write and cause the oi_write_q + * to be emptied. *IF* there is already an event + * scheduled for the oi_write_q by something else + * then when it wakes up in the future and attempts + * to cycle through items in the queue it will + * assert. Let's stop the t_write event and + * if ospf6_write doesn't finish up the work + * it will schedule itself again. + */ + event_cancel(&ospf6->t_write); + event_execute(master, ospf6_write, ospf6, 0, NULL); } else OSPF6_MESSAGE_WRITE_ON(oi); } @@ -2917,9 +2944,9 @@ static uint16_t ospf6_make_lsack_interface(struct ospf6_interface *oi, event_add_event(master, ospf6_lsack_send_interface, oi, 0, &oi->thread_send_lsack); - ospf6_lsa_unlock(lsa); + ospf6_lsa_unlock(&lsa); if (lsanext) - ospf6_lsa_unlock(lsanext); + ospf6_lsa_unlock(&lsanext); break; } ospf6_lsa_age_update_to_send(lsa, oi->transdelay); |
