📄 ospf6_neighbor.c
字号:
/* * Copyright (C) 2003 Yasuhiro Ohara * * This file is part of GNU Zebra. * * GNU Zebra 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, or (at your option) any * later version. * * GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <zebra.h>#include "log.h"#include "memory.h"#include "thread.h"#include "linklist.h"#include "vty.h"#include "command.h"#include "ospf6_proto.h"#include "ospf6_lsa.h"#include "ospf6_lsdb.h"#include "ospf6_message.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"#include "ospf6_neighbor.h"#include "ospf6_intra.h"#include "ospf6_flood.h"#include "ospf6d.h"unsigned char conf_debug_ospf6_neighbor = 0;char *ospf6_neighbor_state_str[] ={ "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange", "Loading", "Full", NULL };intospf6_neighbor_cmp (void *va, void *vb){ struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va; struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb; return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);}struct ospf6_neighbor *ospf6_neighbor_lookup (u_int32_t router_id, struct ospf6_interface *oi){ listnode n; struct ospf6_neighbor *on; for (n = listhead (oi->neighbor_list); n; nextnode (n)) { on = (struct ospf6_neighbor *) getdata (n); if (on->router_id == router_id) return on; } return (struct ospf6_neighbor *) NULL;}/* create ospf6_neighbor */struct ospf6_neighbor *ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi){ struct ospf6_neighbor *on; char buf[16]; on = (struct ospf6_neighbor *) XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor)); if (on == NULL) { zlog_warn ("neighbor: malloc failed"); return NULL; } memset (on, 0, sizeof (struct ospf6_neighbor)); inet_ntop (AF_INET, &router_id, buf, sizeof (buf)); snprintf (on->name, sizeof (on->name), "%s%%%s", buf, oi->interface->name); on->ospf6_if = oi; on->state = OSPF6_NEIGHBOR_DOWN; gettimeofday (&on->last_changed, (struct timezone *) NULL); on->router_id = router_id; on->summary_list = ospf6_lsdb_create (on); on->request_list = ospf6_lsdb_create (on); on->retrans_list = ospf6_lsdb_create (on); on->dbdesc_list = ospf6_lsdb_create (on); on->lsreq_list = ospf6_lsdb_create (on); on->lsupdate_list = ospf6_lsdb_create (on); on->lsack_list = ospf6_lsdb_create (on); listnode_add_sort (oi->neighbor_list, on); return on;}voidospf6_neighbor_delete (struct ospf6_neighbor *on){ struct ospf6_lsa *lsa; ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list); for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; lsa = ospf6_lsdb_next (lsa)) { ospf6_decrement_retrans_count (lsa); ospf6_lsdb_remove (lsa, on->retrans_list); } ospf6_lsdb_remove_all (on->dbdesc_list); ospf6_lsdb_remove_all (on->lsreq_list); ospf6_lsdb_remove_all (on->lsupdate_list); ospf6_lsdb_remove_all (on->lsack_list); ospf6_lsdb_delete (on->summary_list); ospf6_lsdb_delete (on->request_list); ospf6_lsdb_delete (on->retrans_list); ospf6_lsdb_delete (on->dbdesc_list); ospf6_lsdb_delete (on->lsreq_list); ospf6_lsdb_delete (on->lsupdate_list); ospf6_lsdb_delete (on->lsack_list); THREAD_OFF (on->inactivity_timer); THREAD_OFF (on->thread_send_dbdesc); THREAD_OFF (on->thread_send_lsreq); THREAD_OFF (on->thread_send_lsupdate); THREAD_OFF (on->thread_send_lsack); XFREE (MTYPE_OSPF6_NEIGHBOR, on);}static voidospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on){ u_char prev_state; prev_state = on->state; on->state = next_state; if (prev_state == next_state) return; gettimeofday (&on->last_changed, (struct timezone *) NULL); /* log */ if (IS_OSPF6_DEBUG_NEIGHBOR (STATE)) { zlog_info ("Neighbor state change %s: [%s]->[%s]", on->name, ospf6_neighbor_state_str[prev_state], ospf6_neighbor_state_str[next_state]); } if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL) { OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area); if (on->ospf6_if->state == OSPF6_INTERFACE_DR) { OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if); } OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area); }#ifdef XXX if (prev_state == NBS_FULL || next_state == NBS_FULL) nbs_full_change (on->ospf6_interface); /* check for LSAs that already reached MaxAge */ if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE || prev_state == OSPF6_NEIGHBOR_LOADING) && (next_state != OSPF6_NEIGHBOR_EXCHANGE && next_state != OSPF6_NEIGHBOR_LOADING)) { ospf6_maxage_remover (); }#endif /*XXX*/}/* RFC2328 section 10.4 */intneed_adjacency (struct ospf6_neighbor *on){ if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT || on->ospf6_if->state == OSPF6_INTERFACE_DR || on->ospf6_if->state == OSPF6_INTERFACE_BDR) return 1; if (on->ospf6_if->drouter == on->router_id || on->ospf6_if->bdrouter == on->router_id) return 1; return 0;}inthello_received (struct thread *thread){ struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *HelloReceived*", on->name); /* reset Inactivity Timer */ THREAD_OFF (on->inactivity_timer); on->inactivity_timer = thread_add_timer (master, inactivity_timer, on, on->ospf6_if->dead_interval); if (on->state <= OSPF6_NEIGHBOR_DOWN) ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on); return 0;}inttwoway_received (struct thread *thread){ struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state > OSPF6_NEIGHBOR_INIT) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *2Way-Received*", on->name); thread_add_event (master, neighbor_change, on->ospf6_if, 0); if (! need_adjacency (on)) { ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on); return 0; } ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); return 0;}intnegotiation_done (struct thread *thread){ struct ospf6_neighbor *on; struct ospf6_lsa *lsa; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state != OSPF6_NEIGHBOR_EXSTART) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *NegotiationDone*", on->name); /* clear ls-list */ ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list); for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; lsa = ospf6_lsdb_next (lsa)) { ospf6_decrement_retrans_count (lsa); ospf6_lsdb_remove (lsa, on->retrans_list); } /* Interface scoped LSAs */ for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) { if (OSPF6_LSA_IS_MAXAGE (lsa)) { ospf6_increment_retrans_count (lsa); ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); } else ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); } /* Area scoped LSAs */ for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) { if (OSPF6_LSA_IS_MAXAGE (lsa)) { ospf6_increment_retrans_count (lsa); ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); } else ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); } /* AS scoped LSAs */ for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) { if (OSPF6_LSA_IS_MAXAGE (lsa)) { ospf6_increment_retrans_count (lsa); ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list); } else ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list); } UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on); return 0;}intexchange_done (struct thread *thread){ struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state != OSPF6_NEIGHBOR_EXCHANGE) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *ExchangeDone*", on->name); THREAD_OFF (on->thread_send_dbdesc); ospf6_lsdb_remove_all (on->dbdesc_list);/* XXX thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on, on->ospf6_if->dead_interval);*/ if (on->request_list->count == 0) ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on); else ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on); return 0;}intloading_done (struct thread *thread){ struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state != OSPF6_NEIGHBOR_LOADING) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *LoadingDone*", on->name); assert (on->request_list->count == 0); ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on); return 0;}intadj_ok (struct thread *thread){ struct ospf6_neighbor *on; struct ospf6_lsa *lsa; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *AdjOK?*", on->name); if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on)) { ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && ! need_adjacency (on)) { ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on); ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list); for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; lsa = ospf6_lsdb_next (lsa)) { ospf6_decrement_retrans_count (lsa); ospf6_lsdb_remove (lsa, on->retrans_list); } } return 0;}intseqnumber_mismatch (struct thread *thread){ struct ospf6_neighbor *on; struct ospf6_lsa *lsa; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state < OSPF6_NEIGHBOR_EXCHANGE) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", on->name); ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list); for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; lsa = ospf6_lsdb_next (lsa)) { ospf6_decrement_retrans_count (lsa); ospf6_lsdb_remove (lsa, on->retrans_list); } THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); return 0;}intbad_lsreq (struct thread *thread){ struct ospf6_neighbor *on; struct ospf6_lsa *lsa; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state < OSPF6_NEIGHBOR_EXCHANGE) return 0; if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *BadLSReq*", on->name); ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -