blob: 748bf00d6a9fe88de049193231c48e5896120912 [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
paul44145db2004-05-09 11:00:23 +0000212
213/* Handle an interface delete event
214 *
215 * This function is only called when support for
216 * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
217 * is available. It is not called on, eg, Solaris.
218 */
219#if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
paul718e3742002-12-13 20:15:29 +0000220void
221if_delete_update (struct interface *ifp)
222{
223 struct listnode *node;
224 struct listnode *next;
225 struct connected *ifc;
226 struct prefix *p;
227
228 if (if_is_up(ifp))
229 {
230 zlog_err ("interface %s index %d is still up while being deleted.",
231 ifp->name, ifp->ifindex);
232 return;
233 }
234
235 /* Mark interface as inactive */
236 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
237
238 if (IS_ZEBRA_DEBUG_KERNEL)
239 zlog_info ("interface %s index %d is now inactive.",
240 ifp->name, ifp->ifindex);
241
242 /* Delete connected routes from the kernel. */
243 if (ifp->connected)
244 {
245 for (node = listhead (ifp->connected); node; node = next)
246 {
247 next = node->next;
248 ifc = getdata (node);
249 p = ifc->address;
250
251 if (p->family == AF_INET)
252 connected_down_ipv4 (ifp, ifc);
253#ifdef HAVE_IPV6
254 else if (p->family == AF_INET6)
255 connected_down_ipv6 (ifp, ifc);
256#endif /* HAVE_IPV6 */
257
258 zebra_interface_address_delete_update (ifp, ifc);
259
260 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
261
262 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
263 {
264 listnode_delete (ifp->connected, ifc);
265 connected_free (ifc);
266 }
267 }
268 }
269 zebra_interface_delete_update (ifp);
270}
paul44145db2004-05-09 11:00:23 +0000271#endif /* (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK) */
paul718e3742002-12-13 20:15:29 +0000272
273/* Interface is up. */
274void
275if_up (struct interface *ifp)
276{
277 listnode node;
278 listnode next;
279 struct connected *ifc;
280 struct prefix *p;
281
282 /* Notify the protocol daemons. */
283 zebra_interface_up_update (ifp);
284
285 /* Install connected routes to the kernel. */
286 if (ifp->connected)
287 {
288 for (node = listhead (ifp->connected); node; node = next)
289 {
290 next = node->next;
291 ifc = getdata (node);
292 p = ifc->address;
293
294 if (p->family == AF_INET)
295 connected_up_ipv4 (ifp, ifc);
296#ifdef HAVE_IPV6
297 else if (p->family == AF_INET6)
298 connected_up_ipv6 (ifp, ifc);
299#endif /* HAVE_IPV6 */
300 }
301 }
302
303 /* Examine all static routes. */
304 rib_update ();
305}
306
307/* Interface goes down. We have to manage different behavior of based
308 OS. */
309void
310if_down (struct interface *ifp)
311{
312 listnode node;
313 listnode next;
314 struct connected *ifc;
315 struct prefix *p;
316
317 /* Notify to the protocol daemons. */
318 zebra_interface_down_update (ifp);
319
320 /* Delete connected routes from the kernel. */
321 if (ifp->connected)
322 {
323 for (node = listhead (ifp->connected); node; node = next)
324 {
325 next = node->next;
326 ifc = getdata (node);
327 p = ifc->address;
328
329 if (p->family == AF_INET)
330 connected_down_ipv4 (ifp, ifc);
331#ifdef HAVE_IPV6
332 else if (p->family == AF_INET6)
333 connected_down_ipv6 (ifp, ifc);
334#endif /* HAVE_IPV6 */
335 }
336 }
337
338 /* Examine all static routes which direct to the interface. */
339 rib_update ();
340}
341
342void
343if_refresh (struct interface *ifp)
344{
paul2e3b2e42002-12-13 21:03:13 +0000345 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000346 {
347 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000348 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000349 if_down (ifp);
350 }
351 else
352 {
353 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000354 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000355 if_up (ifp);
356 }
357}
358
359/* Printout flag information into vty */
360void
361if_flag_dump_vty (struct vty *vty, unsigned long flag)
362{
363 int separator = 0;
364
365#define IFF_OUT_VTY(X, Y) \
366 if ((X) && (flag & (X))) \
367 { \
368 if (separator) \
369 vty_out (vty, ","); \
370 else \
371 separator = 1; \
372 vty_out (vty, Y); \
373 }
374
375 vty_out (vty, "<");
376 IFF_OUT_VTY (IFF_UP, "UP");
377 IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST");
378 IFF_OUT_VTY (IFF_DEBUG, "DEBUG");
379 IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK");
380 IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT");
381 IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS");
382 IFF_OUT_VTY (IFF_RUNNING, "RUNNING");
383 IFF_OUT_VTY (IFF_NOARP, "NOARP");
384 IFF_OUT_VTY (IFF_PROMISC, "PROMISC");
385 IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI");
386 IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE");
387 IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX");
388 IFF_OUT_VTY (IFF_LINK0, "LINK0");
389 IFF_OUT_VTY (IFF_LINK1, "LINK1");
390 IFF_OUT_VTY (IFF_LINK2, "LINK2");
391 IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST");
paul44145db2004-05-09 11:00:23 +0000392#ifdef SOLARIS_IPV6
393 IFF_OUT_VTY (IFF_IPV4, "IFF_IPv4");
394 IFF_OUT_VTY (IFF_IPV6, "IFF_IPv6");
395#endif /* SOLARIS_IPV6 */
paul718e3742002-12-13 20:15:29 +0000396 vty_out (vty, ">");
397}
398
399/* Output prefix string to vty. */
400int
401prefix_vty_out (struct vty *vty, struct prefix *p)
402{
403 char str[INET6_ADDRSTRLEN];
404
405 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
406 vty_out (vty, "%s", str);
407 return strlen (str);
408}
409
410/* Dump if address information to vty. */
411void
412connected_dump_vty (struct vty *vty, struct connected *connected)
413{
414 struct prefix *p;
415 struct interface *ifp;
416
417 /* Set interface pointer. */
418 ifp = connected->ifp;
419
420 /* Print interface address. */
421 p = connected->address;
422 vty_out (vty, " %s ", prefix_family_str (p));
423 prefix_vty_out (vty, p);
424 vty_out (vty, "/%d", p->prefixlen);
425
426 /* If there is destination address, print it. */
427 p = connected->destination;
428 if (p)
429 {
430 if (p->family == AF_INET)
431 if (ifp->flags & IFF_BROADCAST)
432 {
433 vty_out (vty, " broadcast ");
434 prefix_vty_out (vty, p);
435 }
436
437 if (ifp->flags & IFF_POINTOPOINT)
438 {
439 vty_out (vty, " pointopoint ");
440 prefix_vty_out (vty, p);
441 }
442 }
443
444 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
445 vty_out (vty, " secondary");
446
447 if (connected->label)
448 vty_out (vty, " %s", connected->label);
449
450 vty_out (vty, "%s", VTY_NEWLINE);
451}
452
453#ifdef RTADV
454/* Dump interface ND information to vty. */
455void
456nd_dump_vty (struct vty *vty, struct interface *ifp)
457{
458 struct zebra_if *zif;
459 struct rtadvconf *rtadv;
460
461 zif = (struct zebra_if *) ifp->info;
462 rtadv = &zif->rtadv;
463
464 if (rtadv->AdvSendAdvertisements)
465 {
466 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
467 rtadv->AdvReachableTime, VTY_NEWLINE);
468 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
469 rtadv->AdvRetransTimer, VTY_NEWLINE);
470 vty_out (vty, " ND router advertisements are sent every %d seconds%s",
471 rtadv->MaxRtrAdvInterval, VTY_NEWLINE);
472 vty_out (vty, " ND router advertisements live for %d seconds%s",
473 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
474 if (rtadv->AdvManagedFlag)
475 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
476 VTY_NEWLINE);
477 else
478 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
479 VTY_NEWLINE);
480 }
481}
482#endif /* RTADV */
483
484/* Interface's information print out to vty interface. */
485void
486if_dump_vty (struct vty *vty, struct interface *ifp)
487{
488#ifdef HAVE_SOCKADDR_DL
489 struct sockaddr_dl *sdl;
490#endif /* HAVE_SOCKADDR_DL */
491 struct connected *connected;
492 listnode node;
493
paul2e3b2e42002-12-13 21:03:13 +0000494 vty_out (vty, "Interface %s is ", ifp->name);
495 if (if_is_up(ifp)) {
496 vty_out (vty, "up, line protocol ");
497
498 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
499 if (if_is_running(ifp))
500 vty_out (vty, "is up%s", VTY_NEWLINE);
501 else
502 vty_out (vty, "is down%s", VTY_NEWLINE);
503 } else {
504 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
505 }
506 } else {
507 vty_out (vty, "down%s", VTY_NEWLINE);
508 }
509
paul718e3742002-12-13 20:15:29 +0000510 if (ifp->desc)
511 vty_out (vty, " Description: %s%s", ifp->desc,
512 VTY_NEWLINE);
513 if (ifp->ifindex <= 0)
514 {
515 vty_out(vty, " index %d pseudo interface%s", ifp->ifindex, VTY_NEWLINE);
516 return;
517 }
518 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
519 {
520 vty_out(vty, " index %d inactive interface%s",
521 ifp->ifindex,
522 VTY_NEWLINE);
523 return;
524 }
525
526 vty_out (vty, " index %d metric %d mtu %d ",
527 ifp->ifindex, ifp->metric, ifp->mtu);
528 if_flag_dump_vty (vty, ifp->flags);
paul44145db2004-05-09 11:00:23 +0000529#ifdef HAVE_IPV6
530 if (ifp->mtu6 != ifp->mtu)
531 vty_out (vty, "mtu6 %d ", ifp->mtu6);
532#endif
533
paul718e3742002-12-13 20:15:29 +0000534 vty_out (vty, "%s", VTY_NEWLINE);
535
536 /* Hardware address. */
537#ifdef HAVE_SOCKADDR_DL
538 sdl = &ifp->sdl;
539 if (sdl != NULL && sdl->sdl_alen != 0)
540 {
541 int i;
542 u_char *ptr;
543
544 vty_out (vty, " HWaddr: ");
545 for (i = 0, ptr = LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
546 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
547 vty_out (vty, "%s", VTY_NEWLINE);
548 }
549#else
550 if (ifp->hw_addr_len != 0)
551 {
552 int i;
553
554 vty_out (vty, " HWaddr: ");
555 for (i = 0; i < ifp->hw_addr_len; i++)
556 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
557 vty_out (vty, "%s", VTY_NEWLINE);
558 }
559#endif /* HAVE_SOCKADDR_DL */
560
561 /* Bandwidth in kbps */
562 if (ifp->bandwidth != 0)
563 {
564 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
565 vty_out(vty, "%s", VTY_NEWLINE);
566 }
567
568 for (node = listhead (ifp->connected); node; nextnode (node))
569 {
570 connected = getdata (node);
571 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL))
572 connected_dump_vty (vty, connected);
573 }
574
575#ifdef RTADV
576 nd_dump_vty (vty, ifp);
577#endif /* RTADV */
578
579#ifdef HAVE_PROC_NET_DEV
580 /* Statistics print out using proc file system. */
581 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
582 " multicast packets %lu%s",
583 ifp->stats.rx_packets, ifp->stats.rx_bytes,
584 ifp->stats.rx_dropped, ifp->stats.rx_multicast, VTY_NEWLINE);
585
586 vty_out (vty, " input errors %lu, length %lu, overrun %lu,"
587 " CRC %lu, frame %lu, fifo %lu, missed %lu%s",
588 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
589 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
590 ifp->stats.rx_frame_errors, ifp->stats.rx_fifo_errors,
591 ifp->stats.rx_missed_errors, VTY_NEWLINE);
592
593 vty_out (vty, " output packets %lu, bytes %lu, dropped %lu%s",
594 ifp->stats.tx_packets, ifp->stats.tx_bytes,
595 ifp->stats.tx_dropped, VTY_NEWLINE);
596
597 vty_out (vty, " output errors %lu, aborted %lu, carrier %lu,"
598 " fifo %lu, heartbeat %lu, window %lu%s",
599 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
600 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
601 ifp->stats.tx_heartbeat_errors, ifp->stats.tx_window_errors,
602 VTY_NEWLINE);
603
604 vty_out (vty, " collisions %lu%s", ifp->stats.collisions, VTY_NEWLINE);
605#endif /* HAVE_PROC_NET_DEV */
606
607#ifdef HAVE_NET_RT_IFLIST
608#if defined (__bsdi__) || defined (__NetBSD__)
609 /* Statistics print out using sysctl (). */
610 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
611 " multicast packets %qu%s",
612 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
613 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
614 VTY_NEWLINE);
615
616 vty_out (vty, " input errors %qu%s",
617 ifp->stats.ifi_ierrors, VTY_NEWLINE);
618
619 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
620 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
621 ifp->stats.ifi_omcasts, VTY_NEWLINE);
622
623 vty_out (vty, " output errors %qu%s",
624 ifp->stats.ifi_oerrors, VTY_NEWLINE);
625
626 vty_out (vty, " collisions %qu%s",
627 ifp->stats.ifi_collisions, VTY_NEWLINE);
628#else
629 /* Statistics print out using sysctl (). */
630 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
631 " multicast packets %lu%s",
632 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
633 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
634 VTY_NEWLINE);
635
636 vty_out (vty, " input errors %lu%s",
637 ifp->stats.ifi_ierrors, VTY_NEWLINE);
638
639 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
640 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
641 ifp->stats.ifi_omcasts, VTY_NEWLINE);
642
643 vty_out (vty, " output errors %lu%s",
644 ifp->stats.ifi_oerrors, VTY_NEWLINE);
645
646 vty_out (vty, " collisions %lu%s",
647 ifp->stats.ifi_collisions, VTY_NEWLINE);
648#endif /* __bsdi__ || __NetBSD__ */
649#endif /* HAVE_NET_RT_IFLIST */
650}
651
652/* Check supported address family. */
653int
654if_supported_family (int family)
655{
656 if (family == AF_INET)
657 return 1;
658#ifdef HAVE_IPV6
659 if (family == AF_INET6)
660 return 1;
661#endif /* HAVE_IPV6 */
662 return 0;
663}
664
665/* Wrapper hook point for zebra daemon so that ifindex can be set
666 * DEFUN macro not used as extract.pl HAS to ignore this
667 * See also interface_cmd in lib/if.c
668 */
669DEFUN_NOSH (zebra_interface,
670 zebra_interface_cmd,
671 "interface IFNAME",
672 "Select an interface to configure\n"
673 "Interface's name\n")
674{
675 int ret;
676 struct interface * ifp;
677
678 /* Call lib interface() */
679 ret = interface_cmd.func (self, vty, argc, argv);
680
681 ifp = vty->index;
682
683 /* Set ifindex
684 this only happens if interface is NOT in kernel */
685 if (ifp->ifindex == 0)
686 {
687 ifp->ifindex = if_new_intern_ifindex ();
688 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
689 }
690
691 return ret;
692}
693
paul718e3742002-12-13 20:15:29 +0000694struct cmd_node interface_node =
695{
696 INTERFACE_NODE,
697 "%s(config-if)# ",
698 1
699};
700
701/* Show all or specified interface to vty. */
702DEFUN (show_interface, show_interface_cmd,
703 "show interface [IFNAME]",
704 SHOW_STR
705 "Interface status and configuration\n"
706 "Inteface name\n")
707{
708 listnode node;
709 struct interface *ifp;
710
711#ifdef HAVE_PROC_NET_DEV
712 /* If system has interface statistics via proc file system, update
713 statistics. */
714 ifstat_update_proc ();
715#endif /* HAVE_PROC_NET_DEV */
716#ifdef HAVE_NET_RT_IFLIST
717 ifstat_update_sysctl ();
718#endif /* HAVE_NET_RT_IFLIST */
719
720 /* Specified interface print. */
721 if (argc != 0)
722 {
723 ifp = if_lookup_by_name (argv[0]);
724 if (ifp == NULL)
725 {
726 vty_out (vty, "%% Can't find interface %s%s", argv[0],
727 VTY_NEWLINE);
728 return CMD_WARNING;
729 }
730 if_dump_vty (vty, ifp);
731 return CMD_SUCCESS;
732 }
733
734 /* All interface print. */
735 for (node = listhead (iflist); node; nextnode (node))
736 if_dump_vty (vty, getdata (node));
737
738 return CMD_SUCCESS;
739}
740
741DEFUN (multicast,
742 multicast_cmd,
743 "multicast",
744 "Set multicast flag to interface\n")
745{
746 int ret;
747 struct interface *ifp;
748 struct zebra_if *if_data;
749
750 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000751 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000752 {
paul48b33aa2002-12-13 20:52:52 +0000753 ret = if_set_flags (ifp, IFF_MULTICAST);
754 if (ret < 0)
755 {
756 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
757 return CMD_WARNING;
758 }
759 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000760 }
paul718e3742002-12-13 20:15:29 +0000761 if_data = ifp->info;
762 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000763
paul718e3742002-12-13 20:15:29 +0000764 return CMD_SUCCESS;
765}
766
767DEFUN (no_multicast,
768 no_multicast_cmd,
769 "no multicast",
770 NO_STR
771 "Unset multicast flag to interface\n")
772{
773 int ret;
774 struct interface *ifp;
775 struct zebra_if *if_data;
776
777 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000778 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000779 {
paul48b33aa2002-12-13 20:52:52 +0000780 ret = if_unset_flags (ifp, IFF_MULTICAST);
781 if (ret < 0)
782 {
783 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
784 return CMD_WARNING;
785 }
786 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000787 }
paul718e3742002-12-13 20:15:29 +0000788 if_data = ifp->info;
789 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
790
791 return CMD_SUCCESS;
792}
793
paul2e3b2e42002-12-13 21:03:13 +0000794DEFUN (linkdetect,
795 linkdetect_cmd,
796 "link-detect",
797 "Enable link detection on interface\n")
798{
paul2e3b2e42002-12-13 21:03:13 +0000799 struct interface *ifp;
800 int if_was_operative;
801
802 ifp = (struct interface *) vty->index;
803 if_was_operative = if_is_operative(ifp);
804 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
805
806 /* When linkdetection is enabled, if might come down */
807 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
808
809 /* FIXME: Will defer status change forwarding if interface
810 does not come down! */
811
812 return CMD_SUCCESS;
813}
814
815
816DEFUN (no_linkdetect,
817 no_linkdetect_cmd,
818 "no link-detect",
819 NO_STR
820 "Disable link detection on interface\n")
821{
paul2e3b2e42002-12-13 21:03:13 +0000822 struct interface *ifp;
823 int if_was_operative;
824
825 ifp = (struct interface *) vty->index;
826 if_was_operative = if_is_operative(ifp);
827 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
828
829 /* Interface may come up after disabling link detection */
830 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
831
832 /* FIXME: see linkdetect_cmd */
833
834 return CMD_SUCCESS;
835}
836
paul718e3742002-12-13 20:15:29 +0000837DEFUN (shutdown_if,
838 shutdown_if_cmd,
839 "shutdown",
840 "Shutdown the selected interface\n")
841{
842 int ret;
843 struct interface *ifp;
844 struct zebra_if *if_data;
845
846 ifp = (struct interface *) vty->index;
847 ret = if_unset_flags (ifp, IFF_UP);
848 if (ret < 0)
849 {
850 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
851 return CMD_WARNING;
852 }
853 if_refresh (ifp);
854 if_data = ifp->info;
855 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
856
857 return CMD_SUCCESS;
858}
859
860DEFUN (no_shutdown_if,
861 no_shutdown_if_cmd,
862 "no shutdown",
863 NO_STR
864 "Shutdown the selected interface\n")
865{
866 int ret;
867 struct interface *ifp;
868 struct zebra_if *if_data;
869
870 ifp = (struct interface *) vty->index;
871 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
872 if (ret < 0)
873 {
874 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
875 return CMD_WARNING;
876 }
877 if_refresh (ifp);
878 if_data = ifp->info;
879 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
880
881 return CMD_SUCCESS;
882}
883
884DEFUN (bandwidth_if,
885 bandwidth_if_cmd,
886 "bandwidth <1-10000000>",
887 "Set bandwidth informational parameter\n"
888 "Bandwidth in kilobits\n")
889{
890 struct interface *ifp;
891 unsigned int bandwidth;
892
893 ifp = (struct interface *) vty->index;
894 bandwidth = strtol(argv[0], NULL, 10);
895
896 /* bandwidth range is <1-10000000> */
897 if (bandwidth < 1 || bandwidth > 10000000)
898 {
899 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
900 return CMD_WARNING;
901 }
902
903 ifp->bandwidth = bandwidth;
904
905 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +0000906 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000907 zebra_interface_up_update (ifp);
908
909 return CMD_SUCCESS;
910}
911
912DEFUN (no_bandwidth_if,
913 no_bandwidth_if_cmd,
914 "no bandwidth",
915 NO_STR
916 "Set bandwidth informational parameter\n")
917{
918 struct interface *ifp;
919
920 ifp = (struct interface *) vty->index;
921
922 ifp->bandwidth = 0;
923
924 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +0000925 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000926 zebra_interface_up_update (ifp);
927
928 return CMD_SUCCESS;
929}
930
931ALIAS (no_bandwidth_if,
932 no_bandwidth_if_val_cmd,
933 "no bandwidth <1-10000000>",
934 NO_STR
935 "Set bandwidth informational parameter\n"
936 "Bandwidth in kilobits\n")
937
938int
939ip_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
940 char *peer_str, char *label, int secondary)
941{
942 struct prefix_ipv4 cp;
943 struct connected *ifc;
944 struct prefix_ipv4 *p;
945 struct in_addr mask;
946 int ret;
947
948 ret = str2prefix_ipv4 (addr_str, &cp);
949 if (ret <= 0)
950 {
951 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
952 return CMD_WARNING;
953 }
954
955 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
956 if (! ifc)
957 {
958 ifc = connected_new ();
959 ifc->ifp = ifp;
960
961 /* Address. */
962 p = prefix_ipv4_new ();
963 *p = cp;
964 ifc->address = (struct prefix *) p;
965
966 /* Broadcast. */
967 if (p->prefixlen <= 30)
968 {
969 p = prefix_ipv4_new ();
970 *p = cp;
971 masklen2ip (p->prefixlen, &mask);
972 p->prefix.s_addr |= ~mask.s_addr;
973 ifc->destination = (struct prefix *) p;
974 }
975
976 /* Secondary. */
977 if (secondary)
978 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
979
980 /* Label. */
981 if (label)
982 ifc->label = strdup (label);
983
984 /* Add to linked list. */
985 listnode_add (ifp->connected, ifc);
986 }
987
988 /* This address is configured from zebra. */
989 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
990 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
991
992 /* In case of this route need to install kernel. */
993 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
994 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
995 {
996 /* Some system need to up the interface to set IP address. */
997 if (! if_is_up (ifp))
998 {
999 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1000 if_refresh (ifp);
1001 }
1002
1003 ret = if_set_prefix (ifp, ifc);
1004 if (ret < 0)
1005 {
1006 vty_out (vty, "%% Can't set interface IP address: %s.%s",
1007 strerror(errno), VTY_NEWLINE);
1008 return CMD_WARNING;
1009 }
1010
1011 /* IP address propery set. */
1012 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1013
1014 /* Update interface address information to protocol daemon. */
1015 zebra_interface_address_add_update (ifp, ifc);
1016
1017 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001018 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001019 connected_up_ipv4 (ifp, ifc);
1020 }
1021
1022 return CMD_SUCCESS;
1023}
1024
1025int
1026ip_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
1027 char *peer_str, char *label, int secondry)
1028{
1029 struct prefix_ipv4 cp;
1030 struct connected *ifc;
1031 int ret;
1032
1033 /* Convert to prefix structure. */
1034 ret = str2prefix_ipv4 (addr_str, &cp);
1035 if (ret <= 0)
1036 {
1037 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1038 return CMD_WARNING;
1039 }
1040
1041 /* Check current interface address. */
1042 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1043 if (! ifc)
1044 {
1045 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1046 return CMD_WARNING;
1047 }
1048
1049 /* This is not configured address. */
1050 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1051 return CMD_WARNING;
1052
1053 /* This is not real address or interface is not active. */
1054 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1055 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1056 {
1057 listnode_delete (ifp->connected, ifc);
1058 connected_free (ifc);
1059 return CMD_WARNING;
1060 }
1061
1062 /* This is real route. */
1063 ret = if_unset_prefix (ifp, ifc);
1064 if (ret < 0)
1065 {
1066 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1067 strerror(errno), VTY_NEWLINE);
1068 return CMD_WARNING;
1069 }
1070
1071 /* Redistribute this information. */
1072 zebra_interface_address_delete_update (ifp, ifc);
1073
1074 /* Remove connected route. */
1075 connected_down_ipv4 (ifp, ifc);
1076
1077 /* Free address information. */
1078 listnode_delete (ifp->connected, ifc);
1079 connected_free (ifc);
1080
1081 return CMD_SUCCESS;
1082}
1083
1084DEFUN (ip_address,
1085 ip_address_cmd,
1086 "ip address A.B.C.D/M",
1087 "Interface Internet Protocol config commands\n"
1088 "Set the IP address of an interface\n"
1089 "IP address (e.g. 10.0.0.1/8)\n")
1090{
1091 return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1092}
1093
1094DEFUN (no_ip_address,
1095 no_ip_address_cmd,
1096 "no ip address A.B.C.D/M",
1097 NO_STR
1098 "Interface Internet Protocol config commands\n"
1099 "Set the IP address of an interface\n"
1100 "IP Address (e.g. 10.0.0.1/8)")
1101{
1102 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1103}
1104
1105#ifdef HAVE_NETLINK
1106DEFUN (ip_address_secondary,
1107 ip_address_secondary_cmd,
1108 "ip address A.B.C.D/M secondary",
1109 "Interface Internet Protocol config commands\n"
1110 "Set the IP address of an interface\n"
1111 "IP address (e.g. 10.0.0.1/8)\n"
1112 "Secondary IP address\n")
1113{
1114 return ip_address_install (vty, vty->index, argv[0], NULL, NULL, 1);
1115}
1116
1117DEFUN (ip_address_label,
1118 ip_address_label_cmd,
1119 "ip address A.B.C.D/M label LINE",
1120 "Interface Internet Protocol config commands\n"
1121 "Set the IP address of an interface\n"
1122 "IP address (e.g. 10.0.0.1/8)\n"
1123 "Label of this address\n"
1124 "Label\n")
1125{
1126 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1], 1);
1127}
1128
hassof1d92e12004-03-18 15:40:33 +00001129ALIAS (ip_address_label,
1130 ip_address_secondary_label_cmd,
1131 "ip address A.B.C.D/M secondary label LINE",
1132 "Interface Internet Protocol config commands\n"
1133 "Set the IP address of an interface\n"
1134 "IP address (e.g. 10.0.0.1/8)\n"
1135 "Secondary IP address\n"
1136 "Label of this address\n"
1137 "Label\n")
1138
paul718e3742002-12-13 20:15:29 +00001139DEFUN (no_ip_address_secondary,
1140 no_ip_address_secondary_cmd,
1141 "no ip address A.B.C.D/M secondary",
1142 NO_STR
1143 "Interface Internet Protocol config commands\n"
1144 "Set the IP address of an interface\n"
1145 "IP address (e.g. 10.0.0.1/8)\n"
1146 "Secondary IP address\n")
1147{
1148 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 1);
1149}
1150
1151DEFUN (no_ip_address_label,
1152 no_ip_address_label_cmd,
1153 "no ip address A.B.C.D/M label LINE",
1154 NO_STR
1155 "Interface Internet Protocol config commands\n"
1156 "Set the IP address of an interface\n"
1157 "IP address (e.g. 10.0.0.1/8)\n"
1158 "Label of this address\n"
1159 "Label\n")
1160{
1161 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1], 1);
1162}
hassof1d92e12004-03-18 15:40:33 +00001163
1164ALIAS (no_ip_address_label,
1165 no_ip_address_secondary_label_cmd,
1166 "no ip address A.B.C.D/M secondary label LINE",
1167 NO_STR
1168 "Interface Internet Protocol config commands\n"
1169 "Set the IP address of an interface\n"
1170 "IP address (e.g. 10.0.0.1/8)\n"
1171 "Secondary IP address\n"
1172 "Label of this address\n"
1173 "Label\n")
paul718e3742002-12-13 20:15:29 +00001174#endif /* HAVE_NETLINK */
1175
1176#ifdef HAVE_IPV6
1177int
1178ipv6_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
1179 char *peer_str, char *label, int secondary)
1180{
1181 struct prefix_ipv6 cp;
1182 struct connected *ifc;
1183 struct prefix_ipv6 *p;
1184 int ret;
1185
1186 ret = str2prefix_ipv6 (addr_str, &cp);
1187 if (ret <= 0)
1188 {
1189 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1190 return CMD_WARNING;
1191 }
1192
1193 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1194 if (! ifc)
1195 {
1196 ifc = connected_new ();
1197 ifc->ifp = ifp;
1198
1199 /* Address. */
1200 p = prefix_ipv6_new ();
1201 *p = cp;
1202 ifc->address = (struct prefix *) p;
1203
1204 /* Secondary. */
1205 if (secondary)
1206 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1207
1208 /* Label. */
1209 if (label)
1210 ifc->label = strdup (label);
1211
1212 /* Add to linked list. */
1213 listnode_add (ifp->connected, ifc);
1214 }
1215
1216 /* This address is configured from zebra. */
1217 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1218 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1219
1220 /* In case of this route need to install kernel. */
1221 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1222 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1223 {
1224 /* Some system need to up the interface to set IP address. */
1225 if (! if_is_up (ifp))
1226 {
1227 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1228 if_refresh (ifp);
1229 }
1230
1231 ret = if_prefix_add_ipv6 (ifp, ifc);
1232
1233 if (ret < 0)
1234 {
1235 vty_out (vty, "%% Can't set interface IP address: %s.%s",
1236 strerror(errno), VTY_NEWLINE);
1237 return CMD_WARNING;
1238 }
1239
1240 /* IP address propery set. */
1241 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1242
1243 /* Update interface address information to protocol daemon. */
1244 zebra_interface_address_add_update (ifp, ifc);
1245
1246 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001247 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001248 connected_up_ipv6 (ifp, ifc);
1249 }
1250
1251 return CMD_SUCCESS;
1252}
1253
1254int
1255ipv6_address_uninstall (struct vty *vty, struct interface *ifp, char *addr_str,
1256 char *peer_str, char *label, int secondry)
1257{
1258 struct prefix_ipv6 cp;
1259 struct connected *ifc;
1260 int ret;
1261
1262 /* Convert to prefix structure. */
1263 ret = str2prefix_ipv6 (addr_str, &cp);
1264 if (ret <= 0)
1265 {
1266 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1267 return CMD_WARNING;
1268 }
1269
1270 /* Check current interface address. */
1271 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1272 if (! ifc)
1273 {
1274 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1275 return CMD_WARNING;
1276 }
1277
1278 /* This is not configured address. */
1279 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1280 return CMD_WARNING;
1281
1282 /* This is not real address or interface is not active. */
1283 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1284 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1285 {
1286 listnode_delete (ifp->connected, ifc);
1287 connected_free (ifc);
1288 return CMD_WARNING;
1289 }
1290
1291 /* This is real route. */
1292 ret = if_prefix_delete_ipv6 (ifp, ifc);
1293 if (ret < 0)
1294 {
1295 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1296 strerror(errno), VTY_NEWLINE);
1297 return CMD_WARNING;
1298 }
1299
1300 /* Redistribute this information. */
1301 zebra_interface_address_delete_update (ifp, ifc);
1302
1303 /* Remove connected route. */
1304 connected_down_ipv6 (ifp, ifc);
1305
1306 /* Free address information. */
1307 listnode_delete (ifp->connected, ifc);
1308 connected_free (ifc);
1309
1310 return CMD_SUCCESS;
1311}
1312
1313DEFUN (ipv6_address,
1314 ipv6_address_cmd,
1315 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001316 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001317 "Set the IP address of an interface\n"
1318 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1319{
1320 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1321}
1322
1323DEFUN (no_ipv6_address,
1324 no_ipv6_address_cmd,
1325 "no ipv6 address X:X::X:X/M",
1326 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001327 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001328 "Set the IP address of an interface\n"
1329 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1330{
1331 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1332}
1333#endif /* HAVE_IPV6 */
1334
1335#ifdef KAME
1336DEFUN (ip_tunnel,
1337 ip_tunnel_cmd,
1338 "ip tunnel IP_address IP_address",
1339 "KAME ip tunneling configuration commands\n"
1340 "Set FROM IP address and TO IP address\n")
1341{
1342 return CMD_SUCCESS;
1343}
1344
1345DEFUN (no_ip_tunnel, no_ip_tunnel_cmd,
1346 "no ip tunnel",
1347 NO_STR
1348 "Set FROM IP address and TO IP address\n")
1349{
1350 return CMD_SUCCESS;
1351}
1352#endif /* KAME */
1353
1354int
1355if_config_write (struct vty *vty)
1356{
1357 listnode node;
1358 struct interface *ifp;
1359 char buf[BUFSIZ];
1360
1361 for (node = listhead (iflist); node; nextnode (node))
1362 {
1363 struct zebra_if *if_data;
1364 listnode addrnode;
1365 struct connected *ifc;
1366 struct prefix *p;
1367
1368 ifp = getdata (node);
1369 if_data = ifp->info;
1370
1371 vty_out (vty, "interface %s%s", ifp->name,
1372 VTY_NEWLINE);
1373
1374 if (ifp->desc)
1375 vty_out (vty, " description %s%s", ifp->desc,
1376 VTY_NEWLINE);
1377
1378 /* Assign bandwidth here to avoid unnecessary interface flap
1379 while processing config script */
1380 if (ifp->bandwidth != 0)
1381 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1382
paul2e3b2e42002-12-13 21:03:13 +00001383 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1384 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1385
paul718e3742002-12-13 20:15:29 +00001386 for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
1387 {
1388 ifc = getdata (addrnode);
1389 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1390 {
1391 p = ifc->address;
1392 vty_out (vty, " ip%s address %s/%d",
1393 p->family == AF_INET ? "" : "v6",
1394 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1395 p->prefixlen);
1396
1397 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
1398 vty_out (vty, " secondary");
1399
1400 if (ifc->label)
1401 vty_out (vty, " label %s", ifc->label);
1402
1403 vty_out (vty, "%s", VTY_NEWLINE);
1404 }
1405 }
1406
1407 if (if_data)
1408 {
1409 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1410 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1411
1412 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1413 vty_out (vty, " %smulticast%s",
1414 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1415 VTY_NEWLINE);
1416 }
1417
1418#ifdef RTADV
1419 rtadv_config_write (vty, ifp);
1420#endif /* RTADV */
1421
1422 vty_out (vty, "!%s", VTY_NEWLINE);
1423 }
1424 return 0;
1425}
1426
1427/* Allocate and initialize interface vector. */
1428void
1429zebra_if_init ()
1430{
1431 /* Initialize interface and new hook. */
1432 if_init ();
1433 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1434 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1435
1436 /* Install configuration write function. */
1437 install_node (&interface_node, if_config_write);
1438
1439 install_element (VIEW_NODE, &show_interface_cmd);
1440 install_element (ENABLE_NODE, &show_interface_cmd);
1441 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001442 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001443 install_default (INTERFACE_NODE);
1444 install_element (INTERFACE_NODE, &interface_desc_cmd);
1445 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1446 install_element (INTERFACE_NODE, &multicast_cmd);
1447 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001448 install_element (INTERFACE_NODE, &linkdetect_cmd);
1449 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001450 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1451 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1452 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1453 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1454 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1455 install_element (INTERFACE_NODE, &ip_address_cmd);
1456 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1457#ifdef HAVE_IPV6
1458 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1459 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1460#endif /* HAVE_IPV6 */
1461#ifdef KAME
1462 install_element (INTERFACE_NODE, &ip_tunnel_cmd);
1463 install_element (INTERFACE_NODE, &no_ip_tunnel_cmd);
1464#endif /* KAME */
1465#ifdef HAVE_NETLINK
1466 install_element (INTERFACE_NODE, &ip_address_secondary_cmd);
1467 install_element (INTERFACE_NODE, &ip_address_label_cmd);
hassof1d92e12004-03-18 15:40:33 +00001468 install_element (INTERFACE_NODE, &ip_address_secondary_label_cmd);
paul718e3742002-12-13 20:15:29 +00001469 install_element (INTERFACE_NODE, &no_ip_address_secondary_cmd);
1470 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
hassof1d92e12004-03-18 15:40:33 +00001471 install_element (INTERFACE_NODE, &no_ip_address_secondary_label_cmd);
paul718e3742002-12-13 20:15:29 +00001472#endif /* HAVE_NETLINK */
1473}