2 * Copyright (C) 1999 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
25 nbs_full_change (struct ospf6_interface
*ospf6_interface
)
27 CALL_FOREACH_LSA_HOOK (hook_interface
, hook_change
, ospf6_interface
);
32 nbs_change (state_t nbs_next
, char *reason
, struct ospf6_neighbor
*o6n
)
36 nbs_previous
= o6n
->state
;
37 o6n
->state
= nbs_next
;
39 if (nbs_previous
== nbs_next
)
43 o6n
->ospf6_stat_state_changed
++;
44 gettimeofday (&o6n
->last_changed
, NULL
);
47 if (IS_OSPF6_DUMP_NEIGHBOR
)
50 zlog_info ("Neighbor status change %s: [%s]->[%s](%s)",
52 ospf6_neighbor_state_string
[nbs_previous
],
53 ospf6_neighbor_state_string
[nbs_next
],
56 zlog_info ("Neighbor status change %s: [%s]->[%s]",
58 ospf6_neighbor_state_string
[nbs_previous
],
59 ospf6_neighbor_state_string
[nbs_next
]);
62 if (nbs_previous
== NBS_FULL
|| nbs_next
== NBS_FULL
)
63 nbs_full_change (o6n
->ospf6_interface
);
65 /* check for LSAs that already reached MaxAge */
66 if ((nbs_previous
== NBS_EXCHANGE
|| nbs_previous
== NBS_LOADING
) &&
67 (nbs_next
!= NBS_EXCHANGE
&& nbs_next
!= NBS_LOADING
))
69 ospf6_maxage_remover ();
72 CALL_CHANGE_HOOK (&neighbor_hook
, o6n
);
77 /* RFC2328 section 10.4 */
79 need_adjacency (struct ospf6_neighbor
*o6n
)
82 if (o6n
->ospf6_interface
->state
== IFS_PTOP
)
84 if (o6n
->ospf6_interface
->state
== IFS_DR
)
86 if (o6n
->ospf6_interface
->state
== IFS_BDR
)
88 if (o6n
->router_id
== o6n
->ospf6_interface
->dr
)
90 if (o6n
->router_id
== o6n
->ospf6_interface
->bdr
)
97 hello_received (struct thread
*thread
)
99 struct ospf6_neighbor
*o6n
;
101 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
104 if (IS_OSPF6_DUMP_NEIGHBOR
)
105 zlog_info ("Neighbor Event %s: *HelloReceived*", o6n
->str
);
107 if (o6n
->inactivity_timer
)
108 thread_cancel (o6n
->inactivity_timer
);
110 o6n
->inactivity_timer
= thread_add_timer (master
, inactivity_timer
, o6n
,
111 o6n
->ospf6_interface
->dead_interval
);
112 if (o6n
->state
<= NBS_DOWN
)
113 nbs_change (NBS_INIT
, "HelloReceived", o6n
);
118 twoway_received (struct thread
*thread
)
120 struct ospf6_neighbor
*o6n
;
122 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
125 if (o6n
->state
> NBS_INIT
)
128 if (IS_OSPF6_DUMP_NEIGHBOR
)
129 zlog_info ("Neighbor Event %s: *2Way-Received*", o6n
->str
);
131 thread_add_event (master
, neighbor_change
, o6n
->ospf6_interface
, 0);
133 if (!need_adjacency (o6n
))
135 nbs_change (NBS_TWOWAY
, "No Need Adjacency", o6n
);
139 nbs_change (NBS_EXSTART
, "Need Adjacency", o6n
);
141 DD_MSBIT_SET (o6n
->dbdesc_bits
);
142 DD_MBIT_SET (o6n
->dbdesc_bits
);
143 DD_IBIT_SET (o6n
->dbdesc_bits
);
145 if (o6n
->thread_send_dbdesc
)
146 thread_cancel (o6n
->thread_send_dbdesc
);
147 o6n
->thread_send_dbdesc
=
148 thread_add_event (master
, ospf6_send_dbdesc
, o6n
, 0);
149 if (o6n
->thread_rxmt_dbdesc
)
150 thread_cancel (o6n
->thread_rxmt_dbdesc
);
151 o6n
->thread_rxmt_dbdesc
= (struct thread
*) NULL
;
157 negotiation_done (struct thread
*thread
)
159 struct ospf6_neighbor
*o6n
;
161 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
164 if (o6n
->state
!= NBS_EXSTART
)
167 if (IS_OSPF6_DUMP_NEIGHBOR
)
168 zlog_info ("Neighbor Event %s: *NegotiationDone*", o6n
->str
);
170 nbs_change (NBS_EXCHANGE
, "NegotiationDone", o6n
);
171 DD_IBIT_CLEAR (o6n
->dbdesc_bits
);
177 exchange_done (struct thread
*thread
)
179 struct ospf6_neighbor
*o6n
;
181 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
184 if (o6n
->state
!= NBS_EXCHANGE
)
187 if (o6n
->thread_rxmt_dbdesc
)
188 thread_cancel (o6n
->thread_rxmt_dbdesc
);
189 o6n
->thread_rxmt_dbdesc
= (struct thread
*) NULL
;
191 if (IS_OSPF6_DUMP_NEIGHBOR
)
192 zlog_info ("Neighbor Event %s: *ExchangeDone*", o6n
->str
);
194 ospf6_lsdb_remove_all (o6n
->dbdesc_list
);
196 thread_add_timer (master
, ospf6_neighbor_last_dbdesc_release
, o6n
,
197 o6n
->ospf6_interface
->dead_interval
);
199 if (o6n
->request_list
->count
== 0)
200 nbs_change (NBS_FULL
, "Requestlist Empty", o6n
);
203 thread_add_event (master
, ospf6_send_lsreq
, o6n
, 0);
204 nbs_change (NBS_LOADING
, "Requestlist Not Empty", o6n
);
210 loading_done (struct thread
*thread
)
212 struct ospf6_neighbor
*o6n
;
214 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
217 if (o6n
->state
!= NBS_LOADING
)
220 if (IS_OSPF6_DUMP_NEIGHBOR
)
221 zlog_info ("Neighbor Event %s: *LoadingDone*", o6n
->str
);
223 assert (o6n
->request_list
->count
== 0);
225 nbs_change (NBS_FULL
, "LoadingDone", o6n
);
231 adj_ok (struct thread
*thread
)
233 struct ospf6_neighbor
*o6n
;
235 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
238 if (IS_OSPF6_DUMP_NEIGHBOR
)
239 zlog_info ("Neighbor Event %s: *AdjOK?*", o6n
->str
);
241 if (o6n
->state
== NBS_TWOWAY
)
243 if (!need_adjacency (o6n
))
245 nbs_change (NBS_TWOWAY
, "No Need Adjacency", o6n
);
249 nbs_change (NBS_EXSTART
, "Need Adjacency", o6n
);
251 DD_MSBIT_SET (o6n
->dbdesc_bits
);
252 DD_MBIT_SET (o6n
->dbdesc_bits
);
253 DD_IBIT_SET (o6n
->dbdesc_bits
);
255 if (o6n
->thread_send_dbdesc
)
256 thread_cancel (o6n
->thread_send_dbdesc
);
257 o6n
->thread_send_dbdesc
=
258 thread_add_event (master
, ospf6_send_dbdesc
, o6n
, 0);
263 if (o6n
->state
>= NBS_EXSTART
)
265 if (need_adjacency (o6n
))
269 nbs_change (NBS_TWOWAY
, "No Need Adjacency", o6n
);
270 ospf6_neighbor_lslist_clear (o6n
);
277 seqnumber_mismatch (struct thread
*thread
)
279 struct ospf6_neighbor
*o6n
;
281 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
284 if (o6n
->state
< NBS_EXCHANGE
)
288 o6n
->ospf6_stat_seqnum_mismatch
++;
290 if (IS_OSPF6_DUMP_NEIGHBOR
)
291 zlog_info ("Neighbor Event %s: *SeqNumberMismatch*", o6n
->str
);
293 nbs_change (NBS_EXSTART
, "SeqNumberMismatch", o6n
);
295 DD_MSBIT_SET (o6n
->dbdesc_bits
);
296 DD_MBIT_SET (o6n
->dbdesc_bits
);
297 DD_IBIT_SET (o6n
->dbdesc_bits
);
298 ospf6_neighbor_lslist_clear (o6n
);
300 if (o6n
->thread_send_dbdesc
)
301 thread_cancel (o6n
->thread_send_dbdesc
);
302 o6n
->thread_send_dbdesc
=
303 thread_add_event (master
, ospf6_send_dbdesc
, o6n
, 0);
309 bad_lsreq (struct thread
*thread
)
311 struct ospf6_neighbor
*o6n
;
313 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
316 if (o6n
->state
< NBS_EXCHANGE
)
320 o6n
->ospf6_stat_bad_lsreq
++;
322 if (IS_OSPF6_DUMP_NEIGHBOR
)
323 zlog_info ("Neighbor Event %s: *BadLSReq*", o6n
->str
);
325 nbs_change (NBS_EXSTART
, "BadLSReq", o6n
);
327 DD_MSBIT_SET (o6n
->dbdesc_bits
);
328 DD_MBIT_SET (o6n
->dbdesc_bits
);
329 DD_IBIT_SET (o6n
->dbdesc_bits
);
330 ospf6_neighbor_lslist_clear (o6n
);
332 if (o6n
->thread_send_dbdesc
)
333 thread_cancel (o6n
->thread_send_dbdesc
);
334 o6n
->thread_send_dbdesc
=
335 thread_add_event (master
, ospf6_send_dbdesc
, o6n
, 0);
341 oneway_received (struct thread
*thread
)
343 struct ospf6_neighbor
*o6n
;
345 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
348 if (o6n
->state
< NBS_TWOWAY
)
352 o6n
->ospf6_stat_oneway_received
++;
354 if (IS_OSPF6_DUMP_NEIGHBOR
)
355 zlog_info ("Neighbor Event %s: *1Way-Received*", o6n
->str
);
357 nbs_change (NBS_INIT
, "1Way-Received", o6n
);
359 thread_add_event (master
, neighbor_change
, o6n
->ospf6_interface
, 0);
361 ospf6_neighbor_thread_cancel_all (o6n
);
362 ospf6_neighbor_lslist_clear (o6n
);
367 inactivity_timer (struct thread
*thread
)
369 struct ospf6_neighbor
*o6n
;
371 o6n
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
375 o6n
->ospf6_stat_inactivity_timer
++;
377 if (IS_OSPF6_DUMP_NEIGHBOR
)
378 zlog_info ("Neighbor Event %s: *InactivityTimer*", o6n
->str
);
380 o6n
->inactivity_timer
= NULL
;
381 o6n
->dr
= o6n
->bdr
= o6n
->prevdr
= o6n
->prevbdr
= 0;
382 nbs_change (NBS_DOWN
, "InactivityTimer", o6n
);
384 thread_add_event (master
, neighbor_change
, o6n
->ospf6_interface
, 0);
386 listnode_delete (o6n
->ospf6_interface
->neighbor_list
, o6n
);
387 ospf6_neighbor_delete (o6n
);