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