📄 patch2.4
字号:
hdr->ls_opts |= SPO_DC;@@ -131,6 +131,7 @@ summ->metric = hton32(cost); (void) ospf->lsa_reorig(0, this, olsap, hdr, forced);+ ospf->free_orig_buffer(hdr); } /* Figure out whether we should be injecting an indication-LSAdiff -X exclude_files -Nabur ospfd2.3/src/asexlsa.C ospfd2.4/src/asexlsa.C--- ospfd2.3/src/asexlsa.C Mon May 21 10:19:27 2001+++ ospfd2.4/src/asexlsa.C Thu Sep 13 16:05:43 2001@@ -342,7 +342,7 @@ lsa_flush(olsap); return; }- if ((seqno = ospf->ospf_get_seqno(olsap, length, forced))+ if ((seqno = ospf->ospf_get_seqno(LST_ASL, olsap, forced)) == InvalidLSSeq) return; @@ -350,7 +350,7 @@ rte->ase_orig = true; // Fill in LSA contents // Header- hdr = ospf->orig_buffer();+ hdr = ospf->orig_buffer(length); hdr->ls_opts = SPO_DC | SPO_EXT; if (exdata->mc) hdr->ls_opts |= SPO_MC;@@ -369,6 +369,7 @@ ase->rtag = hton32(exdata->tag); nlsap = (ASextLSA *) ospf->lsa_reorig(0, 0, olsap, hdr, forced);+ ospf->free_orig_buffer(hdr); if (nlsap) nlsap->orig_rte = rte; @@ -418,6 +419,10 @@ void ASextLSA::reoriginate(int forced) {+ if (!orig_rte) {+ lsa_flush(this);+ return;+ } ospf->ase_orig(orig_rte, forced); } @@ -640,7 +645,8 @@ if (intra_AS() && r_mpath == 0) declare_unreachable(); // If the ASBR has changed, redo type-4 summary-LSAs- if (state_changed() || otype != r_type || oa != area()) {+ if (state_changed() || otype != r_type || oa != area() ||+ ospf->exiting_htl_restart) { ospf->ase_sched = true; ospf->asbr_orig(this); }@@ -905,7 +911,8 @@ new_type != r_type || best_cost != cost || best_t2cost != t2cost ||- best_tag != tag) {+ best_tag != tag ||+ ospf->exiting_htl_restart) { update(best_path); r_type = new_type; cost = best_cost;diff -X exclude_files -Nabur ospfd2.3/src/dbage.C ospfd2.4/src/dbage.C--- ospfd2.3/src/dbage.C Mon May 21 10:19:27 2001+++ ospfd2.4/src/dbage.C Thu Sep 13 16:05:43 2001@@ -106,6 +106,9 @@ // Age the link-state database ospf->dbage();+ // Exit helper mode?+ if (ospf->topology_change)+ ospf->htl_topology_change(); // Delete down neighbors ospf->delete_down_neighbors(); // Establish more adjacencies?@@ -131,10 +134,18 @@ // Synchronize with kernel ospf->krt_sync(); - // If not performing a hitless restart, upload remnants+ // Upload remnants of routing table installed by previous instances if (ospf->need_remnants) { ospf->need_remnants = false; sys->upload_remnants();+ }++ // Perform hitless restart processing+ if (ospf->in_hitless_restart()) {+ if (ospf->check_htl_termination)+ ospf->htl_exit_criteria();+ if (ospf->start_htl_exit)+ ospf->exit_hitless_restart(ospf->htl_exit_reason); } } diff -X exclude_files -Nabur ospfd2.3/src/grplsa.C ospfd2.4/src/grplsa.C--- ospfd2.3/src/grplsa.C Mon May 21 10:19:27 2001+++ ospfd2.4/src/grplsa.C Thu Sep 13 16:05:43 2001@@ -118,11 +118,11 @@ while ((entry = iter.next()) && entry->index1() == group) maxlen += sizeof(GMref); // Get LS Sequence Number- seqno = ospf->ospf_get_seqno(olsap, maxlen, forced);+ seqno = ospf->ospf_get_seqno(LST_GM, olsap, forced); if (seqno == InvalidLSSeq) return; // Fill in LSA header- hdr = ospf->orig_buffer();+ hdr = ospf->orig_buffer(maxlen); hdr->ls_opts = SPO_DC | SPO_MC; if (!a_stub) hdr->ls_opts |= SPO_EXT;@@ -196,6 +196,7 @@ hdr->ls_length = hton16(length); (void) ospf->lsa_reorig(0, this, olsap, hdr, forced); }+ ospf->free_orig_buffer(hdr); } /* The state of an interface has changed, requiring usdiff -X exclude_files -Nabur ospfd2.3/src/helper.C ospfd2.4/src/helper.C--- ospfd2.3/src/helper.C Wed Dec 31 19:00:00 1969+++ ospfd2.4/src/helper.C Thu Sep 13 16:05:44 2001@@ -0,0 +1,285 @@+/*+ * OSPFD routing daemon+ * Copyright (C) 2001 by John T. Moy+ * + * This program 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+ * of the License, or (at your option) any later version.+ * + * This program 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; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+ */++#include "ospfinc.h"+#include "monitor.h"+#include "system.h"+#include "ifcfsm.h"+#include "nbrfsm.h"+#include "phyint.h"+#include "opqlsa.h"++/* This file contains the routines implementing+ * helper mode for hitless restart.+ */++/* If we are in helper mode, we should be advertising+ * the neighbor as fully adjacent, even if it isn't.+ */++bool SpfNbr::adv_as_full()++{+ if (n_state == NBS_FULL)+ return(true);+ if (n_helptim.is_running())+ return(true);+ return(false);+}++/* If we are helping a neighbor perform a hitless restart,+ * its timer should be running.+ */++bool SpfNbr::we_are_helping()++{+ return(n_helptim.is_running());+}++/* If the helper timer expires, we exit helper mode with+ * a reason of "timeout".+ */++void HelperTimer::action()++{+ np->exit_helper_mode("Timeout");+}++/* We have received a grace-LSA from a neighbor. If after+ * parsing the grace-LSA a) the link-state database has not+ * changed (aside from refreshes) since the beginning+ * of the requested refresh period and b) the refresh period has not+ * expired, then we enter helper mode for the neighbor by+ * setting the helper timer.+ */++void OSPF::grace_LSA_rx(opqLSA *lsap, LShdr *hdr)++{+ SpfNbr *np;+ SPFtime grace_start;+ int grace_period;+ SPFtime grace_end;+ char *refusal = 0;++ // Ignore our own+ if (lsap->adv_rtr() == myid)+ return;+ if (!(np = lsap->grace_lsa_parse((byte *)(hdr+1),+ ntoh16(hdr->ls_length)-sizeof(LShdr),+ grace_start, grace_period)))+ return;++ // Have associated grace-LSA with a neighbor+ if (spflog(LOG_GRACERX, 5))+ log(np);++ // Now determine whether we should accept it+ time_add(grace_start, grace_period*Timer::SECOND, &grace_end);+ // Neighbor must be in Full state+ if (np->n_state != NBS_FULL)+ refusal = "Not full";+ // No topology changes since grace period start+ else if (time_less(grace_start, last_topology_change))+ refusal = "Topology change";+ // Grace period already expired?+ else if (time_less(grace_end, sys_etime))+ refusal = "Timeout";++ /* If we are refusing the grace request, either exit+ * helper mode if we are already helping, or just+ * log the error.+ */+ if (refusal != 0 && !np->we_are_helping()) {+ if (spflog(LOG_GRACE_REJECT, 5)) {+ log(np);+ log(":");+ log(refusal);+ }+ }+ else if (refusal != 0)+ np->exit_helper_mode(refusal);+ else {+ // (Re)enter helper mode+ if (spflog(LOG_HELPER_START, 5))+ log(np);+ if (np->we_are_helping()) {+ np->n_helptim.stop();+ np->n_ifp->if_helping--;+ n_helping--;+ }+ np->n_helptim.start(grace_period*Timer::SECOND, false);+ np->n_ifp->if_helping++;+ n_helping++;+ }+}++/* When a grace-LSA is flushed, we exit helper mode.+ * This is considered to be the successful completion+ * of a hitless restart.+ */++void OSPF::grace_LSA_flushed(class opqLSA *lsap)++{+ SpfNbr *np;+ SPFtime grace_start;+ int grace_period;++ // Ignore our own+ if (lsap->adv_rtr() == myid)+ return;+ if (!(np = lsap->grace_lsa_parse(lsap->lsa_body,+ lsap->lsa_length - sizeof(LShdr),+ grace_start, grace_period)))+ return;+ // Exit helper mode+ if (np->we_are_helping())+ np->exit_helper_mode("Success");+}++/* Parse the body of a grace-LSA, determing a) the start of the+ * requested grace period, b) the end, and c) the neighbor requesting+ * grace.+ */++SpfNbr *opqLSA::grace_lsa_parse(byte *body, int len, + SPFtime &g_start, int &g_period)++{+ TLVbuf buf(body, len);+ int type;+ InAddr nbr_addr = 0;+ int32 val;++ // Start of grace period determined by LS age+ if (sys_etime.sec < lsa_age()) {+ g_start.sec = 0;+ g_start.msec = 0;+ }+ else {+ g_start.sec = sys_etime.sec - lsa_age();+ g_start.msec = sys_etime.msec;+ }++ // Parse body of grace-LSA+ g_period = 0;+ while (buf.next_tlv(type)) {+ switch(type) {+ case HLRST_PERIOD: // Length of grace period+ if (!buf.get_int(g_period))+ return(0);+ break;+ case HLRST_REASON: // Reason for restart+ break;+ case HLRST_IFADDR: // Interface address+ if (!buf.get_int(val))+ return(0);+ nbr_addr = (InAddr) val;+ break;+ default:+ break;+ }+ };++ return(lsa_ifp->find_nbr(nbr_addr, adv_rtr()));+}++/* When exiting helper mode, we need to reoriginate+ * router-LSAs, network-LSAs, and rerun the Designated Router+ * calculation for the associated interface.+ * If the neighbor we were helping is DR, make sure it+ * stays DR until we receive its next Hello Packet.+ */++void SpfNbr::exit_helper_mode(char *reason, bool actions)++{+ if (ospf->spflog(LOG_HELPER_STOP, 5)) {+ ospf->log(this);+ ospf->log(":");+ ospf->log(reason);+ }+ n_helptim.stop();+ n_ifp->if_helping--;+ ospf->n_helping--;+ /* If neighbor is not yet full again, do the+ * processing that should have been done when the+ * neighjbor initially went out of FULL state,+ */+ if (n_state != NBS_FULL) {+ SpfArea *tap;+ tap = n_ifp->transit_area();+ if (n_ifp->if_nfull-- == 1)+ n_ifp->reorig_all_grplsas();+ if (tap && tap->n_VLs-- == 1 && actions)+ tap->rl_orig();+ }+ // Neighbor stays DR until next Hello+ else if (n_ifp->if_dr_p == this)+ n_dr = n_ifp->if_dr;+ // Caller may take actions itself+ if (actions) {+ // Recalculate Designated Router+ n_ifp->run_fsm(IFE_NCHG);+ // Re-originate router-LSA+ n_ifp->area()->rl_orig();+ // And network-LSA+ n_ifp->nl_orig(false);+ }+}++/* A topology change has occurred. Cancel all helping modes,+ * and reoriginate router-LSAs, network-LSAs and rerun+ * Designated Router calculations, as necessary.+ *+ * Also note the time, for use in verifying future+ * grace requests.+ */++void OSPF::htl_topology_change()++{+ // clear topolog change flag+ topology_change = false;+ // Update time of last topology change+ last_topology_change = sys_etime;+ // Cancel any helping sessions+ if (n_helping != 0) {+ IfcIterator iiter(this);+ SpfIfc *ip;+ while ((ip = iiter.get_next())) {+ NbrIterator niter(ip);+ SpfNbr *np;+ if (ip->if_helping == 0)+ continue;+ while ((np = niter.get_next()))+ if (np->we_are_helping())+ np->exit_helper_mode("Topology change", false);+ // Recalculate Designated Router+ ip->run_fsm(IFE_NCHG);+ // Reoriginate network-LSA+ ip->nl_orig(false);+ }+ // Re-originate all router-LSAs+ rl_orig();+ }+}diff -X exclude_files -Nabur ospfd2.3/src/ifcfsm.C ospfd2.4/src/ifcfsm.C--- ospfd2.3/src/ifcfsm.C Mon May 21 10:19:27 2001+++ ospfd2.4/src/ifcfsm.C Thu Sep 13 16:05:43 2001@@ -304,10 +304,15 @@ c_id = np->n_id; } + // If we are helping the current DR through hitless+ // restart, keep it as DR+ if (if_dr_p && if_dr_p->we_are_helping())+ break;+ // Initialize DR election iter.reset(); if_dr_p = 0;- if (if_dr == if_addr) {+ if (if_dr == if_addr && if_drpri != 0) { c_pri = if_drpri; c_id = ospf->my_id(); }@@ -362,7 +367,7 @@ if (if_dr != prev_dr || if_bdr != prev_bdr) { if (ospf->spflog(LOG_DRCH, 4)) { ospf->log(this);- ospf->log("DR ");+ ospf->log(" DR "); ospf->log(&if_dr); ospf->log(" Back "); ospf->log(&if_bdr);diff -X exclude_files -Nabur ospfd2.3/src/lsa.C ospfd2.4/src/lsa.C--- ospfd2.3/src/lsa.C Mon May 21 10:19:27 2001+++ ospfd2.4/src/lsa.C Thu Sep 13 16:05:43 2001@@ -57,6 +57,7 @@ sent_reply = false; checkage = false; min_failed = false;+ we_orig = false; // Fake LSAs aren't install in database if (blen) {@@ -198,20 +199,22 @@ * routine is not reentrant.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -