]>
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 | * | |
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. | |
20 | */ | |
21 | ||
508e53e2 | 22 | #include <zebra.h> |
718e3744 | 23 | |
508e53e2 | 24 | #include "memory.h" |
718e3744 | 25 | #include "if.h" |
26 | #include "log.h" | |
27 | #include "command.h" | |
508e53e2 | 28 | #include "thread.h" |
29 | #include "prefix.h" | |
30 | #include "plist.h" | |
718e3744 | 31 | |
508e53e2 | 32 | #include "ospf6d.h" |
33 | #include "ospf6_lsa.h" | |
718e3744 | 34 | #include "ospf6_lsdb.h" |
508e53e2 | 35 | #include "ospf6_network.h" |
36 | #include "ospf6_message.h" | |
37 | #include "ospf6_route.h" | |
718e3744 | 38 | #include "ospf6_top.h" |
39 | #include "ospf6_area.h" | |
40 | #include "ospf6_interface.h" | |
508e53e2 | 41 | #include "ospf6_neighbor.h" |
42 | #include "ospf6_intra.h" | |
43 | #include "ospf6_spf.h" | |
718e3744 | 44 | |
508e53e2 | 45 | unsigned char conf_debug_ospf6_interface = 0; |
46 | ||
47 | char *ospf6_interface_state_str[] = | |
718e3744 | 48 | { |
508e53e2 | 49 | "None", |
50 | "Down", | |
51 | "Loopback", | |
52 | "Waiting", | |
53 | "PointToPoint", | |
54 | "DROther", | |
55 | "BDR", | |
56 | "DR", | |
57 | NULL | |
718e3744 | 58 | }; |
59 | ||
508e53e2 | 60 | struct ospf6_interface * |
61 | ospf6_interface_lookup_by_ifindex (int ifindex) | |
718e3744 | 62 | { |
508e53e2 | 63 | struct ospf6_interface *oi; |
64 | struct interface *ifp; | |
718e3744 | 65 | |
508e53e2 | 66 | ifp = if_lookup_by_index (ifindex); |
67 | if (ifp == NULL) | |
68 | return (struct ospf6_interface *) NULL; | |
69 | ||
70 | oi = (struct ospf6_interface *) ifp->info; | |
71 | return oi; | |
718e3744 | 72 | } |
73 | ||
508e53e2 | 74 | struct ospf6_interface * |
75 | ospf6_interface_lookup_by_name (char *ifname) | |
718e3744 | 76 | { |
508e53e2 | 77 | struct ospf6_interface *oi; |
78 | struct interface *ifp; | |
718e3744 | 79 | |
508e53e2 | 80 | ifp = if_lookup_by_name (ifname); |
81 | if (ifp == NULL) | |
82 | return (struct ospf6_interface *) NULL; | |
718e3744 | 83 | |
508e53e2 | 84 | oi = (struct ospf6_interface *) ifp->info; |
85 | return oi; | |
718e3744 | 86 | } |
87 | ||
508e53e2 | 88 | /* schedule routing table recalculation */ |
718e3744 | 89 | void |
508e53e2 | 90 | ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa) |
718e3744 | 91 | { |
508e53e2 | 92 | struct ospf6_interface *oi; |
718e3744 | 93 | |
508e53e2 | 94 | oi = (struct ospf6_interface *) lsa->scope; |
95 | switch (ntohs (lsa->header->type)) | |
96 | { | |
97 | case OSPF6_LSTYPE_LINK: | |
98 | if (oi->state == OSPF6_INTERFACE_DR) | |
99 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
100 | ospf6_spf_schedule (oi->area); | |
101 | break; | |
102 | ||
103 | default: | |
104 | if (IS_OSPF6_DEBUG_LSA (RECV)) | |
105 | zlog_info ("Unknown LSA in Interface %s's lsdb", | |
106 | oi->interface->name); | |
107 | break; | |
108 | } | |
718e3744 | 109 | } |
110 | ||
111 | /* Create new ospf6 interface structure */ | |
112 | struct ospf6_interface * | |
113 | ospf6_interface_create (struct interface *ifp) | |
114 | { | |
508e53e2 | 115 | struct ospf6_interface *oi; |
3b4cd3a9 | 116 | int iobuflen; |
718e3744 | 117 | |
508e53e2 | 118 | oi = (struct ospf6_interface *) |
718e3744 | 119 | XMALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface)); |
120 | ||
508e53e2 | 121 | if (oi) |
122 | memset (oi, 0, sizeof (struct ospf6_interface)); | |
718e3744 | 123 | else |
124 | { | |
125 | zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex); | |
126 | return (struct ospf6_interface *) NULL; | |
127 | } | |
128 | ||
508e53e2 | 129 | oi->area = (struct ospf6_area *) NULL; |
130 | oi->neighbor_list = list_new (); | |
131 | oi->neighbor_list->cmp = ospf6_neighbor_cmp; | |
132 | oi->linklocal_addr = (struct in6_addr *) NULL; | |
133 | oi->instance_id = 0; | |
134 | oi->transdelay = 1; | |
135 | oi->priority = 1; | |
136 | ||
137 | oi->hello_interval = 10; | |
138 | oi->dead_interval = 40; | |
139 | oi->rxmt_interval = 5; | |
140 | oi->cost = 1; | |
508e53e2 | 141 | oi->state = OSPF6_INTERFACE_DOWN; |
142 | oi->flag = 0; | |
143 | ||
b596c71e | 144 | /* Try to adjust I/O buffer size with IfMtu */ |
1203e1c0 | 145 | oi->ifmtu = ifp->mtu6; |
146 | iobuflen = ospf6_iobuf_size (ifp->mtu6); | |
b596c71e | 147 | if (oi->ifmtu > iobuflen) |
3b4cd3a9 | 148 | { |
149 | zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", | |
150 | ifp->name, iobuflen); | |
151 | oi->ifmtu = iobuflen; | |
152 | } | |
3b4cd3a9 | 153 | |
508e53e2 | 154 | oi->lsupdate_list = ospf6_lsdb_create (); |
155 | oi->lsack_list = ospf6_lsdb_create (); | |
156 | oi->lsdb = ospf6_lsdb_create (); | |
157 | oi->lsdb->hook_add = ospf6_interface_lsdb_hook; | |
158 | oi->lsdb->hook_remove = ospf6_interface_lsdb_hook; | |
159 | ||
160 | oi->route_connected = ospf6_route_table_create (); | |
718e3744 | 161 | |
162 | /* link both */ | |
508e53e2 | 163 | oi->interface = ifp; |
164 | ifp->info = oi; | |
718e3744 | 165 | |
508e53e2 | 166 | return oi; |
718e3744 | 167 | } |
168 | ||
169 | void | |
508e53e2 | 170 | ospf6_interface_delete (struct ospf6_interface *oi) |
718e3744 | 171 | { |
172 | listnode n; | |
508e53e2 | 173 | struct ospf6_neighbor *on; |
718e3744 | 174 | |
508e53e2 | 175 | for (n = listhead (oi->neighbor_list); n; nextnode (n)) |
718e3744 | 176 | { |
508e53e2 | 177 | on = (struct ospf6_neighbor *) getdata (n); |
178 | ospf6_neighbor_delete (on); | |
718e3744 | 179 | } |
508e53e2 | 180 | list_delete (oi->neighbor_list); |
718e3744 | 181 | |
508e53e2 | 182 | THREAD_OFF (oi->thread_send_hello); |
183 | THREAD_OFF (oi->thread_send_lsupdate); | |
184 | THREAD_OFF (oi->thread_send_lsack); | |
185 | ||
186 | ospf6_lsdb_remove_all (oi->lsdb); | |
187 | ospf6_lsdb_remove_all (oi->lsupdate_list); | |
188 | ospf6_lsdb_remove_all (oi->lsack_list); | |
189 | ||
190 | ospf6_lsdb_delete (oi->lsdb); | |
191 | ospf6_lsdb_delete (oi->lsupdate_list); | |
192 | ospf6_lsdb_delete (oi->lsack_list); | |
718e3744 | 193 | |
508e53e2 | 194 | ospf6_route_table_delete (oi->route_connected); |
718e3744 | 195 | |
196 | /* cut link */ | |
508e53e2 | 197 | oi->interface->info = NULL; |
718e3744 | 198 | |
199 | /* plist_name */ | |
508e53e2 | 200 | if (oi->plist_name) |
201 | XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name); | |
202 | ||
203 | XFREE (MTYPE_OSPF6_IF, oi); | |
204 | } | |
205 | ||
206 | void | |
207 | ospf6_interface_enable (struct ospf6_interface *oi) | |
208 | { | |
209 | UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); | |
718e3744 | 210 | |
508e53e2 | 211 | oi->thread_send_hello = |
212 | thread_add_event (master, ospf6_hello_send, oi, 0); | |
213 | } | |
214 | ||
215 | void | |
216 | ospf6_interface_disable (struct ospf6_interface *oi) | |
217 | { | |
218 | listnode i; | |
219 | struct ospf6_neighbor *on; | |
220 | ||
221 | SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); | |
222 | ||
223 | for (i = listhead (oi->neighbor_list); i; nextnode (i)) | |
224 | { | |
225 | on = (struct ospf6_neighbor *) getdata (i); | |
226 | ospf6_neighbor_delete (on); | |
227 | } | |
228 | list_delete_all_node (oi->neighbor_list); | |
229 | ||
230 | ospf6_lsdb_remove_all (oi->lsdb); | |
231 | ospf6_lsdb_remove_all (oi->lsupdate_list); | |
232 | ospf6_lsdb_remove_all (oi->lsack_list); | |
233 | ||
234 | THREAD_OFF (oi->thread_send_hello); | |
235 | THREAD_OFF (oi->thread_send_lsupdate); | |
236 | THREAD_OFF (oi->thread_send_lsack); | |
718e3744 | 237 | } |
238 | ||
239 | static struct in6_addr * | |
508e53e2 | 240 | ospf6_interface_get_linklocal_address (struct interface *ifp) |
718e3744 | 241 | { |
242 | listnode n; | |
243 | struct connected *c; | |
244 | struct in6_addr *l = (struct in6_addr *) NULL; | |
245 | ||
246 | /* for each connected address */ | |
247 | for (n = listhead (ifp->connected); n; nextnode (n)) | |
248 | { | |
249 | c = (struct connected *) getdata (n); | |
250 | ||
251 | /* if family not AF_INET6, ignore */ | |
252 | if (c->address->family != AF_INET6) | |
253 | continue; | |
254 | ||
255 | /* linklocal scope check */ | |
256 | if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6)) | |
257 | l = &c->address->u.prefix6; | |
258 | } | |
259 | return l; | |
260 | } | |
261 | ||
262 | void | |
263 | ospf6_interface_if_add (struct interface *ifp) | |
264 | { | |
508e53e2 | 265 | struct ospf6_interface *oi; |
3b4cd3a9 | 266 | int iobuflen; |
718e3744 | 267 | |
508e53e2 | 268 | oi = (struct ospf6_interface *) ifp->info; |
269 | if (oi == NULL) | |
718e3744 | 270 | return; |
271 | ||
b596c71e | 272 | /* Try to adjust I/O buffer size with IfMtu */ |
273 | if (oi->ifmtu == 0) | |
1203e1c0 | 274 | oi->ifmtu = ifp->mtu6; |
275 | iobuflen = ospf6_iobuf_size (ifp->mtu6); | |
b596c71e | 276 | if (oi->ifmtu > iobuflen) |
3b4cd3a9 | 277 | { |
278 | zlog_info ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.", | |
279 | ifp->name, iobuflen); | |
280 | oi->ifmtu = iobuflen; | |
281 | } | |
718e3744 | 282 | |
283 | /* interface start */ | |
508e53e2 | 284 | if (oi->area) |
285 | thread_add_event (master, interface_up, oi, 0); | |
718e3744 | 286 | } |
287 | ||
288 | void | |
289 | ospf6_interface_if_del (struct interface *ifp) | |
290 | { | |
508e53e2 | 291 | struct ospf6_interface *oi; |
718e3744 | 292 | |
508e53e2 | 293 | oi = (struct ospf6_interface *) ifp->info; |
294 | if (oi == NULL) | |
718e3744 | 295 | return; |
296 | ||
297 | /* interface stop */ | |
508e53e2 | 298 | if (oi->area) |
299 | thread_execute (master, interface_down, oi, 0); | |
718e3744 | 300 | |
508e53e2 | 301 | listnode_delete (oi->area->if_list, oi); |
302 | oi->area = (struct ospf6_area *) NULL; | |
718e3744 | 303 | |
304 | /* cut link */ | |
508e53e2 | 305 | oi->interface = NULL; |
718e3744 | 306 | ifp->info = NULL; |
307 | ||
508e53e2 | 308 | ospf6_interface_delete (oi); |
718e3744 | 309 | } |
310 | ||
311 | void | |
312 | ospf6_interface_state_update (struct interface *ifp) | |
313 | { | |
508e53e2 | 314 | struct ospf6_interface *oi; |
718e3744 | 315 | |
508e53e2 | 316 | oi = (struct ospf6_interface *) ifp->info; |
317 | if (oi == NULL) | |
718e3744 | 318 | return; |
508e53e2 | 319 | if (oi->area == NULL) |
718e3744 | 320 | return; |
321 | ||
322 | if (if_is_up (ifp)) | |
508e53e2 | 323 | thread_add_event (master, interface_up, oi, 0); |
718e3744 | 324 | else |
508e53e2 | 325 | thread_add_event (master, interface_down, oi, 0); |
718e3744 | 326 | |
327 | return; | |
328 | } | |
329 | ||
330 | void | |
508e53e2 | 331 | ospf6_interface_connected_route_update (struct interface *ifp) |
718e3744 | 332 | { |
508e53e2 | 333 | struct ospf6_interface *oi; |
334 | struct ospf6_route *route; | |
335 | struct connected *c; | |
336 | listnode i; | |
718e3744 | 337 | |
508e53e2 | 338 | oi = (struct ospf6_interface *) ifp->info; |
339 | if (oi == NULL) | |
718e3744 | 340 | return; |
341 | ||
342 | /* reset linklocal pointer */ | |
508e53e2 | 343 | oi->linklocal_addr = ospf6_interface_get_linklocal_address (ifp); |
718e3744 | 344 | |
508e53e2 | 345 | /* if area is null, do not make connected-route list */ |
346 | if (oi->area == NULL) | |
718e3744 | 347 | return; |
348 | ||
508e53e2 | 349 | /* update "route to advertise" interface route table */ |
350 | ospf6_route_remove_all (oi->route_connected); | |
351 | for (i = listhead (oi->interface->connected); i; nextnode (i)) | |
352 | { | |
353 | c = (struct connected *) getdata (i); | |
354 | ||
355 | if (c->address->family != AF_INET6) | |
356 | continue; | |
357 | ||
358 | CONTINUE_IF_ADDRESS_LINKLOCAL (c->address); | |
359 | CONTINUE_IF_ADDRESS_UNSPECIFIED (c->address); | |
360 | CONTINUE_IF_ADDRESS_LOOPBACK (c->address); | |
361 | CONTINUE_IF_ADDRESS_V4COMPAT (c->address); | |
362 | CONTINUE_IF_ADDRESS_V4MAPPED (c->address); | |
718e3744 | 363 | |
508e53e2 | 364 | /* apply filter */ |
365 | if (oi->plist_name) | |
366 | { | |
367 | struct prefix_list *plist; | |
368 | enum prefix_list_type ret; | |
369 | char buf[128]; | |
370 | ||
371 | prefix2str (c->address, buf, sizeof (buf)); | |
372 | plist = prefix_list_lookup (AFI_IP6, oi->plist_name); | |
373 | ret = prefix_list_apply (plist, (void *) c->address); | |
374 | if (ret == PREFIX_DENY) | |
375 | { | |
376 | zlog_info ("%s on %s filtered by prefix-list %s ", | |
377 | buf, oi->interface->name, oi->plist_name); | |
378 | continue; | |
379 | } | |
380 | } | |
381 | ||
382 | route = ospf6_route_create (); | |
383 | memcpy (&route->prefix, c->address, sizeof (struct prefix)); | |
384 | apply_mask (&route->prefix); | |
385 | route->type = OSPF6_DEST_TYPE_NETWORK; | |
386 | route->path.area_id = oi->area->area_id; | |
387 | route->path.type = OSPF6_PATH_TYPE_INTRA; | |
388 | route->path.cost = oi->cost; | |
389 | route->nexthop[0].ifindex = oi->interface->ifindex; | |
390 | inet_pton (AF_INET6, "::1", &route->nexthop[0].address); | |
391 | ospf6_route_add (route, oi->route_connected); | |
392 | } | |
393 | ||
394 | /* create new Link-LSA */ | |
395 | OSPF6_LINK_LSA_SCHEDULE (oi); | |
396 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
397 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); | |
718e3744 | 398 | } |
399 | ||
508e53e2 | 400 | static void |
401 | ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi) | |
718e3744 | 402 | { |
508e53e2 | 403 | u_char prev_state; |
718e3744 | 404 | |
508e53e2 | 405 | prev_state = oi->state; |
406 | oi->state = next_state; | |
718e3744 | 407 | |
508e53e2 | 408 | if (prev_state == next_state) |
409 | return; | |
410 | ||
411 | /* log */ | |
412 | if (IS_OSPF6_DEBUG_INTERFACE) | |
413 | { | |
414 | zlog_info ("Interface state change %s: %s -> %s", oi->interface->name, | |
415 | ospf6_interface_state_str[prev_state], | |
416 | ospf6_interface_state_str[next_state]); | |
417 | } | |
718e3744 | 418 | |
508e53e2 | 419 | if ((prev_state == OSPF6_INTERFACE_DR || |
420 | prev_state == OSPF6_INTERFACE_BDR) && | |
421 | (next_state != OSPF6_INTERFACE_DR && | |
422 | next_state != OSPF6_INTERFACE_BDR)) | |
423 | ospf6_leave_alldrouters (oi->interface->ifindex); | |
424 | if ((prev_state != OSPF6_INTERFACE_DR && | |
425 | prev_state != OSPF6_INTERFACE_BDR) && | |
426 | (next_state == OSPF6_INTERFACE_DR || | |
427 | next_state == OSPF6_INTERFACE_BDR)) | |
428 | ospf6_join_alldrouters (oi->interface->ifindex); | |
429 | ||
430 | OSPF6_ROUTER_LSA_SCHEDULE (oi->area); | |
431 | if (prev_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_DR) | |
432 | { | |
433 | OSPF6_NETWORK_LSA_SCHEDULE (oi); | |
434 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
435 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); | |
436 | } | |
718e3744 | 437 | } |
438 | ||
508e53e2 | 439 | \f |
440 | /* DR Election, RFC2328 section 9.4 */ | |
718e3744 | 441 | |
508e53e2 | 442 | #define IS_ELIGIBLE(n) \ |
443 | ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0) | |
718e3744 | 444 | |
508e53e2 | 445 | static struct ospf6_neighbor * |
446 | better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b) | |
447 | { | |
448 | if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) && | |
449 | (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)) | |
450 | return NULL; | |
451 | else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) | |
452 | return b; | |
453 | else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id) | |
454 | return a; | |
455 | ||
456 | if (a->bdrouter == a->router_id && b->bdrouter != b->router_id) | |
457 | return a; | |
458 | if (a->bdrouter != a->router_id && b->bdrouter == b->router_id) | |
459 | return b; | |
460 | ||
461 | if (a->priority > b->priority) | |
462 | return a; | |
463 | if (a->priority < b->priority) | |
464 | return b; | |
465 | ||
466 | if (ntohl (a->router_id) > ntohl (b->router_id)) | |
467 | return a; | |
468 | if (ntohl (a->router_id) < ntohl (b->router_id)) | |
469 | return b; | |
470 | ||
471 | zlog_warn ("Router-ID duplicate ?"); | |
472 | return a; | |
473 | } | |
718e3744 | 474 | |
508e53e2 | 475 | static struct ospf6_neighbor * |
476 | better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b) | |
477 | { | |
478 | if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) && | |
479 | (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)) | |
480 | return NULL; | |
481 | else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) | |
482 | return b; | |
483 | else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id) | |
484 | return a; | |
485 | ||
486 | if (a->drouter == a->router_id && b->drouter != b->router_id) | |
487 | return a; | |
488 | if (a->drouter != a->router_id && b->drouter == b->router_id) | |
489 | return b; | |
490 | ||
491 | if (a->priority > b->priority) | |
492 | return a; | |
493 | if (a->priority < b->priority) | |
494 | return b; | |
495 | ||
496 | if (ntohl (a->router_id) > ntohl (b->router_id)) | |
497 | return a; | |
498 | if (ntohl (a->router_id) < ntohl (b->router_id)) | |
499 | return b; | |
500 | ||
501 | zlog_warn ("Router-ID duplicate ?"); | |
502 | return a; | |
718e3744 | 503 | } |
504 | ||
508e53e2 | 505 | static u_char |
506 | dr_election (struct ospf6_interface *oi) | |
718e3744 | 507 | { |
508e53e2 | 508 | listnode i; |
509 | struct ospf6_neighbor *on, *drouter, *bdrouter, myself; | |
510 | struct ospf6_neighbor *best_drouter, *best_bdrouter; | |
511 | u_char next_state = 0; | |
512 | ||
513 | drouter = bdrouter = NULL; | |
514 | best_drouter = best_bdrouter = NULL; | |
515 | ||
516 | /* pseudo neighbor myself, including noting current DR/BDR (1) */ | |
517 | memset (&myself, 0, sizeof (myself)); | |
518 | inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name, | |
519 | sizeof (myself.name)); | |
520 | myself.state = OSPF6_NEIGHBOR_TWOWAY; | |
521 | myself.drouter = oi->drouter; | |
522 | myself.bdrouter = oi->bdrouter; | |
523 | myself.priority = oi->priority; | |
524 | myself.router_id = oi->area->ospf6->router_id; | |
525 | ||
526 | /* Electing BDR (2) */ | |
527 | for (i = listhead (oi->neighbor_list); i; nextnode (i)) | |
528 | { | |
529 | on = (struct ospf6_neighbor *) getdata (i); | |
530 | bdrouter = better_bdrouter (bdrouter, on); | |
531 | } | |
532 | best_bdrouter = bdrouter; | |
533 | bdrouter = better_bdrouter (best_bdrouter, &myself); | |
534 | ||
535 | /* Electing DR (3) */ | |
536 | for (i = listhead (oi->neighbor_list); i; nextnode (i)) | |
537 | { | |
538 | on = (struct ospf6_neighbor *) getdata (i); | |
539 | drouter = better_drouter (drouter, on); | |
540 | } | |
541 | best_drouter = drouter; | |
542 | drouter = better_drouter (best_drouter, &myself); | |
543 | if (drouter == NULL) | |
544 | drouter = bdrouter; | |
545 | ||
546 | /* the router itself is newly/no longer DR/BDR (4) */ | |
547 | if ((drouter == &myself && myself.drouter != myself.router_id) || | |
548 | (drouter != &myself && myself.drouter == myself.router_id) || | |
549 | (bdrouter == &myself && myself.bdrouter != myself.router_id) || | |
550 | (bdrouter != &myself && myself.bdrouter == myself.router_id)) | |
551 | { | |
552 | myself.drouter = (drouter ? drouter->router_id : htonl (0)); | |
553 | myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0)); | |
554 | ||
555 | /* compatible to Electing BDR (2) */ | |
556 | bdrouter = better_bdrouter (best_bdrouter, &myself); | |
557 | ||
558 | /* compatible to Electing DR (3) */ | |
559 | drouter = better_drouter (best_drouter, &myself); | |
560 | if (drouter == NULL) | |
561 | drouter = bdrouter; | |
562 | } | |
563 | ||
564 | /* Set interface state accordingly (5) */ | |
565 | if (drouter && drouter == &myself) | |
566 | next_state = OSPF6_INTERFACE_DR; | |
567 | else if (bdrouter && bdrouter == &myself) | |
568 | next_state = OSPF6_INTERFACE_BDR; | |
569 | else | |
570 | next_state = OSPF6_INTERFACE_DROTHER; | |
718e3744 | 571 | |
508e53e2 | 572 | /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */ |
573 | /* XXX */ | |
574 | ||
575 | /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */ | |
576 | /* RFC 2328 section 12.4. Originating LSAs (3) will be handled | |
577 | accordingly after AdjOK */ | |
578 | if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) || | |
579 | oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0))) | |
718e3744 | 580 | { |
508e53e2 | 581 | if (IS_OSPF6_DEBUG_INTERFACE) |
582 | zlog_info ("DR Election on %s: DR: %s BDR: %s", oi->interface->name, | |
583 | (drouter ? drouter->name : "0.0.0.0"), | |
584 | (bdrouter ? bdrouter->name : "0.0.0.0")); | |
585 | ||
586 | for (i = listhead (oi->neighbor_list); i; nextnode (i)) | |
587 | { | |
588 | on = (struct ospf6_neighbor *) getdata (i); | |
589 | if (on->state < OSPF6_NEIGHBOR_TWOWAY) | |
590 | continue; | |
591 | /* Schedule AdjOK. */ | |
592 | thread_add_event (master, adj_ok, on, 0); | |
593 | } | |
718e3744 | 594 | } |
508e53e2 | 595 | |
596 | oi->drouter = (drouter ? drouter->router_id : htonl (0)); | |
597 | oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0)); | |
598 | return next_state; | |
718e3744 | 599 | } |
600 | ||
508e53e2 | 601 | \f |
602 | /* Interface State Machine */ | |
718e3744 | 603 | int |
508e53e2 | 604 | interface_up (struct thread *thread) |
718e3744 | 605 | { |
508e53e2 | 606 | struct ospf6_interface *oi; |
607 | ||
608 | oi = (struct ospf6_interface *) THREAD_ARG (thread); | |
609 | assert (oi && oi->interface); | |
610 | ||
611 | if (IS_OSPF6_DEBUG_INTERFACE) | |
612 | zlog_info ("Interface Event %s: [InterfaceUp]", | |
613 | oi->interface->name); | |
614 | ||
615 | /* check physical interface is up */ | |
616 | if (! if_is_up (oi->interface)) | |
617 | { | |
618 | if (IS_OSPF6_DEBUG_INTERFACE) | |
619 | zlog_info ("Interface %s is down, can't execute [InterfaceUp]", | |
620 | oi->interface->name); | |
621 | return 0; | |
622 | } | |
623 | ||
624 | /* if already enabled, do nothing */ | |
625 | if (oi->state > OSPF6_INTERFACE_DOWN) | |
626 | { | |
627 | if (IS_OSPF6_DEBUG_INTERFACE) | |
628 | zlog_info ("Interface %s already enabled", | |
629 | oi->interface->name); | |
630 | return 0; | |
631 | } | |
632 | ||
633 | /* Join AllSPFRouters */ | |
634 | ospf6_join_allspfrouters (oi->interface->ifindex); | |
635 | ||
636 | /* Update interface route */ | |
637 | ospf6_interface_connected_route_update (oi->interface); | |
718e3744 | 638 | |
508e53e2 | 639 | /* Schedule Hello */ |
640 | if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) | |
641 | thread_add_event (master, ospf6_hello_send, oi, 0); | |
642 | ||
643 | /* decide next interface state */ | |
644 | if (if_is_pointopoint (oi->interface)) | |
645 | ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi); | |
646 | else if (oi->priority == 0) | |
647 | ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi); | |
648 | else | |
718e3744 | 649 | { |
508e53e2 | 650 | ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi); |
651 | thread_add_timer (master, wait_timer, oi, oi->dead_interval); | |
718e3744 | 652 | } |
508e53e2 | 653 | |
654 | return 0; | |
718e3744 | 655 | } |
656 | ||
657 | int | |
508e53e2 | 658 | wait_timer (struct thread *thread) |
718e3744 | 659 | { |
508e53e2 | 660 | struct ospf6_interface *oi; |
718e3744 | 661 | |
508e53e2 | 662 | oi = (struct ospf6_interface *) THREAD_ARG (thread); |
663 | assert (oi && oi->interface); | |
718e3744 | 664 | |
508e53e2 | 665 | if (IS_OSPF6_DEBUG_INTERFACE) |
666 | zlog_info ("Interface Event %s: [WaitTimer]", | |
667 | oi->interface->name); | |
718e3744 | 668 | |
508e53e2 | 669 | if (oi->state == OSPF6_INTERFACE_WAITING) |
670 | ospf6_interface_state_change (dr_election (oi), oi); | |
718e3744 | 671 | |
508e53e2 | 672 | return 0; |
718e3744 | 673 | } |
674 | ||
508e53e2 | 675 | int |
676 | backup_seen (struct thread *thread) | |
677 | { | |
678 | struct ospf6_interface *oi; | |
679 | ||
680 | oi = (struct ospf6_interface *) THREAD_ARG (thread); | |
681 | assert (oi && oi->interface); | |
682 | ||
683 | if (IS_OSPF6_DEBUG_INTERFACE) | |
684 | zlog_info ("Interface Event %s: [BackupSeen]", | |
685 | oi->interface->name); | |
686 | ||
687 | if (oi->state == OSPF6_INTERFACE_WAITING) | |
688 | ospf6_interface_state_change (dr_election (oi), oi); | |
689 | ||
690 | return 0; | |
691 | } | |
692 | ||
693 | int | |
694 | neighbor_change (struct thread *thread) | |
718e3744 | 695 | { |
508e53e2 | 696 | struct ospf6_interface *oi; |
697 | ||
698 | oi = (struct ospf6_interface *) THREAD_ARG (thread); | |
699 | assert (oi && oi->interface); | |
700 | ||
701 | if (IS_OSPF6_DEBUG_INTERFACE) | |
702 | zlog_info ("Interface Event %s: [NeighborChange]", | |
703 | oi->interface->name); | |
704 | ||
705 | if (oi->state == OSPF6_INTERFACE_DROTHER || | |
706 | oi->state == OSPF6_INTERFACE_BDR || | |
707 | oi->state == OSPF6_INTERFACE_DR) | |
708 | ospf6_interface_state_change (dr_election (oi), oi); | |
709 | ||
710 | return 0; | |
718e3744 | 711 | } |
712 | ||
508e53e2 | 713 | int |
714 | loopind (struct thread *thread) | |
715 | { | |
716 | struct ospf6_interface *oi; | |
717 | ||
718 | oi = (struct ospf6_interface *) THREAD_ARG (thread); | |
719 | assert (oi && oi->interface); | |
720 | ||
721 | if (IS_OSPF6_DEBUG_INTERFACE) | |
722 | zlog_info ("Interface Event %s: [LoopInd]", | |
723 | oi->interface->name); | |
724 | ||
725 | /* XXX not yet */ | |
726 | ||
727 | return 0; | |
728 | } | |
729 | ||
730 | int | |
731 | interface_down (struct thread *thread) | |
718e3744 | 732 | { |
508e53e2 | 733 | struct ospf6_interface *oi; |
734 | listnode n; | |
735 | struct ospf6_neighbor *on; | |
736 | ||
737 | oi = (struct ospf6_interface *) THREAD_ARG (thread); | |
738 | assert (oi && oi->interface); | |
739 | ||
740 | if (IS_OSPF6_DEBUG_INTERFACE) | |
741 | zlog_info ("Interface Event %s: [InterfaceDown]", | |
742 | oi->interface->name); | |
743 | ||
744 | /* Leave AllSPFRouters */ | |
745 | if (oi->state > OSPF6_INTERFACE_DOWN) | |
746 | ospf6_leave_allspfrouters (oi->interface->ifindex); | |
747 | ||
748 | ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi); | |
749 | ||
750 | for (n = listhead (oi->neighbor_list); n; nextnode (n)) | |
751 | { | |
752 | on = (struct ospf6_neighbor *) getdata (n); | |
753 | ospf6_neighbor_delete (on); | |
754 | } | |
755 | list_delete_all_node (oi->neighbor_list); | |
756 | ||
757 | return 0; | |
718e3744 | 758 | } |
759 | ||
508e53e2 | 760 | \f |
718e3744 | 761 | /* show specified interface structure */ |
762 | int | |
508e53e2 | 763 | ospf6_interface_show (struct vty *vty, struct interface *ifp) |
718e3744 | 764 | { |
508e53e2 | 765 | struct ospf6_interface *oi; |
718e3744 | 766 | struct connected *c; |
767 | struct prefix *p; | |
768 | listnode i; | |
508e53e2 | 769 | char strbuf[64], drouter[32], bdrouter[32]; |
718e3744 | 770 | char *updown[3] = {"down", "up", NULL}; |
771 | char *type; | |
508e53e2 | 772 | struct timeval res, now; |
773 | char duration[32]; | |
774 | struct ospf6_lsa *lsa; | |
718e3744 | 775 | |
776 | /* check physical interface type */ | |
508e53e2 | 777 | if (if_is_loopback (ifp)) |
718e3744 | 778 | type = "LOOPBACK"; |
508e53e2 | 779 | else if (if_is_broadcast (ifp)) |
718e3744 | 780 | type = "BROADCAST"; |
508e53e2 | 781 | else if (if_is_pointopoint (ifp)) |
718e3744 | 782 | type = "POINTOPOINT"; |
783 | else | |
784 | type = "UNKNOWN"; | |
785 | ||
786 | vty_out (vty, "%s is %s, type %s%s", | |
508e53e2 | 787 | ifp->name, updown[if_is_up (ifp)], type, |
718e3744 | 788 | VTY_NEWLINE); |
508e53e2 | 789 | vty_out (vty, " Interface ID: %d%s", ifp->ifindex, VTY_NEWLINE); |
718e3744 | 790 | |
508e53e2 | 791 | if (ifp->info == NULL) |
718e3744 | 792 | { |
793 | vty_out (vty, " OSPF not enabled on this interface%s", VTY_NEWLINE); | |
794 | return 0; | |
795 | } | |
796 | else | |
508e53e2 | 797 | oi = (struct ospf6_interface *) ifp->info; |
718e3744 | 798 | |
799 | vty_out (vty, " Internet Address:%s", VTY_NEWLINE); | |
508e53e2 | 800 | for (i = listhead (ifp->connected); i; nextnode (i)) |
718e3744 | 801 | { |
802 | c = (struct connected *)getdata (i); | |
803 | p = c->address; | |
804 | prefix2str (p, strbuf, sizeof (strbuf)); | |
805 | switch (p->family) | |
806 | { | |
807 | case AF_INET: | |
508e53e2 | 808 | vty_out (vty, " inet : %s%s", strbuf, |
718e3744 | 809 | VTY_NEWLINE); |
810 | break; | |
811 | case AF_INET6: | |
508e53e2 | 812 | vty_out (vty, " inet6: %s%s", strbuf, |
718e3744 | 813 | VTY_NEWLINE); |
814 | break; | |
815 | default: | |
508e53e2 | 816 | vty_out (vty, " ??? : %s%s", strbuf, |
718e3744 | 817 | VTY_NEWLINE); |
818 | break; | |
819 | } | |
820 | } | |
821 | ||
508e53e2 | 822 | if (oi->area) |
718e3744 | 823 | { |
508e53e2 | 824 | vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s", |
1203e1c0 | 825 | oi->instance_id, oi->ifmtu, ifp->mtu6, VTY_NEWLINE); |
508e53e2 | 826 | inet_ntop (AF_INET, &oi->area->area_id, |
718e3744 | 827 | strbuf, sizeof (strbuf)); |
508e53e2 | 828 | vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost, |
718e3744 | 829 | VTY_NEWLINE); |
718e3744 | 830 | } |
831 | else | |
832 | vty_out (vty, " Not Attached to Area%s", VTY_NEWLINE); | |
833 | ||
834 | vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s", | |
508e53e2 | 835 | ospf6_interface_state_str[oi->state], |
836 | oi->transdelay, oi->priority, | |
718e3744 | 837 | VTY_NEWLINE); |
838 | vty_out (vty, " Timer intervals configured:%s", VTY_NEWLINE); | |
839 | vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s", | |
508e53e2 | 840 | oi->hello_interval, oi->dead_interval, oi->rxmt_interval, |
718e3744 | 841 | VTY_NEWLINE); |
842 | ||
508e53e2 | 843 | inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter)); |
844 | inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter)); | |
845 | vty_out (vty, " DR: %s BDR: %s%s", drouter, bdrouter, VTY_NEWLINE); | |
718e3744 | 846 | |
847 | vty_out (vty, " Number of I/F scoped LSAs is %u%s", | |
508e53e2 | 848 | oi->lsdb->count, VTY_NEWLINE); |
718e3744 | 849 | |
850 | gettimeofday (&now, (struct timezone *) NULL); | |
718e3744 | 851 | |
508e53e2 | 852 | timerclear (&res); |
853 | if (oi->thread_send_lsupdate) | |
854 | timersub (&oi->thread_send_lsupdate->u.sands, &now, &res); | |
855 | timerstring (&res, duration, sizeof (duration)); | |
856 | vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s", | |
857 | oi->lsupdate_list->count, duration, | |
858 | (oi->thread_send_lsupdate ? "on" : "off"), | |
859 | VTY_NEWLINE); | |
860 | for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa; | |
861 | lsa = ospf6_lsdb_next (lsa)) | |
862 | vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE); | |
863 | ||
864 | timerclear (&res); | |
865 | if (oi->thread_send_lsack) | |
866 | timersub (&oi->thread_send_lsack->u.sands, &now, &res); | |
867 | timerstring (&res, duration, sizeof (duration)); | |
868 | vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s", | |
869 | oi->lsack_list->count, duration, | |
870 | (oi->thread_send_lsack ? "on" : "off"), | |
871 | VTY_NEWLINE); | |
872 | for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa; | |
873 | lsa = ospf6_lsdb_next (lsa)) | |
874 | vty_out (vty, " %s%s", lsa->name, VTY_NEWLINE); | |
718e3744 | 875 | |
508e53e2 | 876 | return 0; |
718e3744 | 877 | } |
878 | ||
879 | /* show interface */ | |
880 | DEFUN (show_ipv6_ospf6_interface, | |
881 | show_ipv6_ospf6_interface_ifname_cmd, | |
882 | "show ipv6 ospf6 interface IFNAME", | |
883 | SHOW_STR | |
884 | IP6_STR | |
885 | OSPF6_STR | |
886 | INTERFACE_STR | |
887 | IFNAME_STR | |
888 | ) | |
889 | { | |
890 | struct interface *ifp; | |
891 | listnode i; | |
892 | ||
893 | if (argc) | |
894 | { | |
895 | ifp = if_lookup_by_name (argv[0]); | |
508e53e2 | 896 | if (ifp == NULL) |
718e3744 | 897 | { |
898 | vty_out (vty, "No such Interface: %s%s", argv[0], | |
508e53e2 | 899 | VTY_NEWLINE); |
718e3744 | 900 | return CMD_WARNING; |
901 | } | |
902 | ospf6_interface_show (vty, ifp); | |
903 | } | |
904 | else | |
905 | { | |
906 | for (i = listhead (iflist); i; nextnode (i)) | |
907 | { | |
508e53e2 | 908 | ifp = (struct interface *) getdata (i); |
718e3744 | 909 | ospf6_interface_show (vty, ifp); |
910 | } | |
911 | } | |
508e53e2 | 912 | |
718e3744 | 913 | return CMD_SUCCESS; |
914 | } | |
915 | ||
916 | ALIAS (show_ipv6_ospf6_interface, | |
917 | show_ipv6_ospf6_interface_cmd, | |
918 | "show ipv6 ospf6 interface", | |
919 | SHOW_STR | |
920 | IP6_STR | |
921 | OSPF6_STR | |
922 | INTERFACE_STR | |
508e53e2 | 923 | ); |
924 | ||
925 | DEFUN (show_ipv6_ospf6_interface_ifname_prefix, | |
926 | show_ipv6_ospf6_interface_ifname_prefix_cmd, | |
927 | "show ipv6 ospf6 interface IFNAME prefix", | |
928 | SHOW_STR | |
929 | IP6_STR | |
930 | OSPF6_STR | |
931 | INTERFACE_STR | |
932 | IFNAME_STR | |
933 | "Display connected prefixes to advertise\n" | |
718e3744 | 934 | ) |
508e53e2 | 935 | { |
936 | struct interface *ifp; | |
937 | struct ospf6_interface *oi; | |
938 | ||
939 | ifp = if_lookup_by_name (argv[0]); | |
940 | if (ifp == NULL) | |
941 | { | |
942 | vty_out (vty, "No such Interface: %s%s", argv[0], VTY_NEWLINE); | |
943 | return CMD_WARNING; | |
944 | } | |
945 | ||
946 | oi = ifp->info; | |
947 | if (oi == NULL) | |
948 | { | |
949 | vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VTY_NEWLINE); | |
950 | return CMD_WARNING; | |
951 | } | |
952 | ||
953 | argc--; | |
954 | argv++; | |
955 | ospf6_route_table_show (vty, argc, argv, oi->route_connected); | |
956 | ||
957 | return CMD_SUCCESS; | |
958 | } | |
959 | ||
960 | ALIAS (show_ipv6_ospf6_interface_ifname_prefix, | |
961 | show_ipv6_ospf6_interface_ifname_prefix_detail_cmd, | |
962 | "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)", | |
963 | SHOW_STR | |
964 | IP6_STR | |
965 | OSPF6_STR | |
966 | INTERFACE_STR | |
967 | IFNAME_STR | |
968 | "Display connected prefixes to advertise\n" | |
969 | OSPF6_ROUTE_ADDRESS_STR | |
970 | OSPF6_ROUTE_PREFIX_STR | |
971 | "Dispaly details of the prefixes\n" | |
972 | ); | |
973 | ||
974 | ALIAS (show_ipv6_ospf6_interface_ifname_prefix, | |
975 | show_ipv6_ospf6_interface_ifname_prefix_match_cmd, | |
976 | "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)", | |
977 | SHOW_STR | |
978 | IP6_STR | |
979 | OSPF6_STR | |
980 | INTERFACE_STR | |
981 | IFNAME_STR | |
982 | "Display connected prefixes to advertise\n" | |
983 | OSPF6_ROUTE_PREFIX_STR | |
984 | OSPF6_ROUTE_MATCH_STR | |
985 | "Dispaly details of the prefixes\n" | |
986 | ); | |
987 | ||
988 | DEFUN (show_ipv6_ospf6_interface_prefix, | |
989 | show_ipv6_ospf6_interface_prefix_cmd, | |
990 | "show ipv6 ospf6 interface prefix", | |
991 | SHOW_STR | |
992 | IP6_STR | |
993 | OSPF6_STR | |
994 | INTERFACE_STR | |
995 | "Display connected prefixes to advertise\n" | |
996 | ) | |
997 | { | |
998 | listnode i; | |
999 | struct ospf6_interface *oi; | |
1000 | struct interface *ifp; | |
1001 | ||
1002 | for (i = listhead (iflist); i; nextnode (i)) | |
1003 | { | |
1004 | ifp = (struct interface *) getdata (i); | |
1005 | oi = (struct ospf6_interface *) ifp->info; | |
1006 | if (oi == NULL) | |
1007 | continue; | |
1008 | ||
1009 | ospf6_route_table_show (vty, argc, argv, oi->route_connected); | |
1010 | } | |
1011 | ||
1012 | return CMD_SUCCESS; | |
1013 | } | |
1014 | ||
1015 | ALIAS (show_ipv6_ospf6_interface_prefix, | |
1016 | show_ipv6_ospf6_interface_prefix_detail_cmd, | |
1017 | "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)", | |
1018 | SHOW_STR | |
1019 | IP6_STR | |
1020 | OSPF6_STR | |
1021 | INTERFACE_STR | |
1022 | "Display connected prefixes to advertise\n" | |
1023 | OSPF6_ROUTE_ADDRESS_STR | |
1024 | OSPF6_ROUTE_PREFIX_STR | |
1025 | "Dispaly details of the prefixes\n" | |
1026 | ); | |
1027 | ||
1028 | ALIAS (show_ipv6_ospf6_interface_prefix, | |
1029 | show_ipv6_ospf6_interface_prefix_match_cmd, | |
1030 | "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)", | |
1031 | SHOW_STR | |
1032 | IP6_STR | |
1033 | OSPF6_STR | |
1034 | INTERFACE_STR | |
1035 | "Display connected prefixes to advertise\n" | |
1036 | OSPF6_ROUTE_PREFIX_STR | |
1037 | OSPF6_ROUTE_MATCH_STR | |
1038 | "Dispaly details of the prefixes\n" | |
1039 | ); | |
1040 | ||
718e3744 | 1041 | |
1042 | /* interface variable set command */ | |
b596c71e | 1043 | DEFUN (ipv6_ospf6_ifmtu, |
1044 | ipv6_ospf6_ifmtu_cmd, | |
1045 | "ipv6 ospf6 ifmtu <1-65535>", | |
1046 | IP6_STR | |
1047 | OSPF6_STR | |
1048 | "Interface MTU\n" | |
1049 | "OSPFv3 Interface MTU\n" | |
1050 | ) | |
1051 | { | |
1052 | struct ospf6_interface *oi; | |
1053 | struct interface *ifp; | |
1054 | int ifmtu, iobuflen; | |
1055 | listnode node; | |
1056 | struct ospf6_neighbor *on; | |
1057 | ||
1058 | ifp = (struct interface *) vty->index; | |
1059 | assert (ifp); | |
1060 | ||
1061 | oi = (struct ospf6_interface *) ifp->info; | |
1062 | if (oi == NULL) | |
1063 | oi = ospf6_interface_create (ifp); | |
1064 | assert (oi); | |
1065 | ||
1066 | ifmtu = strtol (argv[0], NULL, 10); | |
1067 | ||
1068 | if (oi->ifmtu == ifmtu) | |
1069 | return CMD_SUCCESS; | |
1070 | ||
1203e1c0 | 1071 | if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu) |
b596c71e | 1072 | { |
1073 | vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s", | |
1203e1c0 | 1074 | ifp->name, ifp->mtu6, VTY_NEWLINE); |
b596c71e | 1075 | return CMD_WARNING; |
1076 | } | |
1077 | ||
1078 | if (oi->ifmtu < ifmtu) | |
1079 | { | |
1080 | iobuflen = ospf6_iobuf_size (ifmtu); | |
1081 | if (iobuflen < ifmtu) | |
1082 | { | |
1083 | vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s", | |
1084 | ifp->name, iobuflen, VTY_NEWLINE); | |
1085 | oi->ifmtu = iobuflen; | |
1086 | } | |
1087 | else | |
1088 | oi->ifmtu = ifmtu; | |
1089 | } | |
1090 | else | |
1091 | oi->ifmtu = ifmtu; | |
1092 | ||
1093 | /* re-establish adjacencies */ | |
1094 | for (node = listhead (oi->neighbor_list); node; nextnode (node)) | |
1095 | { | |
1096 | on = (struct ospf6_neighbor *) getdata (node); | |
1097 | THREAD_OFF (on->inactivity_timer); | |
1098 | thread_execute (master, inactivity_timer, on, 0); | |
1099 | } | |
1100 | ||
1101 | return CMD_SUCCESS; | |
1102 | } | |
1103 | ||
718e3744 | 1104 | DEFUN (ipv6_ospf6_cost, |
1105 | ipv6_ospf6_cost_cmd, | |
508e53e2 | 1106 | "ipv6 ospf6 cost <1-65535>", |
718e3744 | 1107 | IP6_STR |
1108 | OSPF6_STR | |
1109 | "Interface cost\n" | |
508e53e2 | 1110 | "Outgoing metric of this interface\n" |
718e3744 | 1111 | ) |
1112 | { | |
508e53e2 | 1113 | struct ospf6_interface *oi; |
718e3744 | 1114 | struct interface *ifp; |
1115 | ||
508e53e2 | 1116 | ifp = (struct interface *) vty->index; |
718e3744 | 1117 | assert (ifp); |
1118 | ||
508e53e2 | 1119 | oi = (struct ospf6_interface *) ifp->info; |
1120 | if (oi == NULL) | |
1121 | oi = ospf6_interface_create (ifp); | |
1122 | assert (oi); | |
718e3744 | 1123 | |
508e53e2 | 1124 | if (oi->cost == strtol (argv[0], NULL, 10)) |
718e3744 | 1125 | return CMD_SUCCESS; |
1126 | ||
508e53e2 | 1127 | oi->cost = strtol (argv[0], NULL, 10); |
718e3744 | 1128 | |
508e53e2 | 1129 | /* update cost held in route_connected list in ospf6_interface */ |
1130 | ospf6_interface_connected_route_update (oi->interface); | |
718e3744 | 1131 | |
508e53e2 | 1132 | /* execute LSA hooks */ |
1133 | if (oi->area) | |
1134 | { | |
1135 | OSPF6_LINK_LSA_SCHEDULE (oi); | |
1136 | OSPF6_ROUTER_LSA_SCHEDULE (oi->area); | |
1137 | OSPF6_NETWORK_LSA_SCHEDULE (oi); | |
1138 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
1139 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); | |
1140 | } | |
718e3744 | 1141 | |
1142 | return CMD_SUCCESS; | |
1143 | } | |
1144 | ||
718e3744 | 1145 | DEFUN (ipv6_ospf6_hellointerval, |
1146 | ipv6_ospf6_hellointerval_cmd, | |
508e53e2 | 1147 | "ipv6 ospf6 hello-interval <1-65535>", |
718e3744 | 1148 | IP6_STR |
1149 | OSPF6_STR | |
508e53e2 | 1150 | "Interval time of Hello packets\n" |
718e3744 | 1151 | SECONDS_STR |
1152 | ) | |
1153 | { | |
508e53e2 | 1154 | struct ospf6_interface *oi; |
718e3744 | 1155 | struct interface *ifp; |
1156 | ||
1157 | ifp = (struct interface *) vty->index; | |
1158 | assert (ifp); | |
718e3744 | 1159 | |
508e53e2 | 1160 | oi = (struct ospf6_interface *) ifp->info; |
1161 | if (oi == NULL) | |
1162 | oi = ospf6_interface_create (ifp); | |
1163 | assert (oi); | |
1164 | ||
1165 | oi->hello_interval = strtol (argv[0], NULL, 10); | |
718e3744 | 1166 | return CMD_SUCCESS; |
1167 | } | |
1168 | ||
1169 | /* interface variable set command */ | |
1170 | DEFUN (ipv6_ospf6_deadinterval, | |
1171 | ipv6_ospf6_deadinterval_cmd, | |
508e53e2 | 1172 | "ipv6 ospf6 dead-interval <1-65535>", |
718e3744 | 1173 | IP6_STR |
1174 | OSPF6_STR | |
508e53e2 | 1175 | "Interval time after which a neighbor is declared down\n" |
718e3744 | 1176 | SECONDS_STR |
1177 | ) | |
1178 | { | |
508e53e2 | 1179 | struct ospf6_interface *oi; |
718e3744 | 1180 | struct interface *ifp; |
1181 | ||
1182 | ifp = (struct interface *) vty->index; | |
1183 | assert (ifp); | |
718e3744 | 1184 | |
508e53e2 | 1185 | oi = (struct ospf6_interface *) ifp->info; |
1186 | if (oi == NULL) | |
1187 | oi = ospf6_interface_create (ifp); | |
1188 | assert (oi); | |
1189 | ||
1190 | oi->dead_interval = strtol (argv[0], NULL, 10); | |
718e3744 | 1191 | return CMD_SUCCESS; |
1192 | } | |
1193 | ||
1194 | /* interface variable set command */ | |
1195 | DEFUN (ipv6_ospf6_transmitdelay, | |
1196 | ipv6_ospf6_transmitdelay_cmd, | |
508e53e2 | 1197 | "ipv6 ospf6 transmit-delay <1-3600>", |
718e3744 | 1198 | IP6_STR |
1199 | OSPF6_STR | |
508e53e2 | 1200 | "Transmit delay of this interface\n" |
718e3744 | 1201 | SECONDS_STR |
1202 | ) | |
1203 | { | |
508e53e2 | 1204 | struct ospf6_interface *oi; |
718e3744 | 1205 | struct interface *ifp; |
1206 | ||
1207 | ifp = (struct interface *) vty->index; | |
1208 | assert (ifp); | |
718e3744 | 1209 | |
508e53e2 | 1210 | oi = (struct ospf6_interface *) ifp->info; |
1211 | if (oi == NULL) | |
1212 | oi = ospf6_interface_create (ifp); | |
1213 | assert (oi); | |
1214 | ||
1215 | oi->transdelay = strtol (argv[0], NULL, 10); | |
718e3744 | 1216 | return CMD_SUCCESS; |
1217 | } | |
1218 | ||
1219 | /* interface variable set command */ | |
1220 | DEFUN (ipv6_ospf6_retransmitinterval, | |
1221 | ipv6_ospf6_retransmitinterval_cmd, | |
508e53e2 | 1222 | "ipv6 ospf6 retransmit-interval <1-65535>", |
718e3744 | 1223 | IP6_STR |
1224 | OSPF6_STR | |
1225 | "Time between retransmitting lost link state advertisements\n" | |
1226 | SECONDS_STR | |
1227 | ) | |
1228 | { | |
508e53e2 | 1229 | struct ospf6_interface *oi; |
718e3744 | 1230 | struct interface *ifp; |
1231 | ||
1232 | ifp = (struct interface *) vty->index; | |
1233 | assert (ifp); | |
718e3744 | 1234 | |
508e53e2 | 1235 | oi = (struct ospf6_interface *) ifp->info; |
1236 | if (oi == NULL) | |
1237 | oi = ospf6_interface_create (ifp); | |
1238 | assert (oi); | |
1239 | ||
1240 | oi->rxmt_interval = strtol (argv[0], NULL, 10); | |
718e3744 | 1241 | return CMD_SUCCESS; |
1242 | } | |
1243 | ||
1244 | /* interface variable set command */ | |
1245 | DEFUN (ipv6_ospf6_priority, | |
1246 | ipv6_ospf6_priority_cmd, | |
508e53e2 | 1247 | "ipv6 ospf6 priority <0-255>", |
718e3744 | 1248 | IP6_STR |
1249 | OSPF6_STR | |
1250 | "Router priority\n" | |
508e53e2 | 1251 | "Priority value\n" |
718e3744 | 1252 | ) |
1253 | { | |
508e53e2 | 1254 | struct ospf6_interface *oi; |
718e3744 | 1255 | struct interface *ifp; |
1256 | ||
1257 | ifp = (struct interface *) vty->index; | |
1258 | assert (ifp); | |
718e3744 | 1259 | |
508e53e2 | 1260 | oi = (struct ospf6_interface *) ifp->info; |
1261 | if (oi == NULL) | |
1262 | oi = ospf6_interface_create (ifp); | |
1263 | assert (oi); | |
1264 | ||
1265 | oi->priority = strtol (argv[0], NULL, 10); | |
718e3744 | 1266 | |
508e53e2 | 1267 | if (oi->area) |
1268 | ospf6_interface_state_change (dr_election (oi), oi); | |
718e3744 | 1269 | |
1270 | return CMD_SUCCESS; | |
1271 | } | |
1272 | ||
1273 | DEFUN (ipv6_ospf6_instance, | |
1274 | ipv6_ospf6_instance_cmd, | |
508e53e2 | 1275 | "ipv6 ospf6 instance-id <0-255>", |
718e3744 | 1276 | IP6_STR |
1277 | OSPF6_STR | |
508e53e2 | 1278 | "Instance ID for this interface\n" |
1279 | "Instance ID value\n" | |
718e3744 | 1280 | ) |
1281 | { | |
508e53e2 | 1282 | struct ospf6_interface *oi; |
718e3744 | 1283 | struct interface *ifp; |
1284 | ||
1285 | ifp = (struct interface *)vty->index; | |
1286 | assert (ifp); | |
1287 | ||
508e53e2 | 1288 | oi = (struct ospf6_interface *)ifp->info; |
1289 | if (oi == NULL) | |
1290 | oi = ospf6_interface_create (ifp); | |
1291 | assert (oi); | |
718e3744 | 1292 | |
508e53e2 | 1293 | oi->instance_id = strtol (argv[0], NULL, 10); |
718e3744 | 1294 | return CMD_SUCCESS; |
1295 | } | |
1296 | ||
1297 | DEFUN (ipv6_ospf6_passive, | |
1298 | ipv6_ospf6_passive_cmd, | |
1299 | "ipv6 ospf6 passive", | |
1300 | IP6_STR | |
1301 | OSPF6_STR | |
508e53e2 | 1302 | "passive interface, No adjacency will be formed on this interface\n" |
718e3744 | 1303 | ) |
1304 | { | |
508e53e2 | 1305 | struct ospf6_interface *oi; |
718e3744 | 1306 | struct interface *ifp; |
1307 | listnode node; | |
508e53e2 | 1308 | struct ospf6_neighbor *on; |
718e3744 | 1309 | |
1310 | ifp = (struct interface *) vty->index; | |
1311 | assert (ifp); | |
718e3744 | 1312 | |
508e53e2 | 1313 | oi = (struct ospf6_interface *) ifp->info; |
1314 | if (oi == NULL) | |
1315 | oi = ospf6_interface_create (ifp); | |
1316 | assert (oi); | |
718e3744 | 1317 | |
508e53e2 | 1318 | SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE); |
1319 | THREAD_OFF (oi->thread_send_hello); | |
1320 | ||
1321 | for (node = listhead (oi->neighbor_list); node; nextnode (node)) | |
718e3744 | 1322 | { |
508e53e2 | 1323 | on = (struct ospf6_neighbor *) getdata (node); |
1324 | THREAD_OFF (on->inactivity_timer); | |
1325 | thread_execute (master, inactivity_timer, on, 0); | |
718e3744 | 1326 | } |
1327 | ||
1328 | return CMD_SUCCESS; | |
1329 | } | |
1330 | ||
1331 | DEFUN (no_ipv6_ospf6_passive, | |
1332 | no_ipv6_ospf6_passive_cmd, | |
1333 | "no ipv6 ospf6 passive", | |
1334 | NO_STR | |
1335 | IP6_STR | |
1336 | OSPF6_STR | |
1337 | "passive interface: No Adjacency will be formed on this I/F\n" | |
1338 | ) | |
1339 | { | |
508e53e2 | 1340 | struct ospf6_interface *oi; |
718e3744 | 1341 | struct interface *ifp; |
1342 | ||
1343 | ifp = (struct interface *) vty->index; | |
1344 | assert (ifp); | |
718e3744 | 1345 | |
508e53e2 | 1346 | oi = (struct ospf6_interface *) ifp->info; |
1347 | if (oi == NULL) | |
1348 | oi = ospf6_interface_create (ifp); | |
1349 | assert (oi); | |
718e3744 | 1350 | |
508e53e2 | 1351 | UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE); |
1352 | THREAD_OFF (oi->thread_send_hello); | |
1353 | oi->thread_send_hello = | |
1354 | thread_add_event (master, ospf6_hello_send, oi, 0); | |
718e3744 | 1355 | |
1356 | return CMD_SUCCESS; | |
1357 | } | |
1358 | ||
1359 | DEFUN (ipv6_ospf6_advertise_prefix_list, | |
1360 | ipv6_ospf6_advertise_prefix_list_cmd, | |
1361 | "ipv6 ospf6 advertise prefix-list WORD", | |
1362 | IP6_STR | |
1363 | OSPF6_STR | |
1364 | "Advertising options\n" | |
1365 | "Filter prefix using prefix-list\n" | |
1366 | "Prefix list name\n" | |
1367 | ) | |
1368 | { | |
508e53e2 | 1369 | struct ospf6_interface *oi; |
718e3744 | 1370 | struct interface *ifp; |
1371 | ||
1372 | ifp = (struct interface *) vty->index; | |
1373 | assert (ifp); | |
718e3744 | 1374 | |
508e53e2 | 1375 | oi = (struct ospf6_interface *) ifp->info; |
1376 | if (oi == NULL) | |
1377 | oi = ospf6_interface_create (ifp); | |
1378 | assert (oi); | |
718e3744 | 1379 | |
508e53e2 | 1380 | if (oi->plist_name) |
1381 | XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name); | |
1382 | oi->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]); | |
718e3744 | 1383 | |
508e53e2 | 1384 | ospf6_interface_connected_route_update (oi->interface); |
1385 | OSPF6_LINK_LSA_SCHEDULE (oi); | |
1386 | if (oi->state == OSPF6_INTERFACE_DR) | |
1387 | { | |
1388 | OSPF6_NETWORK_LSA_SCHEDULE (oi); | |
1389 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
1390 | } | |
1391 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); | |
718e3744 | 1392 | |
1393 | return CMD_SUCCESS; | |
1394 | } | |
1395 | ||
1396 | DEFUN (no_ipv6_ospf6_advertise_prefix_list, | |
1397 | no_ipv6_ospf6_advertise_prefix_list_cmd, | |
1398 | "no ipv6 ospf6 advertise prefix-list", | |
1399 | NO_STR | |
1400 | IP6_STR | |
1401 | OSPF6_STR | |
1402 | "Advertising options\n" | |
1403 | "Filter prefix using prefix-list\n" | |
1404 | ) | |
1405 | { | |
508e53e2 | 1406 | struct ospf6_interface *oi; |
718e3744 | 1407 | struct interface *ifp; |
1408 | ||
1409 | ifp = (struct interface *) vty->index; | |
1410 | assert (ifp); | |
718e3744 | 1411 | |
508e53e2 | 1412 | oi = (struct ospf6_interface *) ifp->info; |
1413 | if (oi == NULL) | |
1414 | oi = ospf6_interface_create (ifp); | |
1415 | assert (oi); | |
1416 | ||
1417 | if (oi->plist_name) | |
718e3744 | 1418 | { |
508e53e2 | 1419 | XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name); |
1420 | oi->plist_name = NULL; | |
718e3744 | 1421 | } |
1422 | ||
508e53e2 | 1423 | ospf6_interface_connected_route_update (oi->interface); |
1424 | OSPF6_LINK_LSA_SCHEDULE (oi); | |
1425 | if (oi->state == OSPF6_INTERFACE_DR) | |
1426 | { | |
1427 | OSPF6_NETWORK_LSA_SCHEDULE (oi); | |
1428 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi); | |
1429 | } | |
1430 | OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area); | |
718e3744 | 1431 | |
1432 | return CMD_SUCCESS; | |
1433 | } | |
1434 | ||
1435 | int | |
508e53e2 | 1436 | config_write_ospf6_interface (struct vty *vty) |
718e3744 | 1437 | { |
1438 | listnode i; | |
508e53e2 | 1439 | struct ospf6_interface *oi; |
718e3744 | 1440 | struct interface *ifp; |
1441 | ||
1442 | for (i = listhead (iflist); i; nextnode (i)) | |
1443 | { | |
1444 | ifp = (struct interface *) getdata (i); | |
508e53e2 | 1445 | oi = (struct ospf6_interface *) ifp->info; |
1446 | if (oi == NULL) | |
718e3744 | 1447 | continue; |
1448 | ||
1449 | vty_out (vty, "interface %s%s", | |
508e53e2 | 1450 | oi->interface->name, VTY_NEWLINE); |
1451 | ||
1452 | if (ifp->desc) | |
1453 | vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE); | |
1454 | ||
1203e1c0 | 1455 | if (ifp->mtu6 != oi->ifmtu) |
b596c71e | 1456 | vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VTY_NEWLINE); |
718e3744 | 1457 | vty_out (vty, " ipv6 ospf6 cost %d%s", |
508e53e2 | 1458 | oi->cost, VTY_NEWLINE); |
718e3744 | 1459 | vty_out (vty, " ipv6 ospf6 hello-interval %d%s", |
508e53e2 | 1460 | oi->hello_interval, VTY_NEWLINE); |
718e3744 | 1461 | vty_out (vty, " ipv6 ospf6 dead-interval %d%s", |
508e53e2 | 1462 | oi->dead_interval, VTY_NEWLINE); |
718e3744 | 1463 | vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s", |
508e53e2 | 1464 | oi->rxmt_interval, VTY_NEWLINE); |
718e3744 | 1465 | vty_out (vty, " ipv6 ospf6 priority %d%s", |
508e53e2 | 1466 | oi->priority, VTY_NEWLINE); |
718e3744 | 1467 | vty_out (vty, " ipv6 ospf6 transmit-delay %d%s", |
508e53e2 | 1468 | oi->transdelay, VTY_NEWLINE); |
718e3744 | 1469 | vty_out (vty, " ipv6 ospf6 instance-id %d%s", |
508e53e2 | 1470 | oi->instance_id, VTY_NEWLINE); |
718e3744 | 1471 | |
508e53e2 | 1472 | if (oi->plist_name) |
718e3744 | 1473 | vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s", |
508e53e2 | 1474 | oi->plist_name, VTY_NEWLINE); |
718e3744 | 1475 | |
508e53e2 | 1476 | if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE)) |
718e3744 | 1477 | vty_out (vty, " ipv6 ospf6 passive%s", VTY_NEWLINE); |
1478 | ||
1479 | vty_out (vty, "!%s", VTY_NEWLINE); | |
1480 | } | |
1481 | return 0; | |
1482 | } | |
1483 | ||
1484 | struct cmd_node interface_node = | |
1485 | { | |
1486 | INTERFACE_NODE, | |
1487 | "%s(config-if)# ", | |
1488 | }; | |
1489 | ||
1490 | void | |
1491 | ospf6_interface_init () | |
1492 | { | |
1493 | /* Install interface node. */ | |
508e53e2 | 1494 | install_node (&interface_node, config_write_ospf6_interface); |
718e3744 | 1495 | |
1496 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd); | |
508e53e2 | 1497 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); |
1498 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd); | |
1499 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd); | |
718e3744 | 1500 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); |
508e53e2 | 1501 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); |
1502 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd); | |
1503 | install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd); | |
718e3744 | 1504 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd); |
508e53e2 | 1505 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd); |
1506 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd); | |
1507 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd); | |
718e3744 | 1508 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd); |
508e53e2 | 1509 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); |
1510 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd); | |
1511 | install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd); | |
718e3744 | 1512 | |
508e53e2 | 1513 | install_element (CONFIG_NODE, &interface_cmd); |
718e3744 | 1514 | install_default (INTERFACE_NODE); |
1515 | install_element (INTERFACE_NODE, &interface_desc_cmd); | |
1516 | install_element (INTERFACE_NODE, &no_interface_desc_cmd); | |
1517 | install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd); | |
b596c71e | 1518 | install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd); |
718e3744 | 1519 | install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); |
1520 | install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); | |
1521 | install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd); | |
1522 | install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); | |
1523 | install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); | |
1524 | install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd); | |
508e53e2 | 1525 | |
718e3744 | 1526 | install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd); |
1527 | install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd); | |
508e53e2 | 1528 | |
1529 | install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd); | |
1530 | install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd); | |
1531 | } | |
1532 | ||
1533 | DEFUN (debug_ospf6_interface, | |
1534 | debug_ospf6_interface_cmd, | |
1535 | "debug ospf6 interface", | |
1536 | DEBUG_STR | |
1537 | OSPF6_STR | |
1538 | "Debug OSPFv3 Interface\n" | |
1539 | ) | |
1540 | { | |
1541 | OSPF6_DEBUG_INTERFACE_ON (); | |
1542 | return CMD_SUCCESS; | |
1543 | } | |
1544 | ||
1545 | DEFUN (no_debug_ospf6_interface, | |
1546 | no_debug_ospf6_interface_cmd, | |
1547 | "no debug ospf6 interface", | |
1548 | NO_STR | |
1549 | DEBUG_STR | |
1550 | OSPF6_STR | |
1551 | "Debug OSPFv3 Interface\n" | |
1552 | ) | |
1553 | { | |
1554 | OSPF6_DEBUG_INTERFACE_ON (); | |
1555 | return CMD_SUCCESS; | |
1556 | } | |
1557 | ||
1558 | int | |
1559 | config_write_ospf6_debug_interface (struct vty *vty) | |
1560 | { | |
1561 | if (IS_OSPF6_DEBUG_INTERFACE) | |
1562 | vty_out (vty, "debug ospf6 interface%s", VTY_NEWLINE); | |
1563 | return 0; | |
1564 | } | |
1565 | ||
1566 | void | |
1567 | install_element_ospf6_debug_interface () | |
1568 | { | |
1569 | install_element (ENABLE_NODE, &debug_ospf6_interface_cmd); | |
1570 | install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd); | |
1571 | install_element (CONFIG_NODE, &debug_ospf6_interface_cmd); | |
1572 | install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd); | |
718e3744 | 1573 | } |
1574 | ||
1575 |