blob: 84bac4a00bafeaa521b01a69a2db9343cd0efc14 [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"
42
43/* Allocate a new internal interface index
44 * This works done from the top so that %d macros
45 * print a - sign!
46 */
47static unsigned int
48if_new_intern_ifindex (void)
49{
50 /* Start here so that first one assigned is 0xFFFFFFFF */
51 static unsigned int ifindex = IFINDEX_INTERNBASE + 1;
52
53 for (;;)
54 {
55 ifindex--;
56 if ( ifindex <= IFINDEX_INTERNBASE )
57 ifindex = 0xFFFFFFFF;
58
59 if (if_lookup_by_index(ifindex) == NULL)
60 return ifindex;
61 }
62}
63
64/* Called when new interface is added. */
65int
66if_zebra_new_hook (struct interface *ifp)
67{
68 struct zebra_if *zebra_if;
69
70 zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
71 memset (zebra_if, 0, sizeof (struct zebra_if));
72
73 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
74 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
75
76#ifdef RTADV
77 {
78 /* Set default router advertise values. */
79 struct rtadvconf *rtadv;
80
81 rtadv = &zebra_if->rtadv;
82
83 rtadv->AdvSendAdvertisements = 0;
84 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
85 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
86 rtadv->AdvIntervalTimer = 0;
87 rtadv->AdvManagedFlag = 0;
88 rtadv->AdvOtherConfigFlag = 0;
89 rtadv->AdvLinkMTU = 0;
90 rtadv->AdvReachableTime = 0;
91 rtadv->AdvRetransTimer = 0;
92 rtadv->AdvCurHopLimit = 0;
93 rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
94
95 rtadv->AdvPrefixList = list_new ();
96 }
97#endif /* RTADV */
98
99 ifp->info = zebra_if;
100 return 0;
101}
102
103/* Called when interface is deleted. */
104int
105if_zebra_delete_hook (struct interface *ifp)
106{
107 if (ifp->info)
108 XFREE (MTYPE_TMP, ifp->info);
109 return 0;
110}
111
112/* Wake up configured address if it is not in current kernel
113 address. */
114void
115if_addr_wakeup (struct interface *ifp)
116{
117 struct listnode *node;
118 struct connected *ifc;
119 struct prefix *p;
120 int ret;
121
122 for (node = listhead (ifp->connected); node; nextnode (node))
123 {
124 ifc = getdata (node);
125 p = ifc->address;
126
127 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
128 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
129 {
130 /* Address check. */
131 if (p->family == AF_INET)
132 {
133 if (! if_is_up (ifp))
134 {
135 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
136 if_refresh (ifp);
137 }
138
139 ret = if_set_prefix (ifp, ifc);
140 if (ret < 0)
141 {
142 zlog_warn ("Can't set interface's address: %s",
143 strerror(errno));
144 continue;
145 }
146 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
147
148 zebra_interface_address_add_update (ifp, ifc);
149
paul2e3b2e42002-12-13 21:03:13 +0000150 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000151 connected_up_ipv4 (ifp, ifc);
152 }
153#ifdef HAVE_IPV6
154 if (p->family == AF_INET6)
155 {
156 if (! if_is_up (ifp))
157 {
158 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
159 if_refresh (ifp);
160 }
161
162 ret = if_prefix_add_ipv6 (ifp, ifc);
163 if (ret < 0)
164 {
165 zlog_warn ("Can't set interface's address: %s",
166 strerror(errno));
167 continue;
168 }
169 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
170
171 zebra_interface_address_add_update (ifp, ifc);
172
paul2e3b2e42002-12-13 21:03:13 +0000173 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000174 connected_up_ipv6 (ifp, ifc);
175 }
176#endif /* HAVE_IPV6 */
177 }
178 }
179}
180
181/* Handle interface addition */
182void
183if_add_update (struct interface *ifp)
184{
paul48b33aa2002-12-13 20:52:52 +0000185 struct zebra_if *if_data;
186
187 if_data = ifp->info;
188 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
189 if_set_flags (ifp, IFF_MULTICAST);
190 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
191 if_unset_flags (ifp, IFF_MULTICAST);
192
paul718e3742002-12-13 20:15:29 +0000193 zebra_interface_add_update (ifp);
194
195 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
196 {
197 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
198
199 if_addr_wakeup (ifp);
200
201 if (IS_ZEBRA_DEBUG_KERNEL)
202 zlog_info ("interface %s index %d becomes active.",
203 ifp->name, ifp->ifindex);
204 }
205 else
206 {
207 if (IS_ZEBRA_DEBUG_KERNEL)
208 zlog_info ("interface %s index %d is added.", ifp->name, ifp->ifindex);
209 }
210}
211
212/* Handle an interface delete event */
213void
214if_delete_update (struct interface *ifp)
215{
216 struct listnode *node;
217 struct listnode *next;
218 struct connected *ifc;
219 struct prefix *p;
220
221 if (if_is_up(ifp))
222 {
223 zlog_err ("interface %s index %d is still up while being deleted.",
224 ifp->name, ifp->ifindex);
225 return;
226 }
227
228 /* Mark interface as inactive */
229 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
230
231 if (IS_ZEBRA_DEBUG_KERNEL)
232 zlog_info ("interface %s index %d is now inactive.",
233 ifp->name, ifp->ifindex);
234
235 /* Delete connected routes from the kernel. */
236 if (ifp->connected)
237 {
238 for (node = listhead (ifp->connected); node; node = next)
239 {
240 next = node->next;
241 ifc = getdata (node);
242 p = ifc->address;
243
244 if (p->family == AF_INET)
245 connected_down_ipv4 (ifp, ifc);
246#ifdef HAVE_IPV6
247 else if (p->family == AF_INET6)
248 connected_down_ipv6 (ifp, ifc);
249#endif /* HAVE_IPV6 */
250
251 zebra_interface_address_delete_update (ifp, ifc);
252
253 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
254
255 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
256 {
257 listnode_delete (ifp->connected, ifc);
258 connected_free (ifc);
259 }
260 }
261 }
262 zebra_interface_delete_update (ifp);
263}
264
265/* Interface is up. */
266void
267if_up (struct interface *ifp)
268{
269 listnode node;
270 listnode next;
271 struct connected *ifc;
272 struct prefix *p;
273
274 /* Notify the protocol daemons. */
275 zebra_interface_up_update (ifp);
276
277 /* Install connected routes to the kernel. */
278 if (ifp->connected)
279 {
280 for (node = listhead (ifp->connected); node; node = next)
281 {
282 next = node->next;
283 ifc = getdata (node);
284 p = ifc->address;
285
286 if (p->family == AF_INET)
287 connected_up_ipv4 (ifp, ifc);
288#ifdef HAVE_IPV6
289 else if (p->family == AF_INET6)
290 connected_up_ipv6 (ifp, ifc);
291#endif /* HAVE_IPV6 */
292 }
293 }
294
295 /* Examine all static routes. */
296 rib_update ();
297}
298
299/* Interface goes down. We have to manage different behavior of based
300 OS. */
301void
302if_down (struct interface *ifp)
303{
304 listnode node;
305 listnode next;
306 struct connected *ifc;
307 struct prefix *p;
308
309 /* Notify to the protocol daemons. */
310 zebra_interface_down_update (ifp);
311
312 /* Delete connected routes from the kernel. */
313 if (ifp->connected)
314 {
315 for (node = listhead (ifp->connected); node; node = next)
316 {
317 next = node->next;
318 ifc = getdata (node);
319 p = ifc->address;
320
321 if (p->family == AF_INET)
322 connected_down_ipv4 (ifp, ifc);
323#ifdef HAVE_IPV6
324 else if (p->family == AF_INET6)
325 connected_down_ipv6 (ifp, ifc);
326#endif /* HAVE_IPV6 */
327 }
328 }
329
330 /* Examine all static routes which direct to the interface. */
331 rib_update ();
332}
333
334void
335if_refresh (struct interface *ifp)
336{
paul2e3b2e42002-12-13 21:03:13 +0000337 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000338 {
339 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000340 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000341 if_down (ifp);
342 }
343 else
344 {
345 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000346 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000347 if_up (ifp);
348 }
349}
350
351/* Printout flag information into vty */
352void
353if_flag_dump_vty (struct vty *vty, unsigned long flag)
354{
355 int separator = 0;
356
357#define IFF_OUT_VTY(X, Y) \
358 if ((X) && (flag & (X))) \
359 { \
360 if (separator) \
361 vty_out (vty, ","); \
362 else \
363 separator = 1; \
364 vty_out (vty, Y); \
365 }
366
367 vty_out (vty, "<");
368 IFF_OUT_VTY (IFF_UP, "UP");
369 IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST");
370 IFF_OUT_VTY (IFF_DEBUG, "DEBUG");
371 IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK");
372 IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT");
373 IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS");
374 IFF_OUT_VTY (IFF_RUNNING, "RUNNING");
375 IFF_OUT_VTY (IFF_NOARP, "NOARP");
376 IFF_OUT_VTY (IFF_PROMISC, "PROMISC");
377 IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI");
378 IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE");
379 IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX");
380 IFF_OUT_VTY (IFF_LINK0, "LINK0");
381 IFF_OUT_VTY (IFF_LINK1, "LINK1");
382 IFF_OUT_VTY (IFF_LINK2, "LINK2");
383 IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST");
384 vty_out (vty, ">");
385}
386
387/* Output prefix string to vty. */
388int
389prefix_vty_out (struct vty *vty, struct prefix *p)
390{
391 char str[INET6_ADDRSTRLEN];
392
393 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
394 vty_out (vty, "%s", str);
395 return strlen (str);
396}
397
398/* Dump if address information to vty. */
399void
400connected_dump_vty (struct vty *vty, struct connected *connected)
401{
402 struct prefix *p;
403 struct interface *ifp;
404
405 /* Set interface pointer. */
406 ifp = connected->ifp;
407
408 /* Print interface address. */
409 p = connected->address;
410 vty_out (vty, " %s ", prefix_family_str (p));
411 prefix_vty_out (vty, p);
412 vty_out (vty, "/%d", p->prefixlen);
413
414 /* If there is destination address, print it. */
415 p = connected->destination;
416 if (p)
417 {
418 if (p->family == AF_INET)
419 if (ifp->flags & IFF_BROADCAST)
420 {
421 vty_out (vty, " broadcast ");
422 prefix_vty_out (vty, p);
423 }
424
425 if (ifp->flags & IFF_POINTOPOINT)
426 {
427 vty_out (vty, " pointopoint ");
428 prefix_vty_out (vty, p);
429 }
430 }
431
432 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
433 vty_out (vty, " secondary");
434
435 if (connected->label)
436 vty_out (vty, " %s", connected->label);
437
438 vty_out (vty, "%s", VTY_NEWLINE);
439}
440
441#ifdef RTADV
442/* Dump interface ND information to vty. */
443void
444nd_dump_vty (struct vty *vty, struct interface *ifp)
445{
446 struct zebra_if *zif;
447 struct rtadvconf *rtadv;
448
449 zif = (struct zebra_if *) ifp->info;
450 rtadv = &zif->rtadv;
451
452 if (rtadv->AdvSendAdvertisements)
453 {
454 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
455 rtadv->AdvReachableTime, VTY_NEWLINE);
456 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
457 rtadv->AdvRetransTimer, VTY_NEWLINE);
458 vty_out (vty, " ND router advertisements are sent every %d seconds%s",
459 rtadv->MaxRtrAdvInterval, VTY_NEWLINE);
460 vty_out (vty, " ND router advertisements live for %d seconds%s",
461 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
462 if (rtadv->AdvManagedFlag)
463 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
464 VTY_NEWLINE);
465 else
466 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
467 VTY_NEWLINE);
468 }
469}
470#endif /* RTADV */
471
472/* Interface's information print out to vty interface. */
473void
474if_dump_vty (struct vty *vty, struct interface *ifp)
475{
476#ifdef HAVE_SOCKADDR_DL
477 struct sockaddr_dl *sdl;
478#endif /* HAVE_SOCKADDR_DL */
479 struct connected *connected;
480 listnode node;
481
paul2e3b2e42002-12-13 21:03:13 +0000482 vty_out (vty, "Interface %s is ", ifp->name);
483 if (if_is_up(ifp)) {
484 vty_out (vty, "up, line protocol ");
485
486 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
487 if (if_is_running(ifp))
488 vty_out (vty, "is up%s", VTY_NEWLINE);
489 else
490 vty_out (vty, "is down%s", VTY_NEWLINE);
491 } else {
492 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
493 }
494 } else {
495 vty_out (vty, "down%s", VTY_NEWLINE);
496 }
497
paul718e3742002-12-13 20:15:29 +0000498 if (ifp->desc)
499 vty_out (vty, " Description: %s%s", ifp->desc,
500 VTY_NEWLINE);
501 if (ifp->ifindex <= 0)
502 {
503 vty_out(vty, " index %d pseudo interface%s", ifp->ifindex, VTY_NEWLINE);
504 return;
505 }
506 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
507 {
508 vty_out(vty, " index %d inactive interface%s",
509 ifp->ifindex,
510 VTY_NEWLINE);
511 return;
512 }
513
514 vty_out (vty, " index %d metric %d mtu %d ",
515 ifp->ifindex, ifp->metric, ifp->mtu);
516 if_flag_dump_vty (vty, ifp->flags);
517 vty_out (vty, "%s", VTY_NEWLINE);
518
519 /* Hardware address. */
520#ifdef HAVE_SOCKADDR_DL
521 sdl = &ifp->sdl;
522 if (sdl != NULL && sdl->sdl_alen != 0)
523 {
524 int i;
525 u_char *ptr;
526
527 vty_out (vty, " HWaddr: ");
528 for (i = 0, ptr = LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
529 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
530 vty_out (vty, "%s", VTY_NEWLINE);
531 }
532#else
533 if (ifp->hw_addr_len != 0)
534 {
535 int i;
536
537 vty_out (vty, " HWaddr: ");
538 for (i = 0; i < ifp->hw_addr_len; i++)
539 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
540 vty_out (vty, "%s", VTY_NEWLINE);
541 }
542#endif /* HAVE_SOCKADDR_DL */
543
544 /* Bandwidth in kbps */
545 if (ifp->bandwidth != 0)
546 {
547 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
548 vty_out(vty, "%s", VTY_NEWLINE);
549 }
550
551 for (node = listhead (ifp->connected); node; nextnode (node))
552 {
553 connected = getdata (node);
554 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL))
555 connected_dump_vty (vty, connected);
556 }
557
558#ifdef RTADV
559 nd_dump_vty (vty, ifp);
560#endif /* RTADV */
561
562#ifdef HAVE_PROC_NET_DEV
563 /* Statistics print out using proc file system. */
564 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
565 " multicast packets %lu%s",
566 ifp->stats.rx_packets, ifp->stats.rx_bytes,
567 ifp->stats.rx_dropped, ifp->stats.rx_multicast, VTY_NEWLINE);
568
569 vty_out (vty, " input errors %lu, length %lu, overrun %lu,"
570 " CRC %lu, frame %lu, fifo %lu, missed %lu%s",
571 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
572 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
573 ifp->stats.rx_frame_errors, ifp->stats.rx_fifo_errors,
574 ifp->stats.rx_missed_errors, VTY_NEWLINE);
575
576 vty_out (vty, " output packets %lu, bytes %lu, dropped %lu%s",
577 ifp->stats.tx_packets, ifp->stats.tx_bytes,
578 ifp->stats.tx_dropped, VTY_NEWLINE);
579
580 vty_out (vty, " output errors %lu, aborted %lu, carrier %lu,"
581 " fifo %lu, heartbeat %lu, window %lu%s",
582 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
583 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
584 ifp->stats.tx_heartbeat_errors, ifp->stats.tx_window_errors,
585 VTY_NEWLINE);
586
587 vty_out (vty, " collisions %lu%s", ifp->stats.collisions, VTY_NEWLINE);
588#endif /* HAVE_PROC_NET_DEV */
589
590#ifdef HAVE_NET_RT_IFLIST
591#if defined (__bsdi__) || defined (__NetBSD__)
592 /* Statistics print out using sysctl (). */
593 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
594 " multicast packets %qu%s",
595 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
596 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
597 VTY_NEWLINE);
598
599 vty_out (vty, " input errors %qu%s",
600 ifp->stats.ifi_ierrors, VTY_NEWLINE);
601
602 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
603 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
604 ifp->stats.ifi_omcasts, VTY_NEWLINE);
605
606 vty_out (vty, " output errors %qu%s",
607 ifp->stats.ifi_oerrors, VTY_NEWLINE);
608
609 vty_out (vty, " collisions %qu%s",
610 ifp->stats.ifi_collisions, VTY_NEWLINE);
611#else
612 /* Statistics print out using sysctl (). */
613 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
614 " multicast packets %lu%s",
615 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
616 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
617 VTY_NEWLINE);
618
619 vty_out (vty, " input errors %lu%s",
620 ifp->stats.ifi_ierrors, VTY_NEWLINE);
621
622 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
623 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
624 ifp->stats.ifi_omcasts, VTY_NEWLINE);
625
626 vty_out (vty, " output errors %lu%s",
627 ifp->stats.ifi_oerrors, VTY_NEWLINE);
628
629 vty_out (vty, " collisions %lu%s",
630 ifp->stats.ifi_collisions, VTY_NEWLINE);
631#endif /* __bsdi__ || __NetBSD__ */
632#endif /* HAVE_NET_RT_IFLIST */
633}
634
635/* Check supported address family. */
636int
637if_supported_family (int family)
638{
639 if (family == AF_INET)
640 return 1;
641#ifdef HAVE_IPV6
642 if (family == AF_INET6)
643 return 1;
644#endif /* HAVE_IPV6 */
645 return 0;
646}
647
648/* Wrapper hook point for zebra daemon so that ifindex can be set
649 * DEFUN macro not used as extract.pl HAS to ignore this
650 * See also interface_cmd in lib/if.c
651 */
652DEFUN_NOSH (zebra_interface,
653 zebra_interface_cmd,
654 "interface IFNAME",
655 "Select an interface to configure\n"
656 "Interface's name\n")
657{
658 int ret;
659 struct interface * ifp;
660
661 /* Call lib interface() */
662 ret = interface_cmd.func (self, vty, argc, argv);
663
664 ifp = vty->index;
665
666 /* Set ifindex
667 this only happens if interface is NOT in kernel */
668 if (ifp->ifindex == 0)
669 {
670 ifp->ifindex = if_new_intern_ifindex ();
671 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
672 }
673
674 return ret;
675}
676
paul718e3742002-12-13 20:15:29 +0000677struct cmd_node interface_node =
678{
679 INTERFACE_NODE,
680 "%s(config-if)# ",
681 1
682};
683
684/* Show all or specified interface to vty. */
685DEFUN (show_interface, show_interface_cmd,
686 "show interface [IFNAME]",
687 SHOW_STR
688 "Interface status and configuration\n"
689 "Inteface name\n")
690{
691 listnode node;
692 struct interface *ifp;
693
694#ifdef HAVE_PROC_NET_DEV
695 /* If system has interface statistics via proc file system, update
696 statistics. */
697 ifstat_update_proc ();
698#endif /* HAVE_PROC_NET_DEV */
699#ifdef HAVE_NET_RT_IFLIST
700 ifstat_update_sysctl ();
701#endif /* HAVE_NET_RT_IFLIST */
702
703 /* Specified interface print. */
704 if (argc != 0)
705 {
706 ifp = if_lookup_by_name (argv[0]);
707 if (ifp == NULL)
708 {
709 vty_out (vty, "%% Can't find interface %s%s", argv[0],
710 VTY_NEWLINE);
711 return CMD_WARNING;
712 }
713 if_dump_vty (vty, ifp);
714 return CMD_SUCCESS;
715 }
716
717 /* All interface print. */
718 for (node = listhead (iflist); node; nextnode (node))
719 if_dump_vty (vty, getdata (node));
720
721 return CMD_SUCCESS;
722}
723
724DEFUN (multicast,
725 multicast_cmd,
726 "multicast",
727 "Set multicast flag to interface\n")
728{
729 int ret;
730 struct interface *ifp;
731 struct zebra_if *if_data;
732
733 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000734 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000735 {
paul48b33aa2002-12-13 20:52:52 +0000736 ret = if_set_flags (ifp, IFF_MULTICAST);
737 if (ret < 0)
738 {
739 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
740 return CMD_WARNING;
741 }
742 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000743 }
paul718e3742002-12-13 20:15:29 +0000744 if_data = ifp->info;
745 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000746
paul718e3742002-12-13 20:15:29 +0000747 return CMD_SUCCESS;
748}
749
750DEFUN (no_multicast,
751 no_multicast_cmd,
752 "no multicast",
753 NO_STR
754 "Unset multicast flag to interface\n")
755{
756 int ret;
757 struct interface *ifp;
758 struct zebra_if *if_data;
759
760 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000761 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000762 {
paul48b33aa2002-12-13 20:52:52 +0000763 ret = if_unset_flags (ifp, IFF_MULTICAST);
764 if (ret < 0)
765 {
766 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
767 return CMD_WARNING;
768 }
769 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000770 }
paul718e3742002-12-13 20:15:29 +0000771 if_data = ifp->info;
772 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
773
774 return CMD_SUCCESS;
775}
776
paul2e3b2e42002-12-13 21:03:13 +0000777DEFUN (linkdetect,
778 linkdetect_cmd,
779 "link-detect",
780 "Enable link detection on interface\n")
781{
paul2e3b2e42002-12-13 21:03:13 +0000782 struct interface *ifp;
783 int if_was_operative;
784
785 ifp = (struct interface *) vty->index;
786 if_was_operative = if_is_operative(ifp);
787 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
788
789 /* When linkdetection is enabled, if might come down */
790 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
791
792 /* FIXME: Will defer status change forwarding if interface
793 does not come down! */
794
795 return CMD_SUCCESS;
796}
797
798
799DEFUN (no_linkdetect,
800 no_linkdetect_cmd,
801 "no link-detect",
802 NO_STR
803 "Disable link detection on interface\n")
804{
paul2e3b2e42002-12-13 21:03:13 +0000805 struct interface *ifp;
806 int if_was_operative;
807
808 ifp = (struct interface *) vty->index;
809 if_was_operative = if_is_operative(ifp);
810 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
811
812 /* Interface may come up after disabling link detection */
813 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
814
815 /* FIXME: see linkdetect_cmd */
816
817 return CMD_SUCCESS;
818}
819
paul718e3742002-12-13 20:15:29 +0000820DEFUN (shutdown_if,
821 shutdown_if_cmd,
822 "shutdown",
823 "Shutdown the selected interface\n")
824{
825 int ret;
826 struct interface *ifp;
827 struct zebra_if *if_data;
828
829 ifp = (struct interface *) vty->index;
830 ret = if_unset_flags (ifp, IFF_UP);
831 if (ret < 0)
832 {
833 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
834 return CMD_WARNING;
835 }
836 if_refresh (ifp);
837 if_data = ifp->info;
838 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
839
840 return CMD_SUCCESS;
841}
842
843DEFUN (no_shutdown_if,
844 no_shutdown_if_cmd,
845 "no shutdown",
846 NO_STR
847 "Shutdown the selected interface\n")
848{
849 int ret;
850 struct interface *ifp;
851 struct zebra_if *if_data;
852
853 ifp = (struct interface *) vty->index;
854 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
855 if (ret < 0)
856 {
857 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
858 return CMD_WARNING;
859 }
860 if_refresh (ifp);
861 if_data = ifp->info;
862 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
863
864 return CMD_SUCCESS;
865}
866
867DEFUN (bandwidth_if,
868 bandwidth_if_cmd,
869 "bandwidth <1-10000000>",
870 "Set bandwidth informational parameter\n"
871 "Bandwidth in kilobits\n")
872{
873 struct interface *ifp;
874 unsigned int bandwidth;
875
876 ifp = (struct interface *) vty->index;
877 bandwidth = strtol(argv[0], NULL, 10);
878
879 /* bandwidth range is <1-10000000> */
880 if (bandwidth < 1 || bandwidth > 10000000)
881 {
882 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
883 return CMD_WARNING;
884 }
885
886 ifp->bandwidth = bandwidth;
887
888 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +0000889 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000890 zebra_interface_up_update (ifp);
891
892 return CMD_SUCCESS;
893}
894
895DEFUN (no_bandwidth_if,
896 no_bandwidth_if_cmd,
897 "no bandwidth",
898 NO_STR
899 "Set bandwidth informational parameter\n")
900{
901 struct interface *ifp;
902
903 ifp = (struct interface *) vty->index;
904
905 ifp->bandwidth = 0;
906
907 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +0000908 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000909 zebra_interface_up_update (ifp);
910
911 return CMD_SUCCESS;
912}
913
914ALIAS (no_bandwidth_if,
915 no_bandwidth_if_val_cmd,
916 "no bandwidth <1-10000000>",
917 NO_STR
918 "Set bandwidth informational parameter\n"
919 "Bandwidth in kilobits\n")
920
921int
922ip_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
923 char *peer_str, char *label, int secondary)
924{
925 struct prefix_ipv4 cp;
926 struct connected *ifc;
927 struct prefix_ipv4 *p;
928 struct in_addr mask;
929 int ret;
930
931 ret = str2prefix_ipv4 (addr_str, &cp);
932 if (ret <= 0)
933 {
934 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
935 return CMD_WARNING;
936 }
937
938 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
939 if (! ifc)
940 {
941 ifc = connected_new ();
942 ifc->ifp = ifp;
943
944 /* Address. */
945 p = prefix_ipv4_new ();
946 *p = cp;
947 ifc->address = (struct prefix *) p;
948
949 /* Broadcast. */
950 if (p->prefixlen <= 30)
951 {
952 p = prefix_ipv4_new ();
953 *p = cp;
954 masklen2ip (p->prefixlen, &mask);
955 p->prefix.s_addr |= ~mask.s_addr;
956 ifc->destination = (struct prefix *) p;
957 }
958
959 /* Secondary. */
960 if (secondary)
961 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
962
963 /* Label. */
964 if (label)
965 ifc->label = strdup (label);
966
967 /* Add to linked list. */
968 listnode_add (ifp->connected, ifc);
969 }
970
971 /* This address is configured from zebra. */
972 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
973 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
974
975 /* In case of this route need to install kernel. */
976 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
977 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
978 {
979 /* Some system need to up the interface to set IP address. */
980 if (! if_is_up (ifp))
981 {
982 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
983 if_refresh (ifp);
984 }
985
986 ret = if_set_prefix (ifp, ifc);
987 if (ret < 0)
988 {
989 vty_out (vty, "%% Can't set interface IP address: %s.%s",
990 strerror(errno), VTY_NEWLINE);
991 return CMD_WARNING;
992 }
993
994 /* IP address propery set. */
995 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
996
997 /* Update interface address information to protocol daemon. */
998 zebra_interface_address_add_update (ifp, ifc);
999
1000 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001001 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001002 connected_up_ipv4 (ifp, ifc);
1003 }
1004
1005 return CMD_SUCCESS;
1006}
1007
1008int
1009ip_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
1010 char *peer_str, char *label, int secondry)
1011{
1012 struct prefix_ipv4 cp;
1013 struct connected *ifc;
1014 int ret;
1015
1016 /* Convert to prefix structure. */
1017 ret = str2prefix_ipv4 (addr_str, &cp);
1018 if (ret <= 0)
1019 {
1020 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1021 return CMD_WARNING;
1022 }
1023
1024 /* Check current interface address. */
1025 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1026 if (! ifc)
1027 {
1028 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1029 return CMD_WARNING;
1030 }
1031
1032 /* This is not configured address. */
1033 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1034 return CMD_WARNING;
1035
1036 /* This is not real address or interface is not active. */
1037 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1038 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1039 {
1040 listnode_delete (ifp->connected, ifc);
1041 connected_free (ifc);
1042 return CMD_WARNING;
1043 }
1044
1045 /* This is real route. */
1046 ret = if_unset_prefix (ifp, ifc);
1047 if (ret < 0)
1048 {
1049 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1050 strerror(errno), VTY_NEWLINE);
1051 return CMD_WARNING;
1052 }
1053
1054 /* Redistribute this information. */
1055 zebra_interface_address_delete_update (ifp, ifc);
1056
1057 /* Remove connected route. */
1058 connected_down_ipv4 (ifp, ifc);
1059
1060 /* Free address information. */
1061 listnode_delete (ifp->connected, ifc);
1062 connected_free (ifc);
1063
1064 return CMD_SUCCESS;
1065}
1066
1067DEFUN (ip_address,
1068 ip_address_cmd,
1069 "ip address A.B.C.D/M",
1070 "Interface Internet Protocol config commands\n"
1071 "Set the IP address of an interface\n"
1072 "IP address (e.g. 10.0.0.1/8)\n")
1073{
1074 return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1075}
1076
1077DEFUN (no_ip_address,
1078 no_ip_address_cmd,
1079 "no ip address A.B.C.D/M",
1080 NO_STR
1081 "Interface Internet Protocol config commands\n"
1082 "Set the IP address of an interface\n"
1083 "IP Address (e.g. 10.0.0.1/8)")
1084{
1085 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1086}
1087
1088#ifdef HAVE_NETLINK
1089DEFUN (ip_address_secondary,
1090 ip_address_secondary_cmd,
1091 "ip address A.B.C.D/M secondary",
1092 "Interface Internet Protocol config commands\n"
1093 "Set the IP address of an interface\n"
1094 "IP address (e.g. 10.0.0.1/8)\n"
1095 "Secondary IP address\n")
1096{
1097 return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 1);
1098}
1099
1100DEFUN (ip_address_label,
1101 ip_address_label_cmd,
1102 "ip address A.B.C.D/M label LINE",
1103 "Interface Internet Protocol config commands\n"
1104 "Set the IP address of an interface\n"
1105 "IP address (e.g. 10.0.0.1/8)\n"
1106 "Label of this address\n"
1107 "Label\n")
1108{
1109 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1], 1);
1110}
1111
hassof1d92e12004-03-18 15:40:33 +00001112ALIAS (ip_address_label,
1113 ip_address_secondary_label_cmd,
1114 "ip address A.B.C.D/M secondary label LINE",
1115 "Interface Internet Protocol config commands\n"
1116 "Set the IP address of an interface\n"
1117 "IP address (e.g. 10.0.0.1/8)\n"
1118 "Secondary IP address\n"
1119 "Label of this address\n"
1120 "Label\n")
1121
paul718e3742002-12-13 20:15:29 +00001122DEFUN (no_ip_address_secondary,
1123 no_ip_address_secondary_cmd,
1124 "no ip address A.B.C.D/M secondary",
1125 NO_STR
1126 "Interface Internet Protocol config commands\n"
1127 "Set the IP address of an interface\n"
1128 "IP address (e.g. 10.0.0.1/8)\n"
1129 "Secondary IP address\n")
1130{
1131 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 1);
1132}
1133
1134DEFUN (no_ip_address_label,
1135 no_ip_address_label_cmd,
1136 "no ip address A.B.C.D/M label LINE",
1137 NO_STR
1138 "Interface Internet Protocol config commands\n"
1139 "Set the IP address of an interface\n"
1140 "IP address (e.g. 10.0.0.1/8)\n"
1141 "Label of this address\n"
1142 "Label\n")
1143{
1144 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1], 1);
1145}
hassof1d92e12004-03-18 15:40:33 +00001146
1147ALIAS (no_ip_address_label,
1148 no_ip_address_secondary_label_cmd,
1149 "no ip address A.B.C.D/M secondary label LINE",
1150 NO_STR
1151 "Interface Internet Protocol config commands\n"
1152 "Set the IP address of an interface\n"
1153 "IP address (e.g. 10.0.0.1/8)\n"
1154 "Secondary IP address\n"
1155 "Label of this address\n"
1156 "Label\n")
paul718e3742002-12-13 20:15:29 +00001157#endif /* HAVE_NETLINK */
1158
1159#ifdef HAVE_IPV6
1160int
1161ipv6_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
1162 char *peer_str, char *label, int secondary)
1163{
1164 struct prefix_ipv6 cp;
1165 struct connected *ifc;
1166 struct prefix_ipv6 *p;
1167 int ret;
1168
1169 ret = str2prefix_ipv6 (addr_str, &cp);
1170 if (ret <= 0)
1171 {
1172 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1173 return CMD_WARNING;
1174 }
1175
1176 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1177 if (! ifc)
1178 {
1179 ifc = connected_new ();
1180 ifc->ifp = ifp;
1181
1182 /* Address. */
1183 p = prefix_ipv6_new ();
1184 *p = cp;
1185 ifc->address = (struct prefix *) p;
1186
1187 /* Secondary. */
1188 if (secondary)
1189 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1190
1191 /* Label. */
1192 if (label)
1193 ifc->label = strdup (label);
1194
1195 /* Add to linked list. */
1196 listnode_add (ifp->connected, ifc);
1197 }
1198
1199 /* This address is configured from zebra. */
1200 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1201 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1202
1203 /* In case of this route need to install kernel. */
1204 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1205 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1206 {
1207 /* Some system need to up the interface to set IP address. */
1208 if (! if_is_up (ifp))
1209 {
1210 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1211 if_refresh (ifp);
1212 }
1213
1214 ret = if_prefix_add_ipv6 (ifp, ifc);
1215
1216 if (ret < 0)
1217 {
1218 vty_out (vty, "%% Can't set interface IP address: %s.%s",
1219 strerror(errno), VTY_NEWLINE);
1220 return CMD_WARNING;
1221 }
1222
1223 /* IP address propery set. */
1224 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1225
1226 /* Update interface address information to protocol daemon. */
1227 zebra_interface_address_add_update (ifp, ifc);
1228
1229 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001230 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001231 connected_up_ipv6 (ifp, ifc);
1232 }
1233
1234 return CMD_SUCCESS;
1235}
1236
1237int
1238ipv6_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
1239 char *peer_str, char *label, int secondry)
1240{
1241 struct prefix_ipv6 cp;
1242 struct connected *ifc;
1243 int ret;
1244
1245 /* Convert to prefix structure. */
1246 ret = str2prefix_ipv6 (addr_str, &cp);
1247 if (ret <= 0)
1248 {
1249 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1250 return CMD_WARNING;
1251 }
1252
1253 /* Check current interface address. */
1254 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1255 if (! ifc)
1256 {
1257 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1258 return CMD_WARNING;
1259 }
1260
1261 /* This is not configured address. */
1262 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1263 return CMD_WARNING;
1264
1265 /* This is not real address or interface is not active. */
1266 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1267 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1268 {
1269 listnode_delete (ifp->connected, ifc);
1270 connected_free (ifc);
1271 return CMD_WARNING;
1272 }
1273
1274 /* This is real route. */
1275 ret = if_prefix_delete_ipv6 (ifp, ifc);
1276 if (ret < 0)
1277 {
1278 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1279 strerror(errno), VTY_NEWLINE);
1280 return CMD_WARNING;
1281 }
1282
1283 /* Redistribute this information. */
1284 zebra_interface_address_delete_update (ifp, ifc);
1285
1286 /* Remove connected route. */
1287 connected_down_ipv6 (ifp, ifc);
1288
1289 /* Free address information. */
1290 listnode_delete (ifp->connected, ifc);
1291 connected_free (ifc);
1292
1293 return CMD_SUCCESS;
1294}
1295
1296DEFUN (ipv6_address,
1297 ipv6_address_cmd,
1298 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001299 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001300 "Set the IP address of an interface\n"
1301 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1302{
1303 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1304}
1305
1306DEFUN (no_ipv6_address,
1307 no_ipv6_address_cmd,
1308 "no ipv6 address X:X::X:X/M",
1309 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001310 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001311 "Set the IP address of an interface\n"
1312 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1313{
1314 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1315}
1316#endif /* HAVE_IPV6 */
1317
1318#ifdef KAME
1319DEFUN (ip_tunnel,
1320 ip_tunnel_cmd,
1321 "ip tunnel IP_address IP_address",
1322 "KAME ip tunneling configuration commands\n"
1323 "Set FROM IP address and TO IP address\n")
1324{
1325 return CMD_SUCCESS;
1326}
1327
1328DEFUN (no_ip_tunnel, no_ip_tunnel_cmd,
1329 "no ip tunnel",
1330 NO_STR
1331 "Set FROM IP address and TO IP address\n")
1332{
1333 return CMD_SUCCESS;
1334}
1335#endif /* KAME */
1336
1337int
1338if_config_write (struct vty *vty)
1339{
1340 listnode node;
1341 struct interface *ifp;
1342 char buf[BUFSIZ];
1343
1344 for (node = listhead (iflist); node; nextnode (node))
1345 {
1346 struct zebra_if *if_data;
1347 listnode addrnode;
1348 struct connected *ifc;
1349 struct prefix *p;
1350
1351 ifp = getdata (node);
1352 if_data = ifp->info;
1353
1354 vty_out (vty, "interface %s%s", ifp->name,
1355 VTY_NEWLINE);
1356
1357 if (ifp->desc)
1358 vty_out (vty, " description %s%s", ifp->desc,
1359 VTY_NEWLINE);
1360
1361 /* Assign bandwidth here to avoid unnecessary interface flap
1362 while processing config script */
1363 if (ifp->bandwidth != 0)
1364 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1365
paul2e3b2e42002-12-13 21:03:13 +00001366 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1367 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1368
paul718e3742002-12-13 20:15:29 +00001369 for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
1370 {
1371 ifc = getdata (addrnode);
1372 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1373 {
1374 p = ifc->address;
1375 vty_out (vty, " ip%s address %s/%d",
1376 p->family == AF_INET ? "" : "v6",
1377 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1378 p->prefixlen);
1379
1380 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
1381 vty_out (vty, " secondary");
1382
1383 if (ifc->label)
1384 vty_out (vty, " label %s", ifc->label);
1385
1386 vty_out (vty, "%s", VTY_NEWLINE);
1387 }
1388 }
1389
1390 if (if_data)
1391 {
1392 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1393 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1394
1395 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1396 vty_out (vty, " %smulticast%s",
1397 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1398 VTY_NEWLINE);
1399 }
1400
1401#ifdef RTADV
1402 rtadv_config_write (vty, ifp);
1403#endif /* RTADV */
1404
1405 vty_out (vty, "!%s", VTY_NEWLINE);
1406 }
1407 return 0;
1408}
1409
1410/* Allocate and initialize interface vector. */
1411void
1412zebra_if_init ()
1413{
1414 /* Initialize interface and new hook. */
1415 if_init ();
1416 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1417 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1418
1419 /* Install configuration write function. */
1420 install_node (&interface_node, if_config_write);
1421
1422 install_element (VIEW_NODE, &show_interface_cmd);
1423 install_element (ENABLE_NODE, &show_interface_cmd);
1424 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001425 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001426 install_default (INTERFACE_NODE);
1427 install_element (INTERFACE_NODE, &interface_desc_cmd);
1428 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1429 install_element (INTERFACE_NODE, &multicast_cmd);
1430 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001431 install_element (INTERFACE_NODE, &linkdetect_cmd);
1432 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001433 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1434 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1435 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1436 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1437 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1438 install_element (INTERFACE_NODE, &ip_address_cmd);
1439 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1440#ifdef HAVE_IPV6
1441 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1442 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1443#endif /* HAVE_IPV6 */
1444#ifdef KAME
1445 install_element (INTERFACE_NODE, &ip_tunnel_cmd);
1446 install_element (INTERFACE_NODE, &no_ip_tunnel_cmd);
1447#endif /* KAME */
1448#ifdef HAVE_NETLINK
1449 install_element (INTERFACE_NODE, &ip_address_secondary_cmd);
1450 install_element (INTERFACE_NODE, &ip_address_label_cmd);
hassof1d92e12004-03-18 15:40:33 +00001451 install_element (INTERFACE_NODE, &ip_address_secondary_label_cmd);
paul718e3742002-12-13 20:15:29 +00001452 install_element (INTERFACE_NODE, &no_ip_address_secondary_cmd);
1453 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
hassof1d92e12004-03-18 15:40:33 +00001454 install_element (INTERFACE_NODE, &no_ip_address_secondary_label_cmd);
paul718e3742002-12-13 20:15:29 +00001455#endif /* HAVE_NETLINK */
1456}