]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
508e53e2 | 2 | * Copyright (C) 2003 Yasuhiro Ohara |
718e3744 | 3 | * |
4 | * This file is part of GNU Zebra. | |
5 | * | |
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 | |
9 | * later version. | |
10 | * | |
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. | |
15 | * | |
896014f4 DL |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 19 | */ |
20 | ||
718e3744 | 21 | #include <zebra.h> |
22 | ||
23 | #include "log.h" | |
508e53e2 | 24 | #include "memory.h" |
718e3744 | 25 | #include "thread.h" |
26 | #include "linklist.h" | |
27 | #include "vty.h" | |
28 | #include "command.h" | |
29 | ||
508e53e2 | 30 | #include "ospf6_proto.h" |
718e3744 | 31 | #include "ospf6_lsa.h" |
508e53e2 | 32 | #include "ospf6_lsdb.h" |
718e3744 | 33 | #include "ospf6_message.h" |
508e53e2 | 34 | #include "ospf6_top.h" |
35 | #include "ospf6_area.h" | |
36 | #include "ospf6_interface.h" | |
718e3744 | 37 | #include "ospf6_neighbor.h" |
508e53e2 | 38 | #include "ospf6_intra.h" |
3b4cd3a9 | 39 | #include "ospf6_flood.h" |
049207c3 | 40 | #include "ospf6d.h" |
7f342629 | 41 | #include "ospf6_bfd.h" |
4dfd8aff DW |
42 | #include "ospf6_abr.h" |
43 | #include "ospf6_asbr.h" | |
44 | #include "ospf6_lsa.h" | |
45 | #include "ospf6_spf.h" | |
46 | #include "ospf6_zebra.h" | |
718e3744 | 47 | |
3012671f | 48 | DEFINE_HOOK(ospf6_neighbor_change, |
d62a17ae | 49 | (struct ospf6_neighbor * on, int state, int next_state), |
50 | (on, state, next_state)) | |
3012671f | 51 | |
508e53e2 | 52 | unsigned char conf_debug_ospf6_neighbor = 0; |
53 | ||
d62a17ae | 54 | const char *ospf6_neighbor_state_str[] = { |
55 | "None", "Down", "Attempt", "Init", "Twoway", | |
56 | "ExStart", "ExChange", "Loading", "Full", NULL}; | |
718e3744 | 57 | |
d62a17ae | 58 | int ospf6_neighbor_cmp(void *va, void *vb) |
718e3744 | 59 | { |
d62a17ae | 60 | struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va; |
61 | struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb; | |
62 | return (ntohl(ona->router_id) < ntohl(onb->router_id) ? -1 : 1); | |
718e3744 | 63 | } |
64 | ||
d62a17ae | 65 | struct ospf6_neighbor *ospf6_neighbor_lookup(u_int32_t router_id, |
66 | struct ospf6_interface *oi) | |
718e3744 | 67 | { |
d62a17ae | 68 | struct listnode *n; |
69 | struct ospf6_neighbor *on; | |
70 | ||
71 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on)) | |
72 | if (on->router_id == router_id) | |
73 | return on; | |
74 | ||
75 | return (struct ospf6_neighbor *)NULL; | |
718e3744 | 76 | } |
77 | ||
508e53e2 | 78 | /* create ospf6_neighbor */ |
d62a17ae | 79 | struct ospf6_neighbor *ospf6_neighbor_create(u_int32_t router_id, |
80 | struct ospf6_interface *oi) | |
718e3744 | 81 | { |
d62a17ae | 82 | struct ospf6_neighbor *on; |
83 | char buf[16]; | |
84 | ||
85 | on = (struct ospf6_neighbor *)XMALLOC(MTYPE_OSPF6_NEIGHBOR, | |
86 | sizeof(struct ospf6_neighbor)); | |
87 | if (on == NULL) { | |
88 | zlog_warn("neighbor: malloc failed"); | |
89 | return NULL; | |
90 | } | |
91 | ||
92 | memset(on, 0, sizeof(struct ospf6_neighbor)); | |
93 | inet_ntop(AF_INET, &router_id, buf, sizeof(buf)); | |
94 | snprintf(on->name, sizeof(on->name), "%s%%%s", buf, | |
95 | oi->interface->name); | |
96 | on->ospf6_if = oi; | |
97 | on->state = OSPF6_NEIGHBOR_DOWN; | |
98 | on->state_change = 0; | |
99 | monotime(&on->last_changed); | |
100 | on->router_id = router_id; | |
101 | ||
102 | on->summary_list = ospf6_lsdb_create(on); | |
103 | on->request_list = ospf6_lsdb_create(on); | |
104 | on->retrans_list = ospf6_lsdb_create(on); | |
105 | ||
106 | on->dbdesc_list = ospf6_lsdb_create(on); | |
107 | on->lsupdate_list = ospf6_lsdb_create(on); | |
108 | on->lsack_list = ospf6_lsdb_create(on); | |
109 | ||
110 | listnode_add_sort(oi->neighbor_list, on); | |
111 | ||
112 | ospf6_bfd_info_nbr_create(oi, on); | |
113 | return on; | |
718e3744 | 114 | } |
115 | ||
d62a17ae | 116 | void ospf6_neighbor_delete(struct ospf6_neighbor *on) |
718e3744 | 117 | { |
d62a17ae | 118 | struct ospf6_lsa *lsa; |
3b4cd3a9 | 119 | |
d62a17ae | 120 | ospf6_lsdb_remove_all(on->summary_list); |
121 | ospf6_lsdb_remove_all(on->request_list); | |
122 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
123 | ospf6_decrement_retrans_count(lsa); | |
124 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
125 | } | |
718e3744 | 126 | |
d62a17ae | 127 | ospf6_lsdb_remove_all(on->dbdesc_list); |
128 | ospf6_lsdb_remove_all(on->lsupdate_list); | |
129 | ospf6_lsdb_remove_all(on->lsack_list); | |
508e53e2 | 130 | |
d62a17ae | 131 | ospf6_lsdb_delete(on->summary_list); |
132 | ospf6_lsdb_delete(on->request_list); | |
133 | ospf6_lsdb_delete(on->retrans_list); | |
718e3744 | 134 | |
d62a17ae | 135 | ospf6_lsdb_delete(on->dbdesc_list); |
136 | ospf6_lsdb_delete(on->lsupdate_list); | |
137 | ospf6_lsdb_delete(on->lsack_list); | |
508e53e2 | 138 | |
d62a17ae | 139 | THREAD_OFF(on->inactivity_timer); |
508e53e2 | 140 | |
d62a17ae | 141 | THREAD_OFF(on->thread_send_dbdesc); |
142 | THREAD_OFF(on->thread_send_lsreq); | |
143 | THREAD_OFF(on->thread_send_lsupdate); | |
144 | THREAD_OFF(on->thread_send_lsack); | |
508e53e2 | 145 | |
d62a17ae | 146 | ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER); |
147 | XFREE(MTYPE_OSPF6_NEIGHBOR, on); | |
718e3744 | 148 | } |
149 | ||
d62a17ae | 150 | static void ospf6_neighbor_state_change(u_char next_state, |
151 | struct ospf6_neighbor *on, int event) | |
718e3744 | 152 | { |
d62a17ae | 153 | u_char prev_state; |
154 | ||
155 | prev_state = on->state; | |
156 | on->state = next_state; | |
157 | ||
158 | if (prev_state == next_state) | |
159 | return; | |
160 | ||
161 | on->state_change++; | |
162 | monotime(&on->last_changed); | |
163 | ||
164 | /* log */ | |
165 | if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) { | |
166 | zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)", | |
167 | on->name, ospf6_neighbor_state_str[prev_state], | |
168 | ospf6_neighbor_state_str[next_state], | |
169 | ospf6_neighbor_event_string(event)); | |
170 | } | |
171 | ||
172 | /* Optionally notify about adjacency changes */ | |
173 | if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, | |
174 | OSPF6_LOG_ADJACENCY_CHANGES) | |
175 | && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags, | |
176 | OSPF6_LOG_ADJACENCY_DETAIL) | |
177 | || (next_state == OSPF6_NEIGHBOR_FULL) | |
178 | || (next_state < prev_state))) | |
179 | zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name, | |
180 | ospf6_neighbor_state_str[prev_state], | |
181 | ospf6_neighbor_state_str[next_state], | |
182 | ospf6_neighbor_event_string(event)); | |
183 | ||
184 | if (prev_state == OSPF6_NEIGHBOR_FULL | |
185 | || next_state == OSPF6_NEIGHBOR_FULL) { | |
186 | OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area); | |
187 | if (on->ospf6_if->state == OSPF6_INTERFACE_DR) { | |
188 | OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if); | |
189 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if); | |
190 | } | |
191 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area); | |
192 | } | |
193 | ||
194 | if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE | |
195 | || prev_state == OSPF6_NEIGHBOR_LOADING) | |
196 | && (next_state != OSPF6_NEIGHBOR_EXCHANGE | |
197 | && next_state != OSPF6_NEIGHBOR_LOADING)) | |
198 | ospf6_maxage_remove(on->ospf6_if->area->ospf6); | |
199 | ||
200 | hook_call(ospf6_neighbor_change, on, next_state, prev_state); | |
201 | ospf6_bfd_trigger_event(on, prev_state, next_state); | |
718e3744 | 202 | } |
203 | ||
508e53e2 | 204 | /* RFC2328 section 10.4 */ |
d62a17ae | 205 | static int need_adjacency(struct ospf6_neighbor *on) |
718e3744 | 206 | { |
d62a17ae | 207 | if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT |
208 | || on->ospf6_if->state == OSPF6_INTERFACE_DR | |
209 | || on->ospf6_if->state == OSPF6_INTERFACE_BDR) | |
210 | return 1; | |
718e3744 | 211 | |
d62a17ae | 212 | if (on->ospf6_if->drouter == on->router_id |
213 | || on->ospf6_if->bdrouter == on->router_id) | |
214 | return 1; | |
508e53e2 | 215 | |
d62a17ae | 216 | return 0; |
718e3744 | 217 | } |
218 | ||
d62a17ae | 219 | int hello_received(struct thread *thread) |
718e3744 | 220 | { |
d62a17ae | 221 | struct ospf6_neighbor *on; |
718e3744 | 222 | |
d62a17ae | 223 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
224 | assert(on); | |
718e3744 | 225 | |
d62a17ae | 226 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
227 | zlog_debug("Neighbor Event %s: *HelloReceived*", on->name); | |
508e53e2 | 228 | |
d62a17ae | 229 | /* reset Inactivity Timer */ |
230 | THREAD_OFF(on->inactivity_timer); | |
231 | on->inactivity_timer = NULL; | |
232 | thread_add_timer(master, inactivity_timer, on, | |
233 | on->ospf6_if->dead_interval, &on->inactivity_timer); | |
508e53e2 | 234 | |
d62a17ae | 235 | if (on->state <= OSPF6_NEIGHBOR_DOWN) |
236 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, | |
237 | OSPF6_NEIGHBOR_EVENT_HELLO_RCVD); | |
508e53e2 | 238 | |
d62a17ae | 239 | return 0; |
718e3744 | 240 | } |
241 | ||
d62a17ae | 242 | int twoway_received(struct thread *thread) |
718e3744 | 243 | { |
d62a17ae | 244 | struct ospf6_neighbor *on; |
508e53e2 | 245 | |
d62a17ae | 246 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
247 | assert(on); | |
508e53e2 | 248 | |
d62a17ae | 249 | if (on->state > OSPF6_NEIGHBOR_INIT) |
250 | return 0; | |
508e53e2 | 251 | |
d62a17ae | 252 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
253 | zlog_debug("Neighbor Event %s: *2Way-Received*", on->name); | |
508e53e2 | 254 | |
d62a17ae | 255 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); |
508e53e2 | 256 | |
d62a17ae | 257 | if (!need_adjacency(on)) { |
258 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, | |
259 | OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); | |
260 | return 0; | |
261 | } | |
718e3744 | 262 | |
d62a17ae | 263 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
264 | OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD); | |
265 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
266 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
267 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
508e53e2 | 268 | |
d62a17ae | 269 | THREAD_OFF(on->thread_send_dbdesc); |
270 | on->thread_send_dbdesc = NULL; | |
271 | thread_add_event(master, ospf6_dbdesc_send, on, 0, | |
272 | &on->thread_send_dbdesc); | |
508e53e2 | 273 | |
d62a17ae | 274 | return 0; |
718e3744 | 275 | } |
276 | ||
d62a17ae | 277 | int negotiation_done(struct thread *thread) |
718e3744 | 278 | { |
d62a17ae | 279 | struct ospf6_neighbor *on; |
280 | struct ospf6_lsa *lsa; | |
281 | ||
282 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); | |
283 | assert(on); | |
284 | ||
285 | if (on->state != OSPF6_NEIGHBOR_EXSTART) | |
286 | return 0; | |
287 | ||
288 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
289 | zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name); | |
290 | ||
291 | /* clear ls-list */ | |
292 | ospf6_lsdb_remove_all(on->summary_list); | |
293 | ospf6_lsdb_remove_all(on->request_list); | |
294 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
295 | ospf6_decrement_retrans_count(lsa); | |
296 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
297 | } | |
298 | ||
299 | /* Interface scoped LSAs */ | |
300 | for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) { | |
301 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { | |
302 | ospf6_increment_retrans_count(lsa); | |
303 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
304 | } else | |
305 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
306 | } | |
307 | ||
308 | /* Area scoped LSAs */ | |
309 | for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) { | |
310 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { | |
311 | ospf6_increment_retrans_count(lsa); | |
312 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
313 | } else | |
314 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
315 | } | |
316 | ||
317 | /* AS scoped LSAs */ | |
318 | for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) { | |
319 | if (OSPF6_LSA_IS_MAXAGE(lsa)) { | |
320 | ospf6_increment_retrans_count(lsa); | |
321 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); | |
322 | } else | |
323 | ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list); | |
324 | } | |
325 | ||
326 | UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
327 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on, | |
328 | OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE); | |
329 | ||
330 | return 0; | |
718e3744 | 331 | } |
332 | ||
d62a17ae | 333 | int exchange_done(struct thread *thread) |
718e3744 | 334 | { |
d62a17ae | 335 | struct ospf6_neighbor *on; |
718e3744 | 336 | |
d62a17ae | 337 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
338 | assert(on); | |
508e53e2 | 339 | |
d62a17ae | 340 | if (on->state != OSPF6_NEIGHBOR_EXCHANGE) |
341 | return 0; | |
508e53e2 | 342 | |
d62a17ae | 343 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
344 | zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name); | |
508e53e2 | 345 | |
d62a17ae | 346 | THREAD_OFF(on->thread_send_dbdesc); |
347 | ospf6_lsdb_remove_all(on->dbdesc_list); | |
508e53e2 | 348 | |
d62a17ae | 349 | /* XXX |
350 | thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on, | |
351 | on->ospf6_if->dead_interval); | |
352 | */ | |
508e53e2 | 353 | |
d62a17ae | 354 | if (on->request_list->count == 0) |
355 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, | |
356 | OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); | |
357 | else { | |
358 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on, | |
359 | OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE); | |
eb82e9ee | 360 | |
d62a17ae | 361 | thread_add_event(master, ospf6_lsreq_send, on, 0, |
362 | &on->thread_send_lsreq); | |
363 | } | |
508e53e2 | 364 | |
d62a17ae | 365 | return 0; |
508e53e2 | 366 | } |
367 | ||
eb82e9ee | 368 | /* Check loading state. */ |
d62a17ae | 369 | void ospf6_check_nbr_loading(struct ospf6_neighbor *on) |
eb82e9ee DD |
370 | { |
371 | ||
d62a17ae | 372 | /* RFC2328 Section 10.9: When the neighbor responds to these requests |
373 | with the proper Link State Update packet(s), the Link state request | |
374 | list is truncated and a new Link State Request packet is sent. | |
375 | */ | |
376 | if ((on->state == OSPF6_NEIGHBOR_LOADING) | |
377 | || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) { | |
378 | if (on->request_list->count == 0) | |
379 | thread_add_event(master, loading_done, on, 0, NULL); | |
380 | else if (on->last_ls_req == NULL) { | |
381 | if (on->thread_send_lsreq != NULL) | |
382 | THREAD_OFF(on->thread_send_lsreq); | |
383 | on->thread_send_lsreq = NULL; | |
384 | thread_add_event(master, ospf6_lsreq_send, on, 0, | |
385 | &on->thread_send_lsreq); | |
386 | } | |
eb82e9ee | 387 | } |
eb82e9ee DD |
388 | } |
389 | ||
d62a17ae | 390 | int loading_done(struct thread *thread) |
508e53e2 | 391 | { |
d62a17ae | 392 | struct ospf6_neighbor *on; |
508e53e2 | 393 | |
d62a17ae | 394 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
395 | assert(on); | |
508e53e2 | 396 | |
d62a17ae | 397 | if (on->state != OSPF6_NEIGHBOR_LOADING) |
398 | return 0; | |
508e53e2 | 399 | |
d62a17ae | 400 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
401 | zlog_debug("Neighbor Event %s: *LoadingDone*", on->name); | |
508e53e2 | 402 | |
d62a17ae | 403 | assert(on->request_list->count == 0); |
508e53e2 | 404 | |
d62a17ae | 405 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on, |
406 | OSPF6_NEIGHBOR_EVENT_LOADING_DONE); | |
508e53e2 | 407 | |
d62a17ae | 408 | return 0; |
508e53e2 | 409 | } |
410 | ||
d62a17ae | 411 | int adj_ok(struct thread *thread) |
508e53e2 | 412 | { |
d62a17ae | 413 | struct ospf6_neighbor *on; |
414 | struct ospf6_lsa *lsa; | |
415 | ||
416 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); | |
417 | assert(on); | |
418 | ||
419 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
420 | zlog_debug("Neighbor Event %s: *AdjOK?*", on->name); | |
421 | ||
422 | if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) { | |
423 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, | |
424 | OSPF6_NEIGHBOR_EVENT_ADJ_OK); | |
425 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
426 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
427 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
428 | ||
429 | THREAD_OFF(on->thread_send_dbdesc); | |
430 | on->thread_send_dbdesc = NULL; | |
431 | thread_add_event(master, ospf6_dbdesc_send, on, 0, | |
432 | &on->thread_send_dbdesc); | |
433 | ||
434 | } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) { | |
435 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on, | |
436 | OSPF6_NEIGHBOR_EVENT_ADJ_OK); | |
437 | ospf6_lsdb_remove_all(on->summary_list); | |
438 | ospf6_lsdb_remove_all(on->request_list); | |
439 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
440 | ospf6_decrement_retrans_count(lsa); | |
441 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
442 | } | |
443 | } | |
444 | ||
445 | return 0; | |
508e53e2 | 446 | } |
718e3744 | 447 | |
d62a17ae | 448 | int seqnumber_mismatch(struct thread *thread) |
508e53e2 | 449 | { |
d62a17ae | 450 | struct ospf6_neighbor *on; |
451 | struct ospf6_lsa *lsa; | |
718e3744 | 452 | |
d62a17ae | 453 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
454 | assert(on); | |
718e3744 | 455 | |
d62a17ae | 456 | if (on->state < OSPF6_NEIGHBOR_EXCHANGE) |
457 | return 0; | |
718e3744 | 458 | |
d62a17ae | 459 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
460 | zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name); | |
718e3744 | 461 | |
d62a17ae | 462 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
463 | OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH); | |
464 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
465 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
466 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
718e3744 | 467 | |
d62a17ae | 468 | ospf6_lsdb_remove_all(on->summary_list); |
469 | ospf6_lsdb_remove_all(on->request_list); | |
470 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
471 | ospf6_decrement_retrans_count(lsa); | |
472 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
473 | } | |
508e53e2 | 474 | |
d62a17ae | 475 | THREAD_OFF(on->thread_send_dbdesc); |
476 | on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ | |
931b1b8c | 477 | |
d62a17ae | 478 | on->thread_send_dbdesc = NULL; |
479 | thread_add_event(master, ospf6_dbdesc_send, on, 0, | |
480 | &on->thread_send_dbdesc); | |
508e53e2 | 481 | |
d62a17ae | 482 | return 0; |
718e3744 | 483 | } |
484 | ||
d62a17ae | 485 | int bad_lsreq(struct thread *thread) |
718e3744 | 486 | { |
d62a17ae | 487 | struct ospf6_neighbor *on; |
488 | struct ospf6_lsa *lsa; | |
508e53e2 | 489 | |
d62a17ae | 490 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
491 | assert(on); | |
508e53e2 | 492 | |
d62a17ae | 493 | if (on->state < OSPF6_NEIGHBOR_EXCHANGE) |
494 | return 0; | |
718e3744 | 495 | |
d62a17ae | 496 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
497 | zlog_debug("Neighbor Event %s: *BadLSReq*", on->name); | |
718e3744 | 498 | |
d62a17ae | 499 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on, |
500 | OSPF6_NEIGHBOR_EVENT_BAD_LSREQ); | |
501 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT); | |
502 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT); | |
503 | SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT); | |
718e3744 | 504 | |
d62a17ae | 505 | ospf6_lsdb_remove_all(on->summary_list); |
506 | ospf6_lsdb_remove_all(on->request_list); | |
507 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
508 | ospf6_decrement_retrans_count(lsa); | |
509 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
510 | } | |
718e3744 | 511 | |
d62a17ae | 512 | THREAD_OFF(on->thread_send_dbdesc); |
513 | on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */ | |
931b1b8c | 514 | |
d62a17ae | 515 | on->thread_send_dbdesc = NULL; |
516 | thread_add_event(master, ospf6_dbdesc_send, on, 0, | |
517 | &on->thread_send_dbdesc); | |
508e53e2 | 518 | |
d62a17ae | 519 | return 0; |
718e3744 | 520 | } |
521 | ||
d62a17ae | 522 | int oneway_received(struct thread *thread) |
718e3744 | 523 | { |
d62a17ae | 524 | struct ospf6_neighbor *on; |
525 | struct ospf6_lsa *lsa; | |
718e3744 | 526 | |
d62a17ae | 527 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
528 | assert(on); | |
508e53e2 | 529 | |
d62a17ae | 530 | if (on->state < OSPF6_NEIGHBOR_TWOWAY) |
531 | return 0; | |
508e53e2 | 532 | |
d62a17ae | 533 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
534 | zlog_debug("Neighbor Event %s: *1Way-Received*", on->name); | |
508e53e2 | 535 | |
d62a17ae | 536 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on, |
537 | OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD); | |
538 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); | |
508e53e2 | 539 | |
d62a17ae | 540 | ospf6_lsdb_remove_all(on->summary_list); |
541 | ospf6_lsdb_remove_all(on->request_list); | |
542 | for (ALL_LSDB(on->retrans_list, lsa)) { | |
543 | ospf6_decrement_retrans_count(lsa); | |
544 | ospf6_lsdb_remove(lsa, on->retrans_list); | |
545 | } | |
508e53e2 | 546 | |
d62a17ae | 547 | THREAD_OFF(on->thread_send_dbdesc); |
548 | THREAD_OFF(on->thread_send_lsreq); | |
549 | THREAD_OFF(on->thread_send_lsupdate); | |
550 | THREAD_OFF(on->thread_send_lsack); | |
508e53e2 | 551 | |
d62a17ae | 552 | return 0; |
508e53e2 | 553 | } |
554 | ||
d62a17ae | 555 | int inactivity_timer(struct thread *thread) |
508e53e2 | 556 | { |
d62a17ae | 557 | struct ospf6_neighbor *on; |
508e53e2 | 558 | |
d62a17ae | 559 | on = (struct ospf6_neighbor *)THREAD_ARG(thread); |
560 | assert(on); | |
508e53e2 | 561 | |
d62a17ae | 562 | if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
563 | zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name); | |
508e53e2 | 564 | |
d62a17ae | 565 | on->inactivity_timer = NULL; |
566 | on->drouter = on->prev_drouter = 0; | |
567 | on->bdrouter = on->prev_bdrouter = 0; | |
508e53e2 | 568 | |
d62a17ae | 569 | ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, on, |
570 | OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER); | |
571 | thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL); | |
508e53e2 | 572 | |
d62a17ae | 573 | listnode_delete(on->ospf6_if->neighbor_list, on); |
574 | ospf6_neighbor_delete(on); | |
508e53e2 | 575 | |
d62a17ae | 576 | return 0; |
718e3744 | 577 | } |
578 | ||
508e53e2 | 579 | |
718e3744 | 580 | /* vty functions */ |
581 | /* show neighbor structure */ | |
d62a17ae | 582 | static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on) |
718e3744 | 583 | { |
d62a17ae | 584 | char router_id[16]; |
68bfcc05 | 585 | char duration[64]; |
d62a17ae | 586 | struct timeval res; |
587 | char nstate[16]; | |
68bfcc05 | 588 | char deadtime[64]; |
d62a17ae | 589 | long h, m, s; |
590 | ||
591 | /* Router-ID (Name) */ | |
592 | inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); | |
508e53e2 | 593 | #ifdef HAVE_GETNAMEINFO |
d62a17ae | 594 | { |
595 | } | |
508e53e2 | 596 | #endif /*HAVE_GETNAMEINFO*/ |
597 | ||
d62a17ae | 598 | /* Dead time */ |
599 | h = m = s = 0; | |
600 | if (on->inactivity_timer) { | |
601 | s = monotime_until(&on->inactivity_timer->u.sands, NULL) | |
602 | / 1000000LL; | |
603 | h = s / 3600; | |
604 | s -= h * 3600; | |
605 | m = s / 60; | |
606 | s -= m * 60; | |
607 | } | |
608 | snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s); | |
609 | ||
610 | /* Neighbor State */ | |
611 | if (if_is_pointopoint(on->ospf6_if->interface)) | |
612 | snprintf(nstate, sizeof(nstate), "PointToPoint"); | |
613 | else { | |
614 | if (on->router_id == on->drouter) | |
615 | snprintf(nstate, sizeof(nstate), "DR"); | |
616 | else if (on->router_id == on->bdrouter) | |
617 | snprintf(nstate, sizeof(nstate), "BDR"); | |
618 | else | |
619 | snprintf(nstate, sizeof(nstate), "DROther"); | |
620 | } | |
621 | ||
622 | /* Duration */ | |
623 | monotime_since(&on->last_changed, &res); | |
624 | timerstring(&res, duration, sizeof(duration)); | |
625 | ||
626 | /* | |
627 | vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n", | |
628 | "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration", | |
629 | "I/F", "State"); | |
630 | */ | |
631 | ||
632 | vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %s[%s]\n", router_id, | |
633 | on->priority, deadtime, ospf6_neighbor_state_str[on->state], | |
634 | nstate, duration, on->ospf6_if->interface->name, | |
635 | ospf6_interface_state_str[on->ospf6_if->state]); | |
508e53e2 | 636 | } |
637 | ||
d62a17ae | 638 | static void ospf6_neighbor_show_drchoice(struct vty *vty, |
639 | struct ospf6_neighbor *on) | |
508e53e2 | 640 | { |
d62a17ae | 641 | char router_id[16]; |
642 | char drouter[16], bdrouter[16]; | |
68bfcc05 | 643 | char duration[64]; |
d62a17ae | 644 | struct timeval now, res; |
645 | ||
646 | /* | |
647 | vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n", | |
648 | "RouterID", "State", "Duration", "DR", "BDR", "I/F", | |
649 | "State"); | |
650 | */ | |
651 | ||
652 | inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id)); | |
653 | inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); | |
654 | inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); | |
655 | ||
656 | monotime(&now); | |
657 | timersub(&now, &on->last_changed, &res); | |
658 | timerstring(&res, duration, sizeof(duration)); | |
659 | ||
660 | vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", router_id, | |
661 | ospf6_neighbor_state_str[on->state], duration, drouter, | |
662 | bdrouter, on->ospf6_if->interface->name, | |
663 | ospf6_interface_state_str[on->ospf6_if->state]); | |
718e3744 | 664 | } |
665 | ||
d62a17ae | 666 | static void ospf6_neighbor_show_detail(struct vty *vty, |
667 | struct ospf6_neighbor *on) | |
718e3744 | 668 | { |
d62a17ae | 669 | char drouter[16], bdrouter[16]; |
670 | char linklocal_addr[64], duration[32]; | |
671 | struct timeval now, res; | |
672 | struct ospf6_lsa *lsa; | |
673 | ||
674 | inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr, | |
675 | sizeof(linklocal_addr)); | |
676 | inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter)); | |
677 | inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter)); | |
678 | ||
679 | monotime(&now); | |
680 | timersub(&now, &on->last_changed, &res); | |
681 | timerstring(&res, duration, sizeof(duration)); | |
682 | ||
683 | vty_out(vty, " Neighbor %s\n", on->name); | |
684 | vty_out(vty, " Area %s via interface %s (ifindex %d)\n", | |
685 | on->ospf6_if->area->name, on->ospf6_if->interface->name, | |
686 | on->ospf6_if->interface->ifindex); | |
687 | vty_out(vty, " His IfIndex: %d Link-local address: %s\n", | |
688 | on->ifindex, linklocal_addr); | |
689 | vty_out(vty, " State %s for a duration of %s\n", | |
690 | ospf6_neighbor_state_str[on->state], duration); | |
691 | vty_out(vty, " His choice of DR/BDR %s/%s, Priority %d\n", drouter, | |
692 | bdrouter, on->priority); | |
693 | vty_out(vty, " DbDesc status: %s%s%s SeqNum: %#lx\n", | |
694 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " | |
695 | : ""), | |
696 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""), | |
697 | (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ? "Master" | |
698 | : "Slave"), | |
699 | (u_long)ntohl(on->dbdesc_seqnum)); | |
700 | ||
701 | vty_out(vty, " Summary-List: %d LSAs\n", on->summary_list->count); | |
702 | for (ALL_LSDB(on->summary_list, lsa)) | |
703 | vty_out(vty, " %s\n", lsa->name); | |
704 | ||
705 | vty_out(vty, " Request-List: %d LSAs\n", on->request_list->count); | |
706 | for (ALL_LSDB(on->request_list, lsa)) | |
707 | vty_out(vty, " %s\n", lsa->name); | |
708 | ||
709 | vty_out(vty, " Retrans-List: %d LSAs\n", on->retrans_list->count); | |
710 | for (ALL_LSDB(on->retrans_list, lsa)) | |
711 | vty_out(vty, " %s\n", lsa->name); | |
712 | ||
713 | timerclear(&res); | |
714 | if (on->thread_send_dbdesc) | |
715 | timersub(&on->thread_send_dbdesc->u.sands, &now, &res); | |
716 | timerstring(&res, duration, sizeof(duration)); | |
717 | vty_out(vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", | |
718 | on->dbdesc_list->count, duration, | |
719 | (on->thread_send_dbdesc ? "on" : "off")); | |
720 | for (ALL_LSDB(on->dbdesc_list, lsa)) | |
721 | vty_out(vty, " %s\n", lsa->name); | |
722 | ||
723 | timerclear(&res); | |
724 | if (on->thread_send_lsreq) | |
725 | timersub(&on->thread_send_lsreq->u.sands, &now, &res); | |
726 | timerstring(&res, duration, sizeof(duration)); | |
727 | vty_out(vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n", | |
728 | on->request_list->count, duration, | |
729 | (on->thread_send_lsreq ? "on" : "off")); | |
730 | for (ALL_LSDB(on->request_list, lsa)) | |
731 | vty_out(vty, " %s\n", lsa->name); | |
732 | ||
733 | timerclear(&res); | |
734 | if (on->thread_send_lsupdate) | |
735 | timersub(&on->thread_send_lsupdate->u.sands, &now, &res); | |
736 | timerstring(&res, duration, sizeof(duration)); | |
737 | vty_out(vty, | |
738 | " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", | |
739 | on->lsupdate_list->count, duration, | |
740 | (on->thread_send_lsupdate ? "on" : "off")); | |
741 | for (ALL_LSDB(on->lsupdate_list, lsa)) | |
742 | vty_out(vty, " %s\n", lsa->name); | |
743 | ||
744 | timerclear(&res); | |
745 | if (on->thread_send_lsack) | |
746 | timersub(&on->thread_send_lsack->u.sands, &now, &res); | |
747 | timerstring(&res, duration, sizeof(duration)); | |
748 | vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", | |
749 | on->lsack_list->count, duration, | |
750 | (on->thread_send_lsack ? "on" : "off")); | |
751 | for (ALL_LSDB(on->lsack_list, lsa)) | |
752 | vty_out(vty, " %s\n", lsa->name); | |
753 | ||
754 | ospf6_bfd_show_info(vty, on->bfd_info, 0); | |
718e3744 | 755 | } |
756 | ||
508e53e2 | 757 | DEFUN (show_ipv6_ospf6_neighbor, |
758 | show_ipv6_ospf6_neighbor_cmd, | |
6de69f83 | 759 | "show ipv6 ospf6 neighbor [<detail|drchoice>]", |
718e3744 | 760 | SHOW_STR |
761 | IP6_STR | |
762 | OSPF6_STR | |
763 | "Neighbor list\n" | |
1d68dbfe DW |
764 | "Display details\n" |
765 | "Display DR choices\n") | |
718e3744 | 766 | { |
d62a17ae | 767 | int idx_type = 4; |
768 | struct ospf6_neighbor *on; | |
769 | struct ospf6_interface *oi; | |
770 | struct ospf6_area *oa; | |
771 | struct listnode *i, *j, *k; | |
772 | void (*showfunc)(struct vty *, struct ospf6_neighbor *); | |
773 | ||
774 | OSPF6_CMD_CHECK_RUNNING(); | |
775 | showfunc = ospf6_neighbor_show; | |
776 | ||
777 | if (argc == 5) { | |
778 | if (!strncmp(argv[idx_type]->arg, "de", 2)) | |
779 | showfunc = ospf6_neighbor_show_detail; | |
780 | else if (!strncmp(argv[idx_type]->arg, "dr", 2)) | |
781 | showfunc = ospf6_neighbor_show_drchoice; | |
782 | } | |
783 | ||
784 | if (showfunc == ospf6_neighbor_show) | |
785 | vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n", | |
786 | "Neighbor ID", "Pri", "DeadTime", "State", "IfState", | |
787 | "Duration", "I/F", "State"); | |
788 | else if (showfunc == ospf6_neighbor_show_drchoice) | |
789 | vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n", "RouterID", | |
790 | "State", "Duration", "DR", "BDR", "I/F", "State"); | |
791 | ||
792 | for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) | |
793 | for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) | |
794 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) | |
795 | (*showfunc)(vty, on); | |
796 | ||
797 | return CMD_SUCCESS; | |
718e3744 | 798 | } |
799 | ||
718e3744 | 800 | |
508e53e2 | 801 | DEFUN (show_ipv6_ospf6_neighbor_one, |
802 | show_ipv6_ospf6_neighbor_one_cmd, | |
803 | "show ipv6 ospf6 neighbor A.B.C.D", | |
718e3744 | 804 | SHOW_STR |
805 | IP6_STR | |
806 | OSPF6_STR | |
508e53e2 | 807 | "Neighbor list\n" |
808 | "Specify Router-ID as IPv4 address notation\n" | |
809 | ) | |
718e3744 | 810 | { |
d62a17ae | 811 | int idx_ipv4 = 4; |
812 | struct ospf6_neighbor *on; | |
813 | struct ospf6_interface *oi; | |
814 | struct ospf6_area *oa; | |
815 | struct listnode *i, *j, *k; | |
816 | void (*showfunc)(struct vty *, struct ospf6_neighbor *); | |
817 | u_int32_t router_id; | |
818 | ||
819 | OSPF6_CMD_CHECK_RUNNING(); | |
820 | showfunc = ospf6_neighbor_show_detail; | |
821 | ||
822 | if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) { | |
823 | vty_out(vty, "Router-ID is not parsable: %s\n", | |
824 | argv[idx_ipv4]->arg); | |
825 | return CMD_SUCCESS; | |
826 | } | |
827 | ||
828 | for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) | |
829 | for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) | |
830 | for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) | |
831 | (*showfunc)(vty, on); | |
832 | ||
833 | return CMD_SUCCESS; | |
718e3744 | 834 | } |
835 | ||
d62a17ae | 836 | void ospf6_neighbor_init(void) |
718e3744 | 837 | { |
d62a17ae | 838 | install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); |
839 | install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd); | |
508e53e2 | 840 | } |
841 | ||
842 | DEFUN (debug_ospf6_neighbor, | |
843 | debug_ospf6_neighbor_cmd, | |
6de69f83 | 844 | "debug ospf6 neighbor [<state|event>]", |
508e53e2 | 845 | DEBUG_STR |
846 | OSPF6_STR | |
847 | "Debug OSPFv3 Neighbor\n" | |
1d68dbfe DW |
848 | "Debug OSPFv3 Neighbor State Change\n" |
849 | "Debug OSPFv3 Neighbor Event\n") | |
508e53e2 | 850 | { |
d62a17ae | 851 | int idx_type = 3; |
852 | unsigned char level = 0; | |
853 | ||
854 | if (argc == 4) { | |
855 | if (!strncmp(argv[idx_type]->arg, "s", 1)) | |
856 | level = OSPF6_DEBUG_NEIGHBOR_STATE; | |
857 | else if (!strncmp(argv[idx_type]->arg, "e", 1)) | |
858 | level = OSPF6_DEBUG_NEIGHBOR_EVENT; | |
859 | } else | |
860 | level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; | |
861 | ||
862 | OSPF6_DEBUG_NEIGHBOR_ON(level); | |
863 | return CMD_SUCCESS; | |
718e3744 | 864 | } |
865 | ||
508e53e2 | 866 | |
867 | DEFUN (no_debug_ospf6_neighbor, | |
868 | no_debug_ospf6_neighbor_cmd, | |
6de69f83 | 869 | "no debug ospf6 neighbor [<state|event>]", |
508e53e2 | 870 | NO_STR |
871 | DEBUG_STR | |
872 | OSPF6_STR | |
873 | "Debug OSPFv3 Neighbor\n" | |
1d68dbfe DW |
874 | "Debug OSPFv3 Neighbor State Change\n" |
875 | "Debug OSPFv3 Neighbor Event\n") | |
508e53e2 | 876 | { |
d62a17ae | 877 | int idx_type = 4; |
878 | unsigned char level = 0; | |
879 | ||
880 | if (argc == 5) { | |
881 | if (!strncmp(argv[idx_type]->arg, "s", 1)) | |
882 | level = OSPF6_DEBUG_NEIGHBOR_STATE; | |
883 | if (!strncmp(argv[idx_type]->arg, "e", 1)) | |
884 | level = OSPF6_DEBUG_NEIGHBOR_EVENT; | |
885 | } else | |
886 | level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT; | |
887 | ||
888 | OSPF6_DEBUG_NEIGHBOR_OFF(level); | |
889 | return CMD_SUCCESS; | |
508e53e2 | 890 | } |
891 | ||
508e53e2 | 892 | |
4dfd8aff DW |
893 | DEFUN (no_debug_ospf6, |
894 | no_debug_ospf6_cmd, | |
895 | "no debug ospf6", | |
896 | NO_STR | |
897 | DEBUG_STR | |
898 | OSPF6_STR) | |
899 | { | |
d62a17ae | 900 | u_int i; |
901 | struct ospf6_lsa_handler *handler = NULL; | |
902 | ||
903 | OSPF6_DEBUG_ABR_OFF(); | |
904 | OSPF6_DEBUG_ASBR_OFF(); | |
905 | OSPF6_DEBUG_BROUTER_OFF(); | |
906 | OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF(); | |
907 | OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF(); | |
908 | OSPF6_DEBUG_FLOODING_OFF(); | |
909 | OSPF6_DEBUG_INTERFACE_OFF(); | |
910 | ||
911 | for (i = 0; i < vector_active(ospf6_lsa_handler_vector); i++) { | |
912 | handler = vector_slot(ospf6_lsa_handler_vector, i); | |
913 | ||
914 | if (handler != NULL) { | |
915 | UNSET_FLAG(handler->debug, OSPF6_LSA_DEBUG); | |
916 | } | |
917 | } | |
918 | ||
919 | for (i = 0; i < 6; i++) | |
920 | OSPF6_DEBUG_MESSAGE_OFF(i, | |
921 | OSPF6_DEBUG_NEIGHBOR_STATE | |
922 | | OSPF6_DEBUG_NEIGHBOR_EVENT); | |
923 | ||
924 | OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE | |
925 | | OSPF6_DEBUG_NEIGHBOR_EVENT); | |
926 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE); | |
927 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA); | |
928 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER); | |
929 | OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY); | |
930 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS); | |
931 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME); | |
932 | OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE); | |
933 | OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV); | |
934 | ||
935 | return CMD_SUCCESS; | |
4dfd8aff DW |
936 | } |
937 | ||
d62a17ae | 938 | int config_write_ospf6_debug_neighbor(struct vty *vty) |
508e53e2 | 939 | { |
d62a17ae | 940 | if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) |
941 | vty_out(vty, "debug ospf6 neighbor\n"); | |
942 | else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) | |
943 | vty_out(vty, "debug ospf6 neighbor state\n"); | |
944 | else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT)) | |
945 | vty_out(vty, "debug ospf6 neighbor event\n"); | |
946 | return 0; | |
508e53e2 | 947 | } |
948 | ||
d62a17ae | 949 | void install_element_ospf6_debug_neighbor(void) |
508e53e2 | 950 | { |
d62a17ae | 951 | install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd); |
952 | install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd); | |
953 | install_element(ENABLE_NODE, &no_debug_ospf6_cmd); | |
954 | install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd); | |
955 | install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd); | |
956 | install_element(CONFIG_NODE, &no_debug_ospf6_cmd); | |
508e53e2 | 957 | } |