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.c128
1 files changed, 75 insertions, 53 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 9930b0bd49..ca4bb0a2b9 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -1031,7 +1031,7 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
old_state = nbr->state;
/* Add event to thread. */
- OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived);
+ OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_HelloReceived);
/* RFC2328 Section 9.5.1
If the router is not eligible to become Designated Router,
@@ -1081,40 +1081,76 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
return;
}
- /* If neighbor itself declares DR and no BDR exists,
- cause event BackupSeen */
- if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router))
- if (hello->bd_router.s_addr == INADDR_ANY
- && oi->state == ISM_Waiting)
+ if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
+ /* As per the GR Conformance Test Case 7.2. Section 3
+ * "Also, if X was the Designated Router on network segment S
+ * when the helping relationship began, Y maintains X as the
+ * Designated Router until the helping relationship is
+ * terminated."
+ * When I am helper for this neighbor, I should not trigger the
+ * ISM Events. Also Intentionally not setting the priority and
+ * other fields so that when the neighbor exits the Grace
+ * period, it can handle if there is any change before GR and
+ * after GR. */
+ if (IS_DEBUG_OSPF_GR)
+ zlog_debug(
+ "%s, Neighbor is under GR Restart, hence ignoring the ISM Events",
+ __PRETTY_FUNCTION__);
+ } else {
+ /* If neighbor itself declares DR and no BDR exists,
+ cause event BackupSeen */
+ if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router))
+ if (hello->bd_router.s_addr == INADDR_ANY
+ && oi->state == ISM_Waiting)
+ OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
+
+ /* neighbor itself declares BDR. */
+ if (oi->state == ISM_Waiting
+ && IPV4_ADDR_SAME(&nbr->address.u.prefix4,
+ &hello->bd_router))
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
- /* neighbor itself declares BDR. */
- if (oi->state == ISM_Waiting
- && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router))
- OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
-
- /* had not previously. */
- if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)
- && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router))
- || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router)
- && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->d_router)))
- OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
-
- /* had not previously. */
- if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)
- && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router))
- || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->bd_router)
- && IPV4_ADDR_SAME(&nbr->address.u.prefix4, &nbr->bd_router)))
- OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
-
- /* Neighbor priority check. */
- if (nbr->priority >= 0 && nbr->priority != hello->priority)
- OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
+ /* had not previously. */
+ if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router)
+ && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->d_router))
+ || (IPV4_ADDR_CMP(&nbr->address.u.prefix4, &hello->d_router)
+ && IPV4_ADDR_SAME(&nbr->address.u.prefix4,
+ &nbr->d_router)))
+ OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
+
+ /* had not previously. */
+ if ((IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->bd_router)
+ && IPV4_ADDR_CMP(&nbr->address.u.prefix4, &nbr->bd_router))
+ || (IPV4_ADDR_CMP(&nbr->address.u.prefix4,
+ &hello->bd_router)
+ && IPV4_ADDR_SAME(&nbr->address.u.prefix4,
+ &nbr->bd_router)))
+ OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
+
+ /* Neighbor priority check. */
+ if (nbr->priority >= 0 && nbr->priority != hello->priority)
+ OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
+ }
/* Set neighbor information. */
nbr->priority = hello->priority;
nbr->d_router = hello->d_router;
nbr->bd_router = hello->bd_router;
+
+ /*
+ * RFC 3623 - Section 2:
+ * "If the restarting router determines that it was the Designated
+ * Router on a given segment prior to the restart, it elects
+ * itself as the Designated Router again. The restarting router
+ * knows that it was the Designated Router if, while the
+ * associated interface is in Waiting state, a Hello packet is
+ * received from a neighbor listing the router as the Designated
+ * Router".
+ */
+ if (oi->area->ospf->gr_info.restart_in_progress
+ && oi->state == ISM_Waiting
+ && IPV4_ADDR_SAME(&hello->d_router, &oi->address->u.prefix4))
+ DR(oi) = hello->d_router;
}
/* Save DD flags/options/Seqnum received. */
@@ -1356,14 +1392,10 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
UNSET_FLAG(dd->options, OSPF_OPTION_O);
}
- /* Add event to thread. */
- OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived);
-
if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
zlog_info(
"%s:Packet[DD]: Neighbor %pI4 state is %s, seq_num:0x%x, local:0x%x",
- (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
- &nbr->router_id,
+ ospf_get_name(oi->ospf), &nbr->router_id,
lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
ntohl(dd->dd_seqnum), nbr->dd_seqnum);
@@ -1601,9 +1633,6 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
return;
}
- /* Add event to thread. */
- OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived);
-
/* Neighbor State should be Exchange or later. */
if (nbr->state != NSM_Exchange && nbr->state != NSM_Loading
&& nbr->state != NSM_Full) {
@@ -1848,9 +1877,6 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
return;
}
- /* Add event to thread. */
- OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived);
-
/* Check neighbor state. */
if (nbr->state < NSM_Exchange) {
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
@@ -2089,11 +2115,10 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
if (current == NULL
|| (ret = ospf_lsa_more_recent(current, lsa)) < 0) {
/* CVE-2017-3224 */
- if (current && (lsa->data->ls_seqnum ==
- htonl(OSPF_MAX_SEQUENCE_NUMBER)
- && !IS_LSA_MAXAGE(lsa))) {
+ if (current && (IS_LSA_MAX_SEQ(current))
+ && (IS_LSA_MAX_SEQ(lsa)) && !IS_LSA_MAXAGE(lsa)) {
zlog_debug(
- "Link State Update[%s]: has Max Seq but not MaxAge. Dropping it",
+ "Link State Update[%s]: has Max Seq and higher checksum but not MaxAge. Dropping it",
dump_lsa_key(lsa));
DISCARD_LSA(lsa, 4);
@@ -2238,9 +2263,6 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
return;
}
- /* Add event to thread. */
- OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_PacketReceived);
-
if (nbr->state < NSM_Exchange) {
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
zlog_debug(
@@ -2271,8 +2293,10 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
lsr = ospf_ls_retransmit_lookup(nbr, lsa);
- if (lsr != NULL && ospf_lsa_more_recent(lsr, lsa) == 0)
+ if (lsr != NULL && ospf_lsa_more_recent(lsr, lsa) == 0) {
ospf_ls_retransmit_delete(nbr, lsr);
+ ospf_check_and_gen_init_seq_lsa(oi, lsa);
+ }
lsa->data = NULL;
ospf_lsa_discard(lsa);
@@ -3871,9 +3895,8 @@ void ospf_db_desc_send(struct ospf_neighbor *nbr)
if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
zlog_info(
"%s:Packet[DD]: %pI4 DB Desc send with seqnum:%x , flags:%x",
- (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
- &nbr->router_id, nbr->dd_seqnum,
- nbr->dd_flags);
+ ospf_get_name(oi->ospf), &nbr->router_id,
+ nbr->dd_seqnum, nbr->dd_flags);
}
/* Re-send Database Description. */
@@ -3891,9 +3914,8 @@ void ospf_db_desc_resend(struct ospf_neighbor *nbr)
if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
zlog_info(
"%s:Packet[DD]: %pI4 DB Desc resend with seqnum:%x , flags:%x",
- (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
- &nbr->router_id, nbr->dd_seqnum,
- nbr->dd_flags);
+ ospf_get_name(oi->ospf), &nbr->router_id,
+ nbr->dd_seqnum, nbr->dd_flags);
}
/* Send Link State Request. */