blob: cd78ebbcd48e2ee2f1779e81c55541b084b673c1 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * Interface function.
3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "if.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "command.h"
30#include "memory.h"
31#include "ioctl.h"
32#include "connected.h"
33#include "log.h"
34#include "zclient.h"
35
36#include "zebra/interface.h"
37#include "zebra/rtadv.h"
38#include "zebra/rib.h"
39#include "zebra/zserv.h"
40#include "zebra/redistribute.h"
41#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000042#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000043
Chris Caputob60668d2009-05-03 04:40:57 +000044#ifdef RTADV
45/* Order is intentional. Matches RFC4191. This array is also used for
46 command matching, so only modify with care. */
47const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
48#endif /* RTADV */
paul718e3742002-12-13 20:15:29 +000049
50/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000051static int
paul718e3742002-12-13 20:15:29 +000052if_zebra_new_hook (struct interface *ifp)
53{
54 struct zebra_if *zebra_if;
55
Stephen Hemminger393deb92008-08-18 14:13:29 -070056 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000057
58 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
59 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
60
61#ifdef RTADV
62 {
63 /* Set default router advertise values. */
64 struct rtadvconf *rtadv;
65
66 rtadv = &zebra_if->rtadv;
67
68 rtadv->AdvSendAdvertisements = 0;
69 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
70 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
71 rtadv->AdvIntervalTimer = 0;
72 rtadv->AdvManagedFlag = 0;
73 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000074 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000075 rtadv->AdvLinkMTU = 0;
76 rtadv->AdvReachableTime = 0;
77 rtadv->AdvRetransTimer = 0;
78 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040079 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +000080 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040081 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +000082 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +000083 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +000084
85 rtadv->AdvPrefixList = list_new ();
86 }
87#endif /* RTADV */
88
hassoeef1fe12004-10-03 18:46:08 +000089 /* Initialize installed address chains tree. */
90 zebra_if->ipv4_subnets = route_table_init ();
91
paul718e3742002-12-13 20:15:29 +000092 ifp->info = zebra_if;
93 return 0;
94}
95
96/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000097static int
paul718e3742002-12-13 20:15:29 +000098if_zebra_delete_hook (struct interface *ifp)
99{
hassoeef1fe12004-10-03 18:46:08 +0000100 struct zebra_if *zebra_if;
101
paul718e3742002-12-13 20:15:29 +0000102 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000103 {
104 zebra_if = ifp->info;
105
106 /* Free installed address chains tree. */
107 if (zebra_if->ipv4_subnets)
108 route_table_finish (zebra_if->ipv4_subnets);
109
110 XFREE (MTYPE_TMP, zebra_if);
111 }
112
113 return 0;
114}
115
116/* Tie an interface address to its derived subnet list of addresses. */
117int
118if_subnet_add (struct interface *ifp, struct connected *ifc)
119{
120 struct route_node *rn;
121 struct zebra_if *zebra_if;
122 struct prefix cp;
123 struct list *addr_list;
124
125 assert (ifp && ifp->info && ifc);
126 zebra_if = ifp->info;
127
128 /* Get address derived subnet node and associated address list, while marking
129 address secondary attribute appropriately. */
130 cp = *ifc->address;
131 apply_mask (&cp);
132 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
133
134 if ((addr_list = rn->info))
135 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
136 else
137 {
138 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
139 rn->info = addr_list = list_new ();
140 route_lock_node (rn);
141 }
142
143 /* Tie address at the tail of address list. */
144 listnode_add (addr_list, ifc);
145
146 /* Return list element count. */
147 return (addr_list->count);
148}
149
150/* Untie an interface address from its derived subnet list of addresses. */
151int
152if_subnet_delete (struct interface *ifp, struct connected *ifc)
153{
154 struct route_node *rn;
155 struct zebra_if *zebra_if;
156 struct list *addr_list;
157
158 assert (ifp && ifp->info && ifc);
159 zebra_if = ifp->info;
160
161 /* Get address derived subnet node. */
162 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
163 if (! (rn && rn->info))
Christian Franke9db047f2013-01-24 14:04:44 +0000164 {
165 zlog_warn("Trying to remove an address from an unknown subnet."
166 " (please report this bug)");
167 return -1;
168 }
hassoeef1fe12004-10-03 18:46:08 +0000169 route_unlock_node (rn);
170
171 /* Untie address from subnet's address list. */
172 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000173
174 /* Deleting an address that is not registered is a bug.
175 * In any case, we shouldn't decrement the lock counter if the address
176 * is unknown. */
177 if (!listnode_lookup(addr_list, ifc))
178 {
179 zlog_warn("Trying to remove an address from a subnet where it is not"
180 " currently registered. (please report this bug)");
181 return -1;
182 }
183
hassoeef1fe12004-10-03 18:46:08 +0000184 listnode_delete (addr_list, ifc);
185 route_unlock_node (rn);
186
187 /* Return list element count, if not empty. */
188 if (addr_list->count)
189 {
190 /* If deleted address is primary, mark subsequent one as such and distribute. */
191 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
192 {
paul1eb8ef22005-04-07 07:30:20 +0000193 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000194 zebra_interface_address_delete_update (ifp, ifc);
195 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
196 zebra_interface_address_add_update (ifp, ifc);
197 }
198
199 return addr_list->count;
200 }
201
202 /* Otherwise, free list and route node. */
203 list_free (addr_list);
204 rn->info = NULL;
205 route_unlock_node (rn);
206
paul718e3742002-12-13 20:15:29 +0000207 return 0;
208}
209
paul5c78b3d2006-01-25 04:31:40 +0000210/* if_flags_mangle: A place for hacks that require mangling
211 * or tweaking the interface flags.
212 *
213 * ******************** Solaris flags hacks **************************
214 *
215 * Solaris IFF_UP flag reflects only the primary interface as the
216 * routing socket only sends IFINFO for the primary interface. Hence
217 * ~IFF_UP does not per se imply all the logical interfaces are also
218 * down - which we only know of as addresses. Instead we must determine
219 * whether the interface really is up or not according to how many
220 * addresses are still attached. (Solaris always sends RTM_DELADDR if
221 * an interface, logical or not, goes ~IFF_UP).
222 *
223 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
224 * are addresses left in struct connected, not just the actual underlying
225 * IFF_UP flag.
226 *
227 * We must hence remember the real state of IFF_UP, which we do in
228 * struct zebra_if.primary_state.
229 *
230 * Setting IFF_UP within zebra to administratively shutdown the
231 * interface will affect only the primary interface/address on Solaris.
232 ************************End Solaris flags hacks ***********************
233 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100234static void
paul5c78b3d2006-01-25 04:31:40 +0000235if_flags_mangle (struct interface *ifp, uint64_t *newflags)
236{
237#ifdef SUNOS_5
238 struct zebra_if *zif = ifp->info;
239
240 zif->primary_state = *newflags & (IFF_UP & 0xff);
241
242 if (CHECK_FLAG (zif->primary_state, IFF_UP)
243 || listcount(ifp->connected) > 0)
244 SET_FLAG (*newflags, IFF_UP);
245 else
246 UNSET_FLAG (*newflags, IFF_UP);
247#endif /* SUNOS_5 */
248}
249
250/* Update the flags field of the ifp with the new flag set provided.
251 * Take whatever actions are required for any changes in flags we care
252 * about.
253 *
254 * newflags should be the raw value, as obtained from the OS.
255 */
256void
257if_flags_update (struct interface *ifp, uint64_t newflags)
258{
259 if_flags_mangle (ifp, &newflags);
260
261 if (if_is_operative (ifp))
262 {
263 /* operative -> inoperative? */
264 ifp->flags = newflags;
265 if (!if_is_operative (ifp))
266 if_down (ifp);
267 }
268 else
269 {
270 /* inoperative -> operative? */
271 ifp->flags = newflags;
272 if (if_is_operative (ifp))
273 if_up (ifp);
274 }
275}
276
paul718e3742002-12-13 20:15:29 +0000277/* Wake up configured address if it is not in current kernel
278 address. */
paula1ac18c2005-06-28 17:17:12 +0000279static void
paul718e3742002-12-13 20:15:29 +0000280if_addr_wakeup (struct interface *ifp)
281{
paul1eb8ef22005-04-07 07:30:20 +0000282 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000283 struct connected *ifc;
284 struct prefix *p;
285 int ret;
286
paul1eb8ef22005-04-07 07:30:20 +0000287 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000288 {
paul718e3742002-12-13 20:15:29 +0000289 p = ifc->address;
290
291 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
292 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
293 {
294 /* Address check. */
295 if (p->family == AF_INET)
296 {
297 if (! if_is_up (ifp))
298 {
paul0752ef02005-11-03 12:35:21 +0000299 /* XXX: WTF is it trying to set flags here?
300 * caller has just gotten a new interface, has been
301 * handed the flags already. This code has no business
302 * trying to override administrative status of the interface.
303 * The only call path to here which doesn't originate from
304 * kernel event is irdp - what on earth is it trying to do?
305 *
306 * further RUNNING is not a settable flag on any system
307 * I (paulj) am aware of.
308 */
paul718e3742002-12-13 20:15:29 +0000309 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
310 if_refresh (ifp);
311 }
312
313 ret = if_set_prefix (ifp, ifc);
314 if (ret < 0)
315 {
316 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000317 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000318 continue;
319 }
hassoeef1fe12004-10-03 18:46:08 +0000320
321 /* Add to subnet chain list. */
322 if_subnet_add (ifp, ifc);
323
paul718e3742002-12-13 20:15:29 +0000324 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
325
326 zebra_interface_address_add_update (ifp, ifc);
327
paul2e3b2e42002-12-13 21:03:13 +0000328 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000329 connected_up_ipv4 (ifp, ifc);
330 }
331#ifdef HAVE_IPV6
332 if (p->family == AF_INET6)
333 {
334 if (! if_is_up (ifp))
335 {
paul0752ef02005-11-03 12:35:21 +0000336 /* XXX: See long comment above */
paul718e3742002-12-13 20:15:29 +0000337 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
338 if_refresh (ifp);
339 }
340
341 ret = if_prefix_add_ipv6 (ifp, ifc);
342 if (ret < 0)
343 {
344 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000345 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000346 continue;
347 }
348 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
349
350 zebra_interface_address_add_update (ifp, ifc);
351
paul2e3b2e42002-12-13 21:03:13 +0000352 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000353 connected_up_ipv6 (ifp, ifc);
354 }
355#endif /* HAVE_IPV6 */
356 }
357 }
358}
359
360/* Handle interface addition */
361void
362if_add_update (struct interface *ifp)
363{
paul48b33aa2002-12-13 20:52:52 +0000364 struct zebra_if *if_data;
365
366 if_data = ifp->info;
367 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
368 if_set_flags (ifp, IFF_MULTICAST);
369 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
370 if_unset_flags (ifp, IFF_MULTICAST);
371
paul718e3742002-12-13 20:15:29 +0000372 zebra_interface_add_update (ifp);
373
374 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
375 {
376 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
377
378 if_addr_wakeup (ifp);
379
380 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000381 zlog_debug ("interface %s index %d becomes active.",
382 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000383 }
384 else
385 {
386 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000387 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000388 }
389}
390
paul6eb88272005-07-29 14:36:00 +0000391/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000392void
393if_delete_update (struct interface *ifp)
394{
paul718e3742002-12-13 20:15:29 +0000395 struct connected *ifc;
396 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000397 struct route_node *rn;
398 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000399
400 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000401
402 if (if_is_up(ifp))
403 {
404 zlog_err ("interface %s index %d is still up while being deleted.",
405 ifp->name, ifp->ifindex);
406 return;
407 }
408
409 /* Mark interface as inactive */
410 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
411
412 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000413 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000414 ifp->name, ifp->ifindex);
415
416 /* Delete connected routes from the kernel. */
417 if (ifp->connected)
418 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000419 struct listnode *node;
420 struct listnode *last = NULL;
421
hassoeef1fe12004-10-03 18:46:08 +0000422 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000423 {
paul1eb8ef22005-04-07 07:30:20 +0000424 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000425 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000426
Paul Jakmabeb56332006-05-11 13:28:05 +0000427 if (p->family == AF_INET
428 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000429 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000430 struct listnode *anode;
431 struct listnode *next;
432 struct listnode *first;
433 struct list *addr_list;
434
hassoeef1fe12004-10-03 18:46:08 +0000435 route_unlock_node (rn);
436 addr_list = (struct list *) rn->info;
437
438 /* Remove addresses, secondaries first. */
439 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000440 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000441 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000442 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000443 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000444 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000445 first = NULL;
446 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000447 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000448
Paul Jakmad9a18f12007-04-10 19:30:20 +0000449 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000450 p = ifc->address;
451
452 connected_down_ipv4 (ifp, ifc);
453
454 zebra_interface_address_delete_update (ifp, ifc);
455
456 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
457
458 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000459 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000460 route_unlock_node (rn);
461
462 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000463 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
464 {
465 listnode_delete (ifp->connected, ifc);
466 connected_free (ifc);
467 }
468 else
469 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000470 }
471
472 /* Free chain list and respective route node. */
473 list_delete (addr_list);
474 rn->info = NULL;
475 route_unlock_node (rn);
476 }
paul718e3742002-12-13 20:15:29 +0000477#ifdef HAVE_IPV6
478 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000479 {
480 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000481
hassoeef1fe12004-10-03 18:46:08 +0000482 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000483
hassoeef1fe12004-10-03 18:46:08 +0000484 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
485
486 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
487 last = node;
488 else
489 {
490 listnode_delete (ifp->connected, ifc);
491 connected_free (ifc);
492 }
paul718e3742002-12-13 20:15:29 +0000493 }
hassoeef1fe12004-10-03 18:46:08 +0000494#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200495 else
496 {
497 last = node;
498 }
paul718e3742002-12-13 20:15:29 +0000499 }
500 }
501 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000502
503 /* Update ifindex after distributing the delete message. This is in
504 case any client needs to have the old value of ifindex available
505 while processing the deletion. Each client daemon is responsible
506 for setting ifindex to IFINDEX_INTERNAL after processing the
507 interface deletion message. */
508 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000509}
510
511/* Interface is up. */
512void
513if_up (struct interface *ifp)
514{
hasso52dc7ee2004-09-23 19:18:23 +0000515 struct listnode *node;
516 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000517 struct connected *ifc;
518 struct prefix *p;
519
520 /* Notify the protocol daemons. */
521 zebra_interface_up_update (ifp);
522
523 /* Install connected routes to the kernel. */
524 if (ifp->connected)
525 {
paul1eb8ef22005-04-07 07:30:20 +0000526 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000527 {
paul718e3742002-12-13 20:15:29 +0000528 p = ifc->address;
529
530 if (p->family == AF_INET)
531 connected_up_ipv4 (ifp, ifc);
532#ifdef HAVE_IPV6
533 else if (p->family == AF_INET6)
534 connected_up_ipv6 (ifp, ifc);
535#endif /* HAVE_IPV6 */
536 }
537 }
538
539 /* Examine all static routes. */
540 rib_update ();
541}
542
543/* Interface goes down. We have to manage different behavior of based
544 OS. */
545void
546if_down (struct interface *ifp)
547{
hasso52dc7ee2004-09-23 19:18:23 +0000548 struct listnode *node;
549 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000550 struct connected *ifc;
551 struct prefix *p;
552
553 /* Notify to the protocol daemons. */
554 zebra_interface_down_update (ifp);
555
556 /* Delete connected routes from the kernel. */
557 if (ifp->connected)
558 {
paul1eb8ef22005-04-07 07:30:20 +0000559 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000560 {
paul718e3742002-12-13 20:15:29 +0000561 p = ifc->address;
562
563 if (p->family == AF_INET)
564 connected_down_ipv4 (ifp, ifc);
565#ifdef HAVE_IPV6
566 else if (p->family == AF_INET6)
567 connected_down_ipv6 (ifp, ifc);
568#endif /* HAVE_IPV6 */
569 }
570 }
571
572 /* Examine all static routes which direct to the interface. */
573 rib_update ();
574}
575
576void
577if_refresh (struct interface *ifp)
578{
paul5c78b3d2006-01-25 04:31:40 +0000579 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000580}
581
paul718e3742002-12-13 20:15:29 +0000582/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000583static int
paul718e3742002-12-13 20:15:29 +0000584prefix_vty_out (struct vty *vty, struct prefix *p)
585{
586 char str[INET6_ADDRSTRLEN];
587
588 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
589 vty_out (vty, "%s", str);
590 return strlen (str);
591}
592
593/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000594static void
paul718e3742002-12-13 20:15:29 +0000595connected_dump_vty (struct vty *vty, struct connected *connected)
596{
597 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000598
599 /* Print interface address. */
600 p = connected->address;
601 vty_out (vty, " %s ", prefix_family_str (p));
602 prefix_vty_out (vty, p);
603 vty_out (vty, "/%d", p->prefixlen);
604
605 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000606 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000607 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000608 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
609 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000610 }
611
612 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
613 vty_out (vty, " secondary");
614
615 if (connected->label)
616 vty_out (vty, " %s", connected->label);
617
618 vty_out (vty, "%s", VTY_NEWLINE);
619}
620
621#ifdef RTADV
622/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000623static void
paul718e3742002-12-13 20:15:29 +0000624nd_dump_vty (struct vty *vty, struct interface *ifp)
625{
626 struct zebra_if *zif;
627 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000628 int interval;
paul718e3742002-12-13 20:15:29 +0000629
630 zif = (struct zebra_if *) ifp->info;
631 rtadv = &zif->rtadv;
632
633 if (rtadv->AdvSendAdvertisements)
634 {
635 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
636 rtadv->AdvReachableTime, VTY_NEWLINE);
637 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
638 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000639 interval = rtadv->MaxRtrAdvInterval;
640 if (interval % 1000)
641 vty_out (vty, " ND router advertisements are sent every "
642 "%d milliseconds%s", interval,
643 VTY_NEWLINE);
644 else
645 vty_out (vty, " ND router advertisements are sent every "
646 "%d seconds%s", interval / 1000,
647 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400648 if (rtadv->AdvDefaultLifetime != -1)
649 vty_out (vty, " ND router advertisements live for %d seconds%s",
650 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
651 else
652 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
653 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000654 vty_out (vty, " ND router advertisement default router preference is "
655 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
656 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000657 if (rtadv->AdvManagedFlag)
658 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
659 VTY_NEWLINE);
660 else
661 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
662 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000663 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400664 {
vincent7cee1bb2005-03-25 13:08:53 +0000665 vty_out (vty, " ND router advertisements with "
666 "Home Agent flag bit set.%s",
667 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400668 if (rtadv->HomeAgentLifetime != -1)
669 vty_out (vty, " Home Agent lifetime is %u seconds%s",
670 rtadv->HomeAgentLifetime, VTY_NEWLINE);
671 else
672 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
673 VTY_NEWLINE);
674 vty_out (vty, " Home Agent preference is %u%s",
675 rtadv->HomeAgentPreference, VTY_NEWLINE);
676 }
vincent7cee1bb2005-03-25 13:08:53 +0000677 if (rtadv->AdvIntervalOption)
678 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
679 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000680 }
681}
682#endif /* RTADV */
683
684/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000685static void
paul718e3742002-12-13 20:15:29 +0000686if_dump_vty (struct vty *vty, struct interface *ifp)
687{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000688#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000689 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000690#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000691 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000692 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000693 struct route_node *rn;
694 struct zebra_if *zebra_if;
695
696 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000697
paul2e3b2e42002-12-13 21:03:13 +0000698 vty_out (vty, "Interface %s is ", ifp->name);
699 if (if_is_up(ifp)) {
700 vty_out (vty, "up, line protocol ");
701
702 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
703 if (if_is_running(ifp))
704 vty_out (vty, "is up%s", VTY_NEWLINE);
705 else
706 vty_out (vty, "is down%s", VTY_NEWLINE);
707 } else {
708 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
709 }
710 } else {
711 vty_out (vty, "down%s", VTY_NEWLINE);
712 }
713
paul718e3742002-12-13 20:15:29 +0000714 if (ifp->desc)
715 vty_out (vty, " Description: %s%s", ifp->desc,
716 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000717 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000718 {
ajsd2fc8892005-04-02 18:38:43 +0000719 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000720 return;
721 }
722 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
723 {
724 vty_out(vty, " index %d inactive interface%s",
725 ifp->ifindex,
726 VTY_NEWLINE);
727 return;
728 }
729
730 vty_out (vty, " index %d metric %d mtu %d ",
731 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000732#ifdef HAVE_IPV6
733 if (ifp->mtu6 != ifp->mtu)
734 vty_out (vty, "mtu6 %d ", ifp->mtu6);
735#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000736 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
737 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000738
paul718e3742002-12-13 20:15:29 +0000739 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000740#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000741 sdl = &ifp->sdl;
742 if (sdl != NULL && sdl->sdl_alen != 0)
743 {
744 int i;
745 u_char *ptr;
746
747 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000748 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
749 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000750 vty_out (vty, "%s", VTY_NEWLINE);
751 }
752#else
753 if (ifp->hw_addr_len != 0)
754 {
755 int i;
756
757 vty_out (vty, " HWaddr: ");
758 for (i = 0; i < ifp->hw_addr_len; i++)
759 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
760 vty_out (vty, "%s", VTY_NEWLINE);
761 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000762#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000763
764 /* Bandwidth in kbps */
765 if (ifp->bandwidth != 0)
766 {
767 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
768 vty_out(vty, "%s", VTY_NEWLINE);
769 }
770
hassoeef1fe12004-10-03 18:46:08 +0000771 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000772 {
hassoeef1fe12004-10-03 18:46:08 +0000773 if (! rn->info)
774 continue;
775
paul1eb8ef22005-04-07 07:30:20 +0000776 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
777 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000778 }
779
paul1eb8ef22005-04-07 07:30:20 +0000780 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000781 {
hasso39db97e2004-10-12 20:50:58 +0000782 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
783 (connected->address->family == AF_INET6))
784 connected_dump_vty (vty, connected);
785 }
786
paul718e3742002-12-13 20:15:29 +0000787#ifdef RTADV
788 nd_dump_vty (vty, ifp);
789#endif /* RTADV */
790
791#ifdef HAVE_PROC_NET_DEV
792 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000793 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
794 "%lu dropped%s",
795 ifp->stats.rx_packets, ifp->stats.rx_multicast,
796 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000797
hasso6f2c27a2005-01-18 13:44:35 +0000798 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000799 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000800 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
801 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000802 ifp->stats.rx_frame_errors, VTY_NEWLINE);
803
804 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000805 ifp->stats.rx_missed_errors, VTY_NEWLINE);
806
hasso6f2c27a2005-01-18 13:44:35 +0000807 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000808 ifp->stats.tx_packets, ifp->stats.tx_bytes,
809 ifp->stats.tx_dropped, VTY_NEWLINE);
810
hasso6f2c27a2005-01-18 13:44:35 +0000811 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
812 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000813 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
814 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000815 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000816
hasso6f2c27a2005-01-18 13:44:35 +0000817 vty_out (vty, " %lu window, %lu collisions%s",
818 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000819#endif /* HAVE_PROC_NET_DEV */
820
821#ifdef HAVE_NET_RT_IFLIST
822#if defined (__bsdi__) || defined (__NetBSD__)
823 /* Statistics print out using sysctl (). */
824 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
825 " multicast packets %qu%s",
826 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
827 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
828 VTY_NEWLINE);
829
830 vty_out (vty, " input errors %qu%s",
831 ifp->stats.ifi_ierrors, VTY_NEWLINE);
832
833 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
834 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
835 ifp->stats.ifi_omcasts, VTY_NEWLINE);
836
837 vty_out (vty, " output errors %qu%s",
838 ifp->stats.ifi_oerrors, VTY_NEWLINE);
839
840 vty_out (vty, " collisions %qu%s",
841 ifp->stats.ifi_collisions, VTY_NEWLINE);
842#else
843 /* Statistics print out using sysctl (). */
844 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
845 " multicast packets %lu%s",
846 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
847 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
848 VTY_NEWLINE);
849
850 vty_out (vty, " input errors %lu%s",
851 ifp->stats.ifi_ierrors, VTY_NEWLINE);
852
853 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
854 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
855 ifp->stats.ifi_omcasts, VTY_NEWLINE);
856
857 vty_out (vty, " output errors %lu%s",
858 ifp->stats.ifi_oerrors, VTY_NEWLINE);
859
860 vty_out (vty, " collisions %lu%s",
861 ifp->stats.ifi_collisions, VTY_NEWLINE);
862#endif /* __bsdi__ || __NetBSD__ */
863#endif /* HAVE_NET_RT_IFLIST */
864}
865
paul718e3742002-12-13 20:15:29 +0000866/* Wrapper hook point for zebra daemon so that ifindex can be set
867 * DEFUN macro not used as extract.pl HAS to ignore this
868 * See also interface_cmd in lib/if.c
869 */
870DEFUN_NOSH (zebra_interface,
871 zebra_interface_cmd,
872 "interface IFNAME",
873 "Select an interface to configure\n"
874 "Interface's name\n")
875{
876 int ret;
877 struct interface * ifp;
878
879 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000880 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
881 return ret;
paul718e3742002-12-13 20:15:29 +0000882
883 ifp = vty->index;
884
ajsd2fc8892005-04-02 18:38:43 +0000885 if (ifp->ifindex == IFINDEX_INTERNAL)
886 /* Is this really necessary? Shouldn't status be initialized to 0
887 in that case? */
888 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000889
890 return ret;
891}
892
paul718e3742002-12-13 20:15:29 +0000893struct cmd_node interface_node =
894{
895 INTERFACE_NODE,
896 "%s(config-if)# ",
897 1
898};
899
900/* Show all or specified interface to vty. */
901DEFUN (show_interface, show_interface_cmd,
902 "show interface [IFNAME]",
903 SHOW_STR
904 "Interface status and configuration\n"
905 "Inteface name\n")
906{
hasso52dc7ee2004-09-23 19:18:23 +0000907 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000908 struct interface *ifp;
909
910#ifdef HAVE_PROC_NET_DEV
911 /* If system has interface statistics via proc file system, update
912 statistics. */
913 ifstat_update_proc ();
914#endif /* HAVE_PROC_NET_DEV */
915#ifdef HAVE_NET_RT_IFLIST
916 ifstat_update_sysctl ();
917#endif /* HAVE_NET_RT_IFLIST */
918
919 /* Specified interface print. */
920 if (argc != 0)
921 {
922 ifp = if_lookup_by_name (argv[0]);
923 if (ifp == NULL)
924 {
925 vty_out (vty, "%% Can't find interface %s%s", argv[0],
926 VTY_NEWLINE);
927 return CMD_WARNING;
928 }
929 if_dump_vty (vty, ifp);
930 return CMD_SUCCESS;
931 }
932
933 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000934 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
935 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000936
937 return CMD_SUCCESS;
938}
939
hassoed9bb6d2005-03-13 19:17:21 +0000940DEFUN (show_interface_desc,
941 show_interface_desc_cmd,
942 "show interface description",
943 SHOW_STR
944 "Interface status and configuration\n"
945 "Interface description\n")
946{
947 struct listnode *node;
948 struct interface *ifp;
949
950 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000951 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000952 {
953 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000954
955 len = vty_out (vty, "%s", ifp->name);
956 vty_out (vty, "%*s", (16 - len), " ");
957
958 if (if_is_up(ifp))
959 {
960 vty_out (vty, "up ");
961 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
962 {
963 if (if_is_running(ifp))
964 vty_out (vty, "up ");
965 else
966 vty_out (vty, "down ");
967 }
968 else
969 {
970 vty_out (vty, "unknown ");
971 }
972 }
973 else
974 {
975 vty_out (vty, "down down ");
976 }
977
978 if (ifp->desc)
979 vty_out (vty, "%s", ifp->desc);
980 vty_out (vty, "%s", VTY_NEWLINE);
981 }
982 return CMD_SUCCESS;
983}
984
paul718e3742002-12-13 20:15:29 +0000985DEFUN (multicast,
986 multicast_cmd,
987 "multicast",
988 "Set multicast flag to interface\n")
989{
990 int ret;
991 struct interface *ifp;
992 struct zebra_if *if_data;
993
994 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000995 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000996 {
paul48b33aa2002-12-13 20:52:52 +0000997 ret = if_set_flags (ifp, IFF_MULTICAST);
998 if (ret < 0)
999 {
1000 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1001 return CMD_WARNING;
1002 }
1003 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001004 }
paul718e3742002-12-13 20:15:29 +00001005 if_data = ifp->info;
1006 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001007
paul718e3742002-12-13 20:15:29 +00001008 return CMD_SUCCESS;
1009}
1010
1011DEFUN (no_multicast,
1012 no_multicast_cmd,
1013 "no multicast",
1014 NO_STR
1015 "Unset multicast flag to interface\n")
1016{
1017 int ret;
1018 struct interface *ifp;
1019 struct zebra_if *if_data;
1020
1021 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001022 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001023 {
paul48b33aa2002-12-13 20:52:52 +00001024 ret = if_unset_flags (ifp, IFF_MULTICAST);
1025 if (ret < 0)
1026 {
1027 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1028 return CMD_WARNING;
1029 }
1030 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001031 }
paul718e3742002-12-13 20:15:29 +00001032 if_data = ifp->info;
1033 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1034
1035 return CMD_SUCCESS;
1036}
1037
paul2e3b2e42002-12-13 21:03:13 +00001038DEFUN (linkdetect,
1039 linkdetect_cmd,
1040 "link-detect",
1041 "Enable link detection on interface\n")
1042{
paul2e3b2e42002-12-13 21:03:13 +00001043 struct interface *ifp;
1044 int if_was_operative;
1045
1046 ifp = (struct interface *) vty->index;
1047 if_was_operative = if_is_operative(ifp);
1048 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1049
1050 /* When linkdetection is enabled, if might come down */
1051 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1052
1053 /* FIXME: Will defer status change forwarding if interface
1054 does not come down! */
1055
1056 return CMD_SUCCESS;
1057}
1058
1059
1060DEFUN (no_linkdetect,
1061 no_linkdetect_cmd,
1062 "no link-detect",
1063 NO_STR
1064 "Disable link detection on interface\n")
1065{
paul2e3b2e42002-12-13 21:03:13 +00001066 struct interface *ifp;
1067 int if_was_operative;
1068
1069 ifp = (struct interface *) vty->index;
1070 if_was_operative = if_is_operative(ifp);
1071 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1072
1073 /* Interface may come up after disabling link detection */
1074 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1075
1076 /* FIXME: see linkdetect_cmd */
1077
1078 return CMD_SUCCESS;
1079}
1080
paul718e3742002-12-13 20:15:29 +00001081DEFUN (shutdown_if,
1082 shutdown_if_cmd,
1083 "shutdown",
1084 "Shutdown the selected interface\n")
1085{
1086 int ret;
1087 struct interface *ifp;
1088 struct zebra_if *if_data;
1089
1090 ifp = (struct interface *) vty->index;
1091 ret = if_unset_flags (ifp, IFF_UP);
1092 if (ret < 0)
1093 {
1094 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1095 return CMD_WARNING;
1096 }
1097 if_refresh (ifp);
1098 if_data = ifp->info;
1099 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1100
1101 return CMD_SUCCESS;
1102}
1103
1104DEFUN (no_shutdown_if,
1105 no_shutdown_if_cmd,
1106 "no shutdown",
1107 NO_STR
1108 "Shutdown the selected interface\n")
1109{
1110 int ret;
1111 struct interface *ifp;
1112 struct zebra_if *if_data;
1113
1114 ifp = (struct interface *) vty->index;
1115 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1116 if (ret < 0)
1117 {
1118 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1119 return CMD_WARNING;
1120 }
1121 if_refresh (ifp);
1122 if_data = ifp->info;
1123 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1124
1125 return CMD_SUCCESS;
1126}
1127
1128DEFUN (bandwidth_if,
1129 bandwidth_if_cmd,
1130 "bandwidth <1-10000000>",
1131 "Set bandwidth informational parameter\n"
1132 "Bandwidth in kilobits\n")
1133{
1134 struct interface *ifp;
1135 unsigned int bandwidth;
1136
1137 ifp = (struct interface *) vty->index;
1138 bandwidth = strtol(argv[0], NULL, 10);
1139
1140 /* bandwidth range is <1-10000000> */
1141 if (bandwidth < 1 || bandwidth > 10000000)
1142 {
1143 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1144 return CMD_WARNING;
1145 }
1146
1147 ifp->bandwidth = bandwidth;
1148
1149 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001150 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001151 zebra_interface_up_update (ifp);
1152
1153 return CMD_SUCCESS;
1154}
1155
1156DEFUN (no_bandwidth_if,
1157 no_bandwidth_if_cmd,
1158 "no bandwidth",
1159 NO_STR
1160 "Set bandwidth informational parameter\n")
1161{
1162 struct interface *ifp;
1163
1164 ifp = (struct interface *) vty->index;
1165
1166 ifp->bandwidth = 0;
1167
1168 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001169 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001170 zebra_interface_up_update (ifp);
1171
1172 return CMD_SUCCESS;
1173}
1174
1175ALIAS (no_bandwidth_if,
1176 no_bandwidth_if_val_cmd,
1177 "no bandwidth <1-10000000>",
1178 NO_STR
1179 "Set bandwidth informational parameter\n"
1180 "Bandwidth in kilobits\n")
1181
paula1ac18c2005-06-28 17:17:12 +00001182static int
hasso39db97e2004-10-12 20:50:58 +00001183ip_address_install (struct vty *vty, struct interface *ifp,
1184 const char *addr_str, const char *peer_str,
1185 const char *label)
paul718e3742002-12-13 20:15:29 +00001186{
1187 struct prefix_ipv4 cp;
1188 struct connected *ifc;
1189 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001190 int ret;
1191
1192 ret = str2prefix_ipv4 (addr_str, &cp);
1193 if (ret <= 0)
1194 {
1195 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1196 return CMD_WARNING;
1197 }
1198
paulca162182005-09-12 16:58:52 +00001199 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001200 if (! ifc)
1201 {
1202 ifc = connected_new ();
1203 ifc->ifp = ifp;
1204
1205 /* Address. */
1206 p = prefix_ipv4_new ();
1207 *p = cp;
1208 ifc->address = (struct prefix *) p;
1209
1210 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001211 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001212 {
1213 p = prefix_ipv4_new ();
1214 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001215 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001216 ifc->destination = (struct prefix *) p;
1217 }
1218
paul718e3742002-12-13 20:15:29 +00001219 /* Label. */
1220 if (label)
paul0752ef02005-11-03 12:35:21 +00001221 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001222
1223 /* Add to linked list. */
1224 listnode_add (ifp->connected, ifc);
1225 }
1226
1227 /* This address is configured from zebra. */
1228 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1229 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1230
1231 /* In case of this route need to install kernel. */
1232 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1233 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1234 {
1235 /* Some system need to up the interface to set IP address. */
1236 if (! if_is_up (ifp))
1237 {
1238 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1239 if_refresh (ifp);
1240 }
1241
1242 ret = if_set_prefix (ifp, ifc);
1243 if (ret < 0)
1244 {
1245 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001246 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001247 return CMD_WARNING;
1248 }
1249
hassoeef1fe12004-10-03 18:46:08 +00001250 /* Add to subnet chain list (while marking secondary attribute). */
1251 if_subnet_add (ifp, ifc);
1252
paul718e3742002-12-13 20:15:29 +00001253 /* IP address propery set. */
1254 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1255
1256 /* Update interface address information to protocol daemon. */
1257 zebra_interface_address_add_update (ifp, ifc);
1258
1259 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001260 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001261 connected_up_ipv4 (ifp, ifc);
1262 }
1263
1264 return CMD_SUCCESS;
1265}
1266
paula1ac18c2005-06-28 17:17:12 +00001267static int
hasso39db97e2004-10-12 20:50:58 +00001268ip_address_uninstall (struct vty *vty, struct interface *ifp,
1269 const char *addr_str, const char *peer_str,
1270 const char *label)
paul718e3742002-12-13 20:15:29 +00001271{
1272 struct prefix_ipv4 cp;
1273 struct connected *ifc;
1274 int ret;
1275
1276 /* Convert to prefix structure. */
1277 ret = str2prefix_ipv4 (addr_str, &cp);
1278 if (ret <= 0)
1279 {
1280 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1281 return CMD_WARNING;
1282 }
1283
1284 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001285 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001286 if (! ifc)
1287 {
1288 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1289 return CMD_WARNING;
1290 }
1291
1292 /* This is not configured address. */
1293 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1294 return CMD_WARNING;
1295
Paul Jakma74ecdc92006-06-15 18:10:47 +00001296 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1297
paul718e3742002-12-13 20:15:29 +00001298 /* This is not real address or interface is not active. */
1299 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1300 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1301 {
1302 listnode_delete (ifp->connected, ifc);
1303 connected_free (ifc);
1304 return CMD_WARNING;
1305 }
1306
1307 /* This is real route. */
1308 ret = if_unset_prefix (ifp, ifc);
1309 if (ret < 0)
1310 {
1311 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001312 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001313 return CMD_WARNING;
1314 }
David Lamparter7f062c22010-02-01 16:41:26 +01001315 /* success! call returned that the address deletion went through.
1316 * this is a synchronous operation, so we know it succeeded and can
1317 * now update all internal state. */
paul718e3742002-12-13 20:15:29 +00001318
David Lamparter7f062c22010-02-01 16:41:26 +01001319 /* the HAVE_NETLINK check is only here because, on BSD, although the
1320 * call above is still synchronous, we get a second confirmation later
1321 * through the route socket, and we don't want to touch that behaviour
1322 * for now. It should work without the #ifdef, but why take the risk...
1323 * -- equinox 2012-07-13 */
1324#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001325
1326 /* Remove connected route. */
1327 connected_down_ipv4 (ifp, ifc);
1328
David Lamparter7f062c22010-02-01 16:41:26 +01001329 /* Redistribute this information. */
1330 zebra_interface_address_delete_update (ifp, ifc);
1331
1332 /* IP address propery set. */
1333 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1334
1335 /* remove from interface, remark secondaries */
1336 if_subnet_delete (ifp, ifc);
1337
paul718e3742002-12-13 20:15:29 +00001338 /* Free address information. */
1339 listnode_delete (ifp->connected, ifc);
1340 connected_free (ifc);
hassoeef1fe12004-10-03 18:46:08 +00001341#endif
paul718e3742002-12-13 20:15:29 +00001342
1343 return CMD_SUCCESS;
1344}
1345
1346DEFUN (ip_address,
1347 ip_address_cmd,
1348 "ip address A.B.C.D/M",
1349 "Interface Internet Protocol config commands\n"
1350 "Set the IP address of an interface\n"
1351 "IP address (e.g. 10.0.0.1/8)\n")
1352{
hassoeef1fe12004-10-03 18:46:08 +00001353 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001354}
1355
1356DEFUN (no_ip_address,
1357 no_ip_address_cmd,
1358 "no ip address A.B.C.D/M",
1359 NO_STR
1360 "Interface Internet Protocol config commands\n"
1361 "Set the IP address of an interface\n"
1362 "IP Address (e.g. 10.0.0.1/8)")
1363{
hassoeef1fe12004-10-03 18:46:08 +00001364 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001365}
1366
1367#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001368DEFUN (ip_address_label,
1369 ip_address_label_cmd,
1370 "ip address A.B.C.D/M label LINE",
1371 "Interface Internet Protocol config commands\n"
1372 "Set the IP address of an interface\n"
1373 "IP address (e.g. 10.0.0.1/8)\n"
1374 "Label of this address\n"
1375 "Label\n")
1376{
hassoeef1fe12004-10-03 18:46:08 +00001377 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001378}
1379
1380DEFUN (no_ip_address_label,
1381 no_ip_address_label_cmd,
1382 "no ip address A.B.C.D/M label LINE",
1383 NO_STR
1384 "Interface Internet Protocol config commands\n"
1385 "Set the IP address of an interface\n"
1386 "IP address (e.g. 10.0.0.1/8)\n"
1387 "Label of this address\n"
1388 "Label\n")
1389{
hassoeef1fe12004-10-03 18:46:08 +00001390 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001391}
1392#endif /* HAVE_NETLINK */
1393
1394#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001395static int
hasso39db97e2004-10-12 20:50:58 +00001396ipv6_address_install (struct vty *vty, struct interface *ifp,
1397 const char *addr_str, const char *peer_str,
1398 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001399{
1400 struct prefix_ipv6 cp;
1401 struct connected *ifc;
1402 struct prefix_ipv6 *p;
1403 int ret;
1404
1405 ret = str2prefix_ipv6 (addr_str, &cp);
1406 if (ret <= 0)
1407 {
1408 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1409 return CMD_WARNING;
1410 }
1411
paulca162182005-09-12 16:58:52 +00001412 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001413 if (! ifc)
1414 {
1415 ifc = connected_new ();
1416 ifc->ifp = ifp;
1417
1418 /* Address. */
1419 p = prefix_ipv6_new ();
1420 *p = cp;
1421 ifc->address = (struct prefix *) p;
1422
1423 /* Secondary. */
1424 if (secondary)
1425 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1426
1427 /* Label. */
1428 if (label)
paul0752ef02005-11-03 12:35:21 +00001429 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001430
1431 /* Add to linked list. */
1432 listnode_add (ifp->connected, ifc);
1433 }
1434
1435 /* This address is configured from zebra. */
1436 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1437 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1438
1439 /* In case of this route need to install kernel. */
1440 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1441 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1442 {
1443 /* Some system need to up the interface to set IP address. */
1444 if (! if_is_up (ifp))
1445 {
1446 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1447 if_refresh (ifp);
1448 }
1449
1450 ret = if_prefix_add_ipv6 (ifp, ifc);
1451
1452 if (ret < 0)
1453 {
1454 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001455 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001456 return CMD_WARNING;
1457 }
1458
1459 /* IP address propery set. */
1460 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1461
1462 /* Update interface address information to protocol daemon. */
1463 zebra_interface_address_add_update (ifp, ifc);
1464
1465 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001466 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001467 connected_up_ipv6 (ifp, ifc);
1468 }
1469
1470 return CMD_SUCCESS;
1471}
1472
paula1ac18c2005-06-28 17:17:12 +00001473static int
hasso39db97e2004-10-12 20:50:58 +00001474ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1475 const char *addr_str, const char *peer_str,
1476 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001477{
1478 struct prefix_ipv6 cp;
1479 struct connected *ifc;
1480 int ret;
1481
1482 /* Convert to prefix structure. */
1483 ret = str2prefix_ipv6 (addr_str, &cp);
1484 if (ret <= 0)
1485 {
1486 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1487 return CMD_WARNING;
1488 }
1489
1490 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001491 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001492 if (! ifc)
1493 {
1494 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1495 return CMD_WARNING;
1496 }
1497
1498 /* This is not configured address. */
1499 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1500 return CMD_WARNING;
1501
Christian Franke676e1a02013-01-24 14:04:45 +00001502 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1503
paul718e3742002-12-13 20:15:29 +00001504 /* This is not real address or interface is not active. */
1505 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1506 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1507 {
1508 listnode_delete (ifp->connected, ifc);
1509 connected_free (ifc);
1510 return CMD_WARNING;
1511 }
1512
1513 /* This is real route. */
1514 ret = if_prefix_delete_ipv6 (ifp, ifc);
1515 if (ret < 0)
1516 {
1517 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001518 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001519 return CMD_WARNING;
1520 }
1521
1522 /* Redistribute this information. */
1523 zebra_interface_address_delete_update (ifp, ifc);
1524
1525 /* Remove connected route. */
1526 connected_down_ipv6 (ifp, ifc);
1527
1528 /* Free address information. */
1529 listnode_delete (ifp->connected, ifc);
1530 connected_free (ifc);
1531
1532 return CMD_SUCCESS;
1533}
1534
1535DEFUN (ipv6_address,
1536 ipv6_address_cmd,
1537 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001538 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001539 "Set the IP address of an interface\n"
1540 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1541{
1542 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1543}
1544
1545DEFUN (no_ipv6_address,
1546 no_ipv6_address_cmd,
1547 "no ipv6 address X:X::X:X/M",
1548 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001549 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001550 "Set the IP address of an interface\n"
1551 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1552{
1553 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1554}
1555#endif /* HAVE_IPV6 */
1556
paula1ac18c2005-06-28 17:17:12 +00001557static int
paul718e3742002-12-13 20:15:29 +00001558if_config_write (struct vty *vty)
1559{
hasso52dc7ee2004-09-23 19:18:23 +00001560 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001561 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001562
paul1eb8ef22005-04-07 07:30:20 +00001563 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001564 {
1565 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001566 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001567 struct connected *ifc;
1568 struct prefix *p;
1569
paul718e3742002-12-13 20:15:29 +00001570 if_data = ifp->info;
1571
1572 vty_out (vty, "interface %s%s", ifp->name,
1573 VTY_NEWLINE);
1574
1575 if (ifp->desc)
1576 vty_out (vty, " description %s%s", ifp->desc,
1577 VTY_NEWLINE);
1578
1579 /* Assign bandwidth here to avoid unnecessary interface flap
1580 while processing config script */
1581 if (ifp->bandwidth != 0)
1582 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1583
paul2e3b2e42002-12-13 21:03:13 +00001584 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1585 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1586
paul1eb8ef22005-04-07 07:30:20 +00001587 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001588 {
paul718e3742002-12-13 20:15:29 +00001589 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1590 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001591 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001592 p = ifc->address;
1593 vty_out (vty, " ip%s address %s/%d",
1594 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001595 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001596 p->prefixlen);
1597
paul718e3742002-12-13 20:15:29 +00001598 if (ifc->label)
1599 vty_out (vty, " label %s", ifc->label);
1600
1601 vty_out (vty, "%s", VTY_NEWLINE);
1602 }
1603 }
1604
1605 if (if_data)
1606 {
1607 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1608 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1609
1610 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1611 vty_out (vty, " %smulticast%s",
1612 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1613 VTY_NEWLINE);
1614 }
1615
1616#ifdef RTADV
1617 rtadv_config_write (vty, ifp);
1618#endif /* RTADV */
1619
hassoca776982004-06-12 14:33:05 +00001620#ifdef HAVE_IRDP
1621 irdp_config_write (vty, ifp);
1622#endif /* IRDP */
1623
paul718e3742002-12-13 20:15:29 +00001624 vty_out (vty, "!%s", VTY_NEWLINE);
1625 }
1626 return 0;
1627}
1628
1629/* Allocate and initialize interface vector. */
1630void
paula1ac18c2005-06-28 17:17:12 +00001631zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001632{
1633 /* Initialize interface and new hook. */
1634 if_init ();
1635 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1636 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1637
1638 /* Install configuration write function. */
1639 install_node (&interface_node, if_config_write);
1640
1641 install_element (VIEW_NODE, &show_interface_cmd);
1642 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001643 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001644 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001645 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001646 install_default (INTERFACE_NODE);
1647 install_element (INTERFACE_NODE, &interface_desc_cmd);
1648 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1649 install_element (INTERFACE_NODE, &multicast_cmd);
1650 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001651 install_element (INTERFACE_NODE, &linkdetect_cmd);
1652 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001653 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1654 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1655 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1656 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1657 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1658 install_element (INTERFACE_NODE, &ip_address_cmd);
1659 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1660#ifdef HAVE_IPV6
1661 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1662 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1663#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001664#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001665 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001666 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001667#endif /* HAVE_NETLINK */
1668}