blob: 55717545dcd86fec780e6395e50aa16378544a08 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * Interface function.
3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "if.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "command.h"
30#include "memory.h"
31#include "ioctl.h"
32#include "connected.h"
33#include "log.h"
34#include "zclient.h"
35
36#include "zebra/interface.h"
37#include "zebra/rtadv.h"
38#include "zebra/rib.h"
39#include "zebra/zserv.h"
40#include "zebra/redistribute.h"
41#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000042#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000043
44/* Allocate a new internal interface index
45 * This works done from the top so that %d macros
46 * print a - sign!
47 */
48static unsigned int
49if_new_intern_ifindex (void)
50{
51 /* Start here so that first one assigned is 0xFFFFFFFF */
52 static unsigned int ifindex = IFINDEX_INTERNBASE + 1;
53
54 for (;;)
55 {
56 ifindex--;
57 if ( ifindex <= IFINDEX_INTERNBASE )
58 ifindex = 0xFFFFFFFF;
59
60 if (if_lookup_by_index(ifindex) == NULL)
61 return ifindex;
62 }
63}
64
65/* Called when new interface is added. */
66int
67if_zebra_new_hook (struct interface *ifp)
68{
69 struct zebra_if *zebra_if;
70
71 zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
72 memset (zebra_if, 0, sizeof (struct zebra_if));
73
74 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
75 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
76
77#ifdef RTADV
78 {
79 /* Set default router advertise values. */
80 struct rtadvconf *rtadv;
81
82 rtadv = &zebra_if->rtadv;
83
84 rtadv->AdvSendAdvertisements = 0;
85 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
86 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
87 rtadv->AdvIntervalTimer = 0;
88 rtadv->AdvManagedFlag = 0;
89 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000090 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000091 rtadv->AdvLinkMTU = 0;
92 rtadv->AdvReachableTime = 0;
93 rtadv->AdvRetransTimer = 0;
94 rtadv->AdvCurHopLimit = 0;
95 rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
vincent7cee1bb2005-03-25 13:08:53 +000096 rtadv->HomeAgentPreference = 0;
97 rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
98 rtadv->AdvIntervalOption = 0;
paul718e3742002-12-13 20:15:29 +000099
100 rtadv->AdvPrefixList = list_new ();
101 }
102#endif /* RTADV */
103
hassoeef1fe12004-10-03 18:46:08 +0000104 /* Initialize installed address chains tree. */
105 zebra_if->ipv4_subnets = route_table_init ();
106
paul718e3742002-12-13 20:15:29 +0000107 ifp->info = zebra_if;
108 return 0;
109}
110
111/* Called when interface is deleted. */
112int
113if_zebra_delete_hook (struct interface *ifp)
114{
hassoeef1fe12004-10-03 18:46:08 +0000115 struct zebra_if *zebra_if;
116
paul718e3742002-12-13 20:15:29 +0000117 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000118 {
119 zebra_if = ifp->info;
120
121 /* Free installed address chains tree. */
122 if (zebra_if->ipv4_subnets)
123 route_table_finish (zebra_if->ipv4_subnets);
124
125 XFREE (MTYPE_TMP, zebra_if);
126 }
127
128 return 0;
129}
130
131/* Tie an interface address to its derived subnet list of addresses. */
132int
133if_subnet_add (struct interface *ifp, struct connected *ifc)
134{
135 struct route_node *rn;
136 struct zebra_if *zebra_if;
137 struct prefix cp;
138 struct list *addr_list;
139
140 assert (ifp && ifp->info && ifc);
141 zebra_if = ifp->info;
142
143 /* Get address derived subnet node and associated address list, while marking
144 address secondary attribute appropriately. */
145 cp = *ifc->address;
146 apply_mask (&cp);
147 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
148
149 if ((addr_list = rn->info))
150 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
151 else
152 {
153 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
154 rn->info = addr_list = list_new ();
155 route_lock_node (rn);
156 }
157
158 /* Tie address at the tail of address list. */
159 listnode_add (addr_list, ifc);
160
161 /* Return list element count. */
162 return (addr_list->count);
163}
164
165/* Untie an interface address from its derived subnet list of addresses. */
166int
167if_subnet_delete (struct interface *ifp, struct connected *ifc)
168{
169 struct route_node *rn;
170 struct zebra_if *zebra_if;
171 struct list *addr_list;
172
173 assert (ifp && ifp->info && ifc);
174 zebra_if = ifp->info;
175
176 /* Get address derived subnet node. */
177 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
178 if (! (rn && rn->info))
179 return -1;
180 route_unlock_node (rn);
181
182 /* Untie address from subnet's address list. */
183 addr_list = rn->info;
184 listnode_delete (addr_list, ifc);
185 route_unlock_node (rn);
186
187 /* Return list element count, if not empty. */
188 if (addr_list->count)
189 {
190 /* If deleted address is primary, mark subsequent one as such and distribute. */
191 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
192 {
193 ifc = (struct connected *) addr_list->head->data;
194 zebra_interface_address_delete_update (ifp, ifc);
195 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
196 zebra_interface_address_add_update (ifp, ifc);
197 }
198
199 return addr_list->count;
200 }
201
202 /* Otherwise, free list and route node. */
203 list_free (addr_list);
204 rn->info = NULL;
205 route_unlock_node (rn);
206
paul718e3742002-12-13 20:15:29 +0000207 return 0;
208}
209
210/* Wake up configured address if it is not in current kernel
211 address. */
212void
213if_addr_wakeup (struct interface *ifp)
214{
215 struct listnode *node;
216 struct connected *ifc;
217 struct prefix *p;
218 int ret;
219
220 for (node = listhead (ifp->connected); node; nextnode (node))
221 {
222 ifc = getdata (node);
223 p = ifc->address;
224
225 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
226 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
227 {
228 /* Address check. */
229 if (p->family == AF_INET)
230 {
231 if (! if_is_up (ifp))
232 {
233 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
234 if_refresh (ifp);
235 }
236
237 ret = if_set_prefix (ifp, ifc);
238 if (ret < 0)
239 {
240 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000241 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000242 continue;
243 }
hassoeef1fe12004-10-03 18:46:08 +0000244
245 /* Add to subnet chain list. */
246 if_subnet_add (ifp, ifc);
247
paul718e3742002-12-13 20:15:29 +0000248 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
249
250 zebra_interface_address_add_update (ifp, ifc);
251
paul2e3b2e42002-12-13 21:03:13 +0000252 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000253 connected_up_ipv4 (ifp, ifc);
254 }
255#ifdef HAVE_IPV6
256 if (p->family == AF_INET6)
257 {
258 if (! if_is_up (ifp))
259 {
260 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
261 if_refresh (ifp);
262 }
263
264 ret = if_prefix_add_ipv6 (ifp, ifc);
265 if (ret < 0)
266 {
267 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000268 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000269 continue;
270 }
271 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
272
273 zebra_interface_address_add_update (ifp, ifc);
274
paul2e3b2e42002-12-13 21:03:13 +0000275 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000276 connected_up_ipv6 (ifp, ifc);
277 }
278#endif /* HAVE_IPV6 */
279 }
280 }
281}
282
283/* Handle interface addition */
284void
285if_add_update (struct interface *ifp)
286{
paul48b33aa2002-12-13 20:52:52 +0000287 struct zebra_if *if_data;
288
289 if_data = ifp->info;
290 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
291 if_set_flags (ifp, IFF_MULTICAST);
292 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
293 if_unset_flags (ifp, IFF_MULTICAST);
294
paul718e3742002-12-13 20:15:29 +0000295 zebra_interface_add_update (ifp);
296
297 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
298 {
299 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
300
301 if_addr_wakeup (ifp);
302
303 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000304 zlog_debug ("interface %s index %d becomes active.",
305 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000306 }
307 else
308 {
309 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000310 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000311 }
312}
313
paul44145db2004-05-09 11:00:23 +0000314
315/* Handle an interface delete event
316 *
317 * This function is only called when support for
318 * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
319 * is available. It is not called on, eg, Solaris.
320 */
321#if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
paul718e3742002-12-13 20:15:29 +0000322void
323if_delete_update (struct interface *ifp)
324{
325 struct listnode *node;
326 struct listnode *next;
hassoeef1fe12004-10-03 18:46:08 +0000327 struct listnode *first;
328 struct listnode *last;
paul718e3742002-12-13 20:15:29 +0000329 struct connected *ifc;
330 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000331 struct route_node *rn;
332 struct zebra_if *zebra_if;
333 struct list *addr_list;
334
335 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000336
337 if (if_is_up(ifp))
338 {
339 zlog_err ("interface %s index %d is still up while being deleted.",
340 ifp->name, ifp->ifindex);
341 return;
342 }
343
344 /* Mark interface as inactive */
345 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
346
347 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000348 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000349 ifp->name, ifp->ifindex);
350
351 /* Delete connected routes from the kernel. */
352 if (ifp->connected)
353 {
hassoeef1fe12004-10-03 18:46:08 +0000354 last = NULL;
355 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000356 {
paul718e3742002-12-13 20:15:29 +0000357 ifc = getdata (node);
358 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000359
paul718e3742002-12-13 20:15:29 +0000360 if (p->family == AF_INET)
hassoeef1fe12004-10-03 18:46:08 +0000361 {
362 rn = route_node_lookup (zebra_if->ipv4_subnets, p);
363 route_unlock_node (rn);
364 addr_list = (struct list *) rn->info;
365
366 /* Remove addresses, secondaries first. */
367 first = listhead (addr_list);
368 for (node = first->next; node || first; node = next)
369 {
370 if (! node)
371 {
372 node = first;
373 first = NULL;
374 }
375 next = node->next;
376
377 ifc = getdata (node);
378 p = ifc->address;
379
380 connected_down_ipv4 (ifp, ifc);
381
382 zebra_interface_address_delete_update (ifp, ifc);
383
384 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
385
386 /* Remove from subnet chain. */
387 list_delete_node (addr_list, node);
388 route_unlock_node (rn);
389
390 /* Remove from interface address list (unconditionally). */
391 listnode_delete (ifp->connected, ifc);
392 connected_free (ifc);
393 }
394
395 /* Free chain list and respective route node. */
396 list_delete (addr_list);
397 rn->info = NULL;
398 route_unlock_node (rn);
399 }
paul718e3742002-12-13 20:15:29 +0000400#ifdef HAVE_IPV6
401 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000402 {
403 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000404
hassoeef1fe12004-10-03 18:46:08 +0000405 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000406
hassoeef1fe12004-10-03 18:46:08 +0000407 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
408
409 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
410 last = node;
411 else
412 {
413 listnode_delete (ifp->connected, ifc);
414 connected_free (ifc);
415 }
paul718e3742002-12-13 20:15:29 +0000416 }
hassoeef1fe12004-10-03 18:46:08 +0000417#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +0000418 }
419 }
420 zebra_interface_delete_update (ifp);
421}
paul44145db2004-05-09 11:00:23 +0000422#endif /* (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK) */
paul718e3742002-12-13 20:15:29 +0000423
424/* Interface is up. */
425void
426if_up (struct interface *ifp)
427{
hasso52dc7ee2004-09-23 19:18:23 +0000428 struct listnode *node;
429 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000430 struct connected *ifc;
431 struct prefix *p;
432
433 /* Notify the protocol daemons. */
434 zebra_interface_up_update (ifp);
435
436 /* Install connected routes to the kernel. */
437 if (ifp->connected)
438 {
439 for (node = listhead (ifp->connected); node; node = next)
440 {
441 next = node->next;
442 ifc = getdata (node);
443 p = ifc->address;
444
445 if (p->family == AF_INET)
446 connected_up_ipv4 (ifp, ifc);
447#ifdef HAVE_IPV6
448 else if (p->family == AF_INET6)
449 connected_up_ipv6 (ifp, ifc);
450#endif /* HAVE_IPV6 */
451 }
452 }
453
454 /* Examine all static routes. */
455 rib_update ();
456}
457
458/* Interface goes down. We have to manage different behavior of based
459 OS. */
460void
461if_down (struct interface *ifp)
462{
hasso52dc7ee2004-09-23 19:18:23 +0000463 struct listnode *node;
464 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000465 struct connected *ifc;
466 struct prefix *p;
467
468 /* Notify to the protocol daemons. */
469 zebra_interface_down_update (ifp);
470
471 /* Delete connected routes from the kernel. */
472 if (ifp->connected)
473 {
474 for (node = listhead (ifp->connected); node; node = next)
475 {
476 next = node->next;
477 ifc = getdata (node);
478 p = ifc->address;
479
480 if (p->family == AF_INET)
481 connected_down_ipv4 (ifp, ifc);
482#ifdef HAVE_IPV6
483 else if (p->family == AF_INET6)
484 connected_down_ipv6 (ifp, ifc);
485#endif /* HAVE_IPV6 */
486 }
487 }
488
489 /* Examine all static routes which direct to the interface. */
490 rib_update ();
491}
492
493void
494if_refresh (struct interface *ifp)
495{
paul2e3b2e42002-12-13 21:03:13 +0000496 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000497 {
498 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000499 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000500 if_down (ifp);
501 }
502 else
503 {
504 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000505 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000506 if_up (ifp);
507 }
508}
509
510/* Printout flag information into vty */
511void
512if_flag_dump_vty (struct vty *vty, unsigned long flag)
513{
514 int separator = 0;
515
516#define IFF_OUT_VTY(X, Y) \
517 if ((X) && (flag & (X))) \
518 { \
519 if (separator) \
520 vty_out (vty, ","); \
521 else \
522 separator = 1; \
523 vty_out (vty, Y); \
524 }
525
526 vty_out (vty, "<");
527 IFF_OUT_VTY (IFF_UP, "UP");
528 IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST");
529 IFF_OUT_VTY (IFF_DEBUG, "DEBUG");
530 IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK");
531 IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT");
532 IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS");
533 IFF_OUT_VTY (IFF_RUNNING, "RUNNING");
534 IFF_OUT_VTY (IFF_NOARP, "NOARP");
535 IFF_OUT_VTY (IFF_PROMISC, "PROMISC");
536 IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI");
537 IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE");
538 IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX");
539 IFF_OUT_VTY (IFF_LINK0, "LINK0");
540 IFF_OUT_VTY (IFF_LINK1, "LINK1");
541 IFF_OUT_VTY (IFF_LINK2, "LINK2");
542 IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST");
paul44145db2004-05-09 11:00:23 +0000543#ifdef SOLARIS_IPV6
544 IFF_OUT_VTY (IFF_IPV4, "IFF_IPv4");
545 IFF_OUT_VTY (IFF_IPV6, "IFF_IPv6");
546#endif /* SOLARIS_IPV6 */
paul718e3742002-12-13 20:15:29 +0000547 vty_out (vty, ">");
548}
549
550/* Output prefix string to vty. */
551int
552prefix_vty_out (struct vty *vty, struct prefix *p)
553{
554 char str[INET6_ADDRSTRLEN];
555
556 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
557 vty_out (vty, "%s", str);
558 return strlen (str);
559}
560
561/* Dump if address information to vty. */
562void
563connected_dump_vty (struct vty *vty, struct connected *connected)
564{
565 struct prefix *p;
566 struct interface *ifp;
567
568 /* Set interface pointer. */
569 ifp = connected->ifp;
570
571 /* Print interface address. */
572 p = connected->address;
573 vty_out (vty, " %s ", prefix_family_str (p));
574 prefix_vty_out (vty, p);
575 vty_out (vty, "/%d", p->prefixlen);
576
577 /* If there is destination address, print it. */
578 p = connected->destination;
579 if (p)
580 {
581 if (p->family == AF_INET)
582 if (ifp->flags & IFF_BROADCAST)
583 {
584 vty_out (vty, " broadcast ");
585 prefix_vty_out (vty, p);
586 }
587
588 if (ifp->flags & IFF_POINTOPOINT)
589 {
590 vty_out (vty, " pointopoint ");
591 prefix_vty_out (vty, p);
592 }
593 }
594
595 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
596 vty_out (vty, " secondary");
597
598 if (connected->label)
599 vty_out (vty, " %s", connected->label);
600
601 vty_out (vty, "%s", VTY_NEWLINE);
602}
603
604#ifdef RTADV
605/* Dump interface ND information to vty. */
606void
607nd_dump_vty (struct vty *vty, struct interface *ifp)
608{
609 struct zebra_if *zif;
610 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000611 int interval;
paul718e3742002-12-13 20:15:29 +0000612
613 zif = (struct zebra_if *) ifp->info;
614 rtadv = &zif->rtadv;
615
616 if (rtadv->AdvSendAdvertisements)
617 {
618 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
619 rtadv->AdvReachableTime, VTY_NEWLINE);
620 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
621 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000622 interval = rtadv->MaxRtrAdvInterval;
623 if (interval % 1000)
624 vty_out (vty, " ND router advertisements are sent every "
625 "%d milliseconds%s", interval,
626 VTY_NEWLINE);
627 else
628 vty_out (vty, " ND router advertisements are sent every "
629 "%d seconds%s", interval / 1000,
630 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000631 vty_out (vty, " ND router advertisements live for %d seconds%s",
632 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
633 if (rtadv->AdvManagedFlag)
634 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
635 VTY_NEWLINE);
636 else
637 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
638 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000639 if (rtadv->AdvHomeAgentFlag)
640 vty_out (vty, " ND router advertisements with "
641 "Home Agent flag bit set.%s",
642 VTY_NEWLINE);
643 if (rtadv->AdvIntervalOption)
644 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
645 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000646 }
647}
648#endif /* RTADV */
649
650/* Interface's information print out to vty interface. */
651void
652if_dump_vty (struct vty *vty, struct interface *ifp)
653{
654#ifdef HAVE_SOCKADDR_DL
655 struct sockaddr_dl *sdl;
656#endif /* HAVE_SOCKADDR_DL */
657 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000658 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000659 struct route_node *rn;
660 struct zebra_if *zebra_if;
661
662 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000663
paul2e3b2e42002-12-13 21:03:13 +0000664 vty_out (vty, "Interface %s is ", ifp->name);
665 if (if_is_up(ifp)) {
666 vty_out (vty, "up, line protocol ");
667
668 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
669 if (if_is_running(ifp))
670 vty_out (vty, "is up%s", VTY_NEWLINE);
671 else
672 vty_out (vty, "is down%s", VTY_NEWLINE);
673 } else {
674 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
675 }
676 } else {
677 vty_out (vty, "down%s", VTY_NEWLINE);
678 }
679
paul718e3742002-12-13 20:15:29 +0000680 if (ifp->desc)
681 vty_out (vty, " Description: %s%s", ifp->desc,
682 VTY_NEWLINE);
683 if (ifp->ifindex <= 0)
684 {
685 vty_out(vty, " index %d pseudo interface%s", ifp->ifindex, VTY_NEWLINE);
686 return;
687 }
688 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
689 {
690 vty_out(vty, " index %d inactive interface%s",
691 ifp->ifindex,
692 VTY_NEWLINE);
693 return;
694 }
695
696 vty_out (vty, " index %d metric %d mtu %d ",
697 ifp->ifindex, ifp->metric, ifp->mtu);
698 if_flag_dump_vty (vty, ifp->flags);
paul44145db2004-05-09 11:00:23 +0000699#ifdef HAVE_IPV6
700 if (ifp->mtu6 != ifp->mtu)
701 vty_out (vty, "mtu6 %d ", ifp->mtu6);
702#endif
703
paul718e3742002-12-13 20:15:29 +0000704 vty_out (vty, "%s", VTY_NEWLINE);
705
706 /* Hardware address. */
707#ifdef HAVE_SOCKADDR_DL
708 sdl = &ifp->sdl;
709 if (sdl != NULL && sdl->sdl_alen != 0)
710 {
711 int i;
712 u_char *ptr;
713
714 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000715 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
716 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000717 vty_out (vty, "%s", VTY_NEWLINE);
718 }
719#else
720 if (ifp->hw_addr_len != 0)
721 {
722 int i;
723
724 vty_out (vty, " HWaddr: ");
725 for (i = 0; i < ifp->hw_addr_len; i++)
726 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
727 vty_out (vty, "%s", VTY_NEWLINE);
728 }
729#endif /* HAVE_SOCKADDR_DL */
730
731 /* Bandwidth in kbps */
732 if (ifp->bandwidth != 0)
733 {
734 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
735 vty_out(vty, "%s", VTY_NEWLINE);
736 }
737
hassoeef1fe12004-10-03 18:46:08 +0000738 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000739 {
hassoeef1fe12004-10-03 18:46:08 +0000740 if (! rn->info)
741 continue;
742
743 for (node = listhead ((struct list *) rn->info); node; nextnode (node))
744 {
745 connected = getdata (node);
746 connected_dump_vty (vty, connected);
747 }
paul718e3742002-12-13 20:15:29 +0000748 }
749
hasso39db97e2004-10-12 20:50:58 +0000750 for (node = listhead (ifp->connected); node; nextnode (node))
751 {
752 connected = getdata (node);
753 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
754 (connected->address->family == AF_INET6))
755 connected_dump_vty (vty, connected);
756 }
757
paul718e3742002-12-13 20:15:29 +0000758#ifdef RTADV
759 nd_dump_vty (vty, ifp);
760#endif /* RTADV */
761
762#ifdef HAVE_PROC_NET_DEV
763 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000764 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
765 "%lu dropped%s",
766 ifp->stats.rx_packets, ifp->stats.rx_multicast,
767 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000768
hasso6f2c27a2005-01-18 13:44:35 +0000769 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000770 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000771 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
772 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000773 ifp->stats.rx_frame_errors, VTY_NEWLINE);
774
775 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000776 ifp->stats.rx_missed_errors, VTY_NEWLINE);
777
hasso6f2c27a2005-01-18 13:44:35 +0000778 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000779 ifp->stats.tx_packets, ifp->stats.tx_bytes,
780 ifp->stats.tx_dropped, VTY_NEWLINE);
781
hasso6f2c27a2005-01-18 13:44:35 +0000782 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
783 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000784 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
785 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000786 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000787
hasso6f2c27a2005-01-18 13:44:35 +0000788 vty_out (vty, " %lu window, %lu collisions%s",
789 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000790#endif /* HAVE_PROC_NET_DEV */
791
792#ifdef HAVE_NET_RT_IFLIST
793#if defined (__bsdi__) || defined (__NetBSD__)
794 /* Statistics print out using sysctl (). */
795 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
796 " multicast packets %qu%s",
797 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
798 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
799 VTY_NEWLINE);
800
801 vty_out (vty, " input errors %qu%s",
802 ifp->stats.ifi_ierrors, VTY_NEWLINE);
803
804 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
805 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
806 ifp->stats.ifi_omcasts, VTY_NEWLINE);
807
808 vty_out (vty, " output errors %qu%s",
809 ifp->stats.ifi_oerrors, VTY_NEWLINE);
810
811 vty_out (vty, " collisions %qu%s",
812 ifp->stats.ifi_collisions, VTY_NEWLINE);
813#else
814 /* Statistics print out using sysctl (). */
815 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
816 " multicast packets %lu%s",
817 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
818 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
819 VTY_NEWLINE);
820
821 vty_out (vty, " input errors %lu%s",
822 ifp->stats.ifi_ierrors, VTY_NEWLINE);
823
824 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
825 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
826 ifp->stats.ifi_omcasts, VTY_NEWLINE);
827
828 vty_out (vty, " output errors %lu%s",
829 ifp->stats.ifi_oerrors, VTY_NEWLINE);
830
831 vty_out (vty, " collisions %lu%s",
832 ifp->stats.ifi_collisions, VTY_NEWLINE);
833#endif /* __bsdi__ || __NetBSD__ */
834#endif /* HAVE_NET_RT_IFLIST */
835}
836
837/* Check supported address family. */
838int
839if_supported_family (int family)
840{
841 if (family == AF_INET)
842 return 1;
843#ifdef HAVE_IPV6
844 if (family == AF_INET6)
845 return 1;
846#endif /* HAVE_IPV6 */
847 return 0;
848}
849
850/* Wrapper hook point for zebra daemon so that ifindex can be set
851 * DEFUN macro not used as extract.pl HAS to ignore this
852 * See also interface_cmd in lib/if.c
853 */
854DEFUN_NOSH (zebra_interface,
855 zebra_interface_cmd,
856 "interface IFNAME",
857 "Select an interface to configure\n"
858 "Interface's name\n")
859{
860 int ret;
861 struct interface * ifp;
862
863 /* Call lib interface() */
864 ret = interface_cmd.func (self, vty, argc, argv);
865
866 ifp = vty->index;
867
868 /* Set ifindex
869 this only happens if interface is NOT in kernel */
870 if (ifp->ifindex == 0)
871 {
872 ifp->ifindex = if_new_intern_ifindex ();
873 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
874 }
875
876 return ret;
877}
878
paul718e3742002-12-13 20:15:29 +0000879struct cmd_node interface_node =
880{
881 INTERFACE_NODE,
882 "%s(config-if)# ",
883 1
884};
885
886/* Show all or specified interface to vty. */
887DEFUN (show_interface, show_interface_cmd,
888 "show interface [IFNAME]",
889 SHOW_STR
890 "Interface status and configuration\n"
891 "Inteface name\n")
892{
hasso52dc7ee2004-09-23 19:18:23 +0000893 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000894 struct interface *ifp;
895
896#ifdef HAVE_PROC_NET_DEV
897 /* If system has interface statistics via proc file system, update
898 statistics. */
899 ifstat_update_proc ();
900#endif /* HAVE_PROC_NET_DEV */
901#ifdef HAVE_NET_RT_IFLIST
902 ifstat_update_sysctl ();
903#endif /* HAVE_NET_RT_IFLIST */
904
905 /* Specified interface print. */
906 if (argc != 0)
907 {
908 ifp = if_lookup_by_name (argv[0]);
909 if (ifp == NULL)
910 {
911 vty_out (vty, "%% Can't find interface %s%s", argv[0],
912 VTY_NEWLINE);
913 return CMD_WARNING;
914 }
915 if_dump_vty (vty, ifp);
916 return CMD_SUCCESS;
917 }
918
919 /* All interface print. */
920 for (node = listhead (iflist); node; nextnode (node))
921 if_dump_vty (vty, getdata (node));
922
923 return CMD_SUCCESS;
924}
925
hassoed9bb6d2005-03-13 19:17:21 +0000926DEFUN (show_interface_desc,
927 show_interface_desc_cmd,
928 "show interface description",
929 SHOW_STR
930 "Interface status and configuration\n"
931 "Interface description\n")
932{
933 struct listnode *node;
934 struct interface *ifp;
935
936 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
937 for (node = listhead (iflist); node; nextnode (node))
938 {
939 int len;
940 ifp = getdata (node);
941
942 len = vty_out (vty, "%s", ifp->name);
943 vty_out (vty, "%*s", (16 - len), " ");
944
945 if (if_is_up(ifp))
946 {
947 vty_out (vty, "up ");
948 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
949 {
950 if (if_is_running(ifp))
951 vty_out (vty, "up ");
952 else
953 vty_out (vty, "down ");
954 }
955 else
956 {
957 vty_out (vty, "unknown ");
958 }
959 }
960 else
961 {
962 vty_out (vty, "down down ");
963 }
964
965 if (ifp->desc)
966 vty_out (vty, "%s", ifp->desc);
967 vty_out (vty, "%s", VTY_NEWLINE);
968 }
969 return CMD_SUCCESS;
970}
971
paul718e3742002-12-13 20:15:29 +0000972DEFUN (multicast,
973 multicast_cmd,
974 "multicast",
975 "Set multicast flag to interface\n")
976{
977 int ret;
978 struct interface *ifp;
979 struct zebra_if *if_data;
980
981 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000982 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000983 {
paul48b33aa2002-12-13 20:52:52 +0000984 ret = if_set_flags (ifp, IFF_MULTICAST);
985 if (ret < 0)
986 {
987 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
988 return CMD_WARNING;
989 }
990 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000991 }
paul718e3742002-12-13 20:15:29 +0000992 if_data = ifp->info;
993 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000994
paul718e3742002-12-13 20:15:29 +0000995 return CMD_SUCCESS;
996}
997
998DEFUN (no_multicast,
999 no_multicast_cmd,
1000 "no multicast",
1001 NO_STR
1002 "Unset multicast flag to interface\n")
1003{
1004 int ret;
1005 struct interface *ifp;
1006 struct zebra_if *if_data;
1007
1008 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001009 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001010 {
paul48b33aa2002-12-13 20:52:52 +00001011 ret = if_unset_flags (ifp, IFF_MULTICAST);
1012 if (ret < 0)
1013 {
1014 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1015 return CMD_WARNING;
1016 }
1017 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001018 }
paul718e3742002-12-13 20:15:29 +00001019 if_data = ifp->info;
1020 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1021
1022 return CMD_SUCCESS;
1023}
1024
paul2e3b2e42002-12-13 21:03:13 +00001025DEFUN (linkdetect,
1026 linkdetect_cmd,
1027 "link-detect",
1028 "Enable link detection on interface\n")
1029{
paul2e3b2e42002-12-13 21:03:13 +00001030 struct interface *ifp;
1031 int if_was_operative;
1032
1033 ifp = (struct interface *) vty->index;
1034 if_was_operative = if_is_operative(ifp);
1035 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1036
1037 /* When linkdetection is enabled, if might come down */
1038 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1039
1040 /* FIXME: Will defer status change forwarding if interface
1041 does not come down! */
1042
1043 return CMD_SUCCESS;
1044}
1045
1046
1047DEFUN (no_linkdetect,
1048 no_linkdetect_cmd,
1049 "no link-detect",
1050 NO_STR
1051 "Disable link detection on interface\n")
1052{
paul2e3b2e42002-12-13 21:03:13 +00001053 struct interface *ifp;
1054 int if_was_operative;
1055
1056 ifp = (struct interface *) vty->index;
1057 if_was_operative = if_is_operative(ifp);
1058 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1059
1060 /* Interface may come up after disabling link detection */
1061 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1062
1063 /* FIXME: see linkdetect_cmd */
1064
1065 return CMD_SUCCESS;
1066}
1067
paul718e3742002-12-13 20:15:29 +00001068DEFUN (shutdown_if,
1069 shutdown_if_cmd,
1070 "shutdown",
1071 "Shutdown the selected interface\n")
1072{
1073 int ret;
1074 struct interface *ifp;
1075 struct zebra_if *if_data;
1076
1077 ifp = (struct interface *) vty->index;
1078 ret = if_unset_flags (ifp, IFF_UP);
1079 if (ret < 0)
1080 {
1081 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1082 return CMD_WARNING;
1083 }
1084 if_refresh (ifp);
1085 if_data = ifp->info;
1086 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1087
1088 return CMD_SUCCESS;
1089}
1090
1091DEFUN (no_shutdown_if,
1092 no_shutdown_if_cmd,
1093 "no shutdown",
1094 NO_STR
1095 "Shutdown the selected interface\n")
1096{
1097 int ret;
1098 struct interface *ifp;
1099 struct zebra_if *if_data;
1100
1101 ifp = (struct interface *) vty->index;
1102 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1103 if (ret < 0)
1104 {
1105 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1106 return CMD_WARNING;
1107 }
1108 if_refresh (ifp);
1109 if_data = ifp->info;
1110 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1111
1112 return CMD_SUCCESS;
1113}
1114
1115DEFUN (bandwidth_if,
1116 bandwidth_if_cmd,
1117 "bandwidth <1-10000000>",
1118 "Set bandwidth informational parameter\n"
1119 "Bandwidth in kilobits\n")
1120{
1121 struct interface *ifp;
1122 unsigned int bandwidth;
1123
1124 ifp = (struct interface *) vty->index;
1125 bandwidth = strtol(argv[0], NULL, 10);
1126
1127 /* bandwidth range is <1-10000000> */
1128 if (bandwidth < 1 || bandwidth > 10000000)
1129 {
1130 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1131 return CMD_WARNING;
1132 }
1133
1134 ifp->bandwidth = bandwidth;
1135
1136 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001137 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001138 zebra_interface_up_update (ifp);
1139
1140 return CMD_SUCCESS;
1141}
1142
1143DEFUN (no_bandwidth_if,
1144 no_bandwidth_if_cmd,
1145 "no bandwidth",
1146 NO_STR
1147 "Set bandwidth informational parameter\n")
1148{
1149 struct interface *ifp;
1150
1151 ifp = (struct interface *) vty->index;
1152
1153 ifp->bandwidth = 0;
1154
1155 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001156 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001157 zebra_interface_up_update (ifp);
1158
1159 return CMD_SUCCESS;
1160}
1161
1162ALIAS (no_bandwidth_if,
1163 no_bandwidth_if_val_cmd,
1164 "no bandwidth <1-10000000>",
1165 NO_STR
1166 "Set bandwidth informational parameter\n"
1167 "Bandwidth in kilobits\n")
1168
1169int
hasso39db97e2004-10-12 20:50:58 +00001170ip_address_install (struct vty *vty, struct interface *ifp,
1171 const char *addr_str, const char *peer_str,
1172 const char *label)
paul718e3742002-12-13 20:15:29 +00001173{
1174 struct prefix_ipv4 cp;
1175 struct connected *ifc;
1176 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001177 int ret;
1178
1179 ret = str2prefix_ipv4 (addr_str, &cp);
1180 if (ret <= 0)
1181 {
1182 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1183 return CMD_WARNING;
1184 }
1185
1186 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1187 if (! ifc)
1188 {
1189 ifc = connected_new ();
1190 ifc->ifp = ifp;
1191
1192 /* Address. */
1193 p = prefix_ipv4_new ();
1194 *p = cp;
1195 ifc->address = (struct prefix *) p;
1196
1197 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001198 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001199 {
1200 p = prefix_ipv4_new ();
1201 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001202 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001203 ifc->destination = (struct prefix *) p;
1204 }
1205
paul718e3742002-12-13 20:15:29 +00001206 /* Label. */
1207 if (label)
1208 ifc->label = strdup (label);
1209
1210 /* Add to linked list. */
1211 listnode_add (ifp->connected, ifc);
1212 }
1213
1214 /* This address is configured from zebra. */
1215 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1216 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1217
1218 /* In case of this route need to install kernel. */
1219 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1220 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1221 {
1222 /* Some system need to up the interface to set IP address. */
1223 if (! if_is_up (ifp))
1224 {
1225 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1226 if_refresh (ifp);
1227 }
1228
1229 ret = if_set_prefix (ifp, ifc);
1230 if (ret < 0)
1231 {
1232 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001233 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001234 return CMD_WARNING;
1235 }
1236
hassoeef1fe12004-10-03 18:46:08 +00001237 /* Add to subnet chain list (while marking secondary attribute). */
1238 if_subnet_add (ifp, ifc);
1239
paul718e3742002-12-13 20:15:29 +00001240 /* 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_ipv4 (ifp, ifc);
1249 }
1250
1251 return CMD_SUCCESS;
1252}
1253
1254int
hasso39db97e2004-10-12 20:50:58 +00001255ip_address_uninstall (struct vty *vty, struct interface *ifp,
1256 const char *addr_str, const char *peer_str,
1257 const char *label)
paul718e3742002-12-13 20:15:29 +00001258{
1259 struct prefix_ipv4 cp;
1260 struct connected *ifc;
1261 int ret;
1262
1263 /* Convert to prefix structure. */
1264 ret = str2prefix_ipv4 (addr_str, &cp);
1265 if (ret <= 0)
1266 {
1267 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1268 return CMD_WARNING;
1269 }
1270
1271 /* Check current interface address. */
1272 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1273 if (! ifc)
1274 {
1275 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1276 return CMD_WARNING;
1277 }
1278
1279 /* This is not configured address. */
1280 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1281 return CMD_WARNING;
1282
1283 /* This is not real address or interface is not active. */
1284 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1285 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1286 {
1287 listnode_delete (ifp->connected, ifc);
1288 connected_free (ifc);
1289 return CMD_WARNING;
1290 }
1291
1292 /* This is real route. */
1293 ret = if_unset_prefix (ifp, ifc);
1294 if (ret < 0)
1295 {
1296 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001297 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001298 return CMD_WARNING;
1299 }
1300
hassoeef1fe12004-10-03 18:46:08 +00001301#if 0
paul718e3742002-12-13 20:15:29 +00001302 /* Redistribute this information. */
1303 zebra_interface_address_delete_update (ifp, ifc);
1304
1305 /* Remove connected route. */
1306 connected_down_ipv4 (ifp, ifc);
1307
1308 /* Free address information. */
1309 listnode_delete (ifp->connected, ifc);
1310 connected_free (ifc);
hassoeef1fe12004-10-03 18:46:08 +00001311#endif
paul718e3742002-12-13 20:15:29 +00001312
1313 return CMD_SUCCESS;
1314}
1315
1316DEFUN (ip_address,
1317 ip_address_cmd,
1318 "ip address A.B.C.D/M",
1319 "Interface Internet Protocol config commands\n"
1320 "Set the IP address of an interface\n"
1321 "IP address (e.g. 10.0.0.1/8)\n")
1322{
hassoeef1fe12004-10-03 18:46:08 +00001323 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001324}
1325
1326DEFUN (no_ip_address,
1327 no_ip_address_cmd,
1328 "no ip address A.B.C.D/M",
1329 NO_STR
1330 "Interface Internet Protocol config commands\n"
1331 "Set the IP address of an interface\n"
1332 "IP Address (e.g. 10.0.0.1/8)")
1333{
hassoeef1fe12004-10-03 18:46:08 +00001334 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001335}
1336
1337#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001338DEFUN (ip_address_label,
1339 ip_address_label_cmd,
1340 "ip address A.B.C.D/M label LINE",
1341 "Interface Internet Protocol config commands\n"
1342 "Set the IP address of an interface\n"
1343 "IP address (e.g. 10.0.0.1/8)\n"
1344 "Label of this address\n"
1345 "Label\n")
1346{
hassoeef1fe12004-10-03 18:46:08 +00001347 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001348}
1349
1350DEFUN (no_ip_address_label,
1351 no_ip_address_label_cmd,
1352 "no ip address A.B.C.D/M label LINE",
1353 NO_STR
1354 "Interface Internet Protocol config commands\n"
1355 "Set the IP address of an interface\n"
1356 "IP address (e.g. 10.0.0.1/8)\n"
1357 "Label of this address\n"
1358 "Label\n")
1359{
hassoeef1fe12004-10-03 18:46:08 +00001360 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001361}
1362#endif /* HAVE_NETLINK */
1363
1364#ifdef HAVE_IPV6
1365int
hasso39db97e2004-10-12 20:50:58 +00001366ipv6_address_install (struct vty *vty, struct interface *ifp,
1367 const char *addr_str, const char *peer_str,
1368 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001369{
1370 struct prefix_ipv6 cp;
1371 struct connected *ifc;
1372 struct prefix_ipv6 *p;
1373 int ret;
1374
1375 ret = str2prefix_ipv6 (addr_str, &cp);
1376 if (ret <= 0)
1377 {
1378 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1379 return CMD_WARNING;
1380 }
1381
1382 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1383 if (! ifc)
1384 {
1385 ifc = connected_new ();
1386 ifc->ifp = ifp;
1387
1388 /* Address. */
1389 p = prefix_ipv6_new ();
1390 *p = cp;
1391 ifc->address = (struct prefix *) p;
1392
1393 /* Secondary. */
1394 if (secondary)
1395 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1396
1397 /* Label. */
1398 if (label)
1399 ifc->label = strdup (label);
1400
1401 /* Add to linked list. */
1402 listnode_add (ifp->connected, ifc);
1403 }
1404
1405 /* This address is configured from zebra. */
1406 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1407 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1408
1409 /* In case of this route need to install kernel. */
1410 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1411 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1412 {
1413 /* Some system need to up the interface to set IP address. */
1414 if (! if_is_up (ifp))
1415 {
1416 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1417 if_refresh (ifp);
1418 }
1419
1420 ret = if_prefix_add_ipv6 (ifp, ifc);
1421
1422 if (ret < 0)
1423 {
1424 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001425 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001426 return CMD_WARNING;
1427 }
1428
1429 /* IP address propery set. */
1430 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1431
1432 /* Update interface address information to protocol daemon. */
1433 zebra_interface_address_add_update (ifp, ifc);
1434
1435 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001436 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001437 connected_up_ipv6 (ifp, ifc);
1438 }
1439
1440 return CMD_SUCCESS;
1441}
1442
1443int
hasso39db97e2004-10-12 20:50:58 +00001444ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1445 const char *addr_str, const char *peer_str,
1446 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001447{
1448 struct prefix_ipv6 cp;
1449 struct connected *ifc;
1450 int ret;
1451
1452 /* Convert to prefix structure. */
1453 ret = str2prefix_ipv6 (addr_str, &cp);
1454 if (ret <= 0)
1455 {
1456 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1457 return CMD_WARNING;
1458 }
1459
1460 /* Check current interface address. */
1461 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1462 if (! ifc)
1463 {
1464 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1465 return CMD_WARNING;
1466 }
1467
1468 /* This is not configured address. */
1469 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1470 return CMD_WARNING;
1471
1472 /* This is not real address or interface is not active. */
1473 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1474 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1475 {
1476 listnode_delete (ifp->connected, ifc);
1477 connected_free (ifc);
1478 return CMD_WARNING;
1479 }
1480
1481 /* This is real route. */
1482 ret = if_prefix_delete_ipv6 (ifp, ifc);
1483 if (ret < 0)
1484 {
1485 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001486 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001487 return CMD_WARNING;
1488 }
1489
1490 /* Redistribute this information. */
1491 zebra_interface_address_delete_update (ifp, ifc);
1492
1493 /* Remove connected route. */
1494 connected_down_ipv6 (ifp, ifc);
1495
1496 /* Free address information. */
1497 listnode_delete (ifp->connected, ifc);
1498 connected_free (ifc);
1499
1500 return CMD_SUCCESS;
1501}
1502
1503DEFUN (ipv6_address,
1504 ipv6_address_cmd,
1505 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001506 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001507 "Set the IP address of an interface\n"
1508 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1509{
1510 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1511}
1512
1513DEFUN (no_ipv6_address,
1514 no_ipv6_address_cmd,
1515 "no ipv6 address X:X::X:X/M",
1516 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001517 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001518 "Set the IP address of an interface\n"
1519 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1520{
1521 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1522}
1523#endif /* HAVE_IPV6 */
1524
paul718e3742002-12-13 20:15:29 +00001525int
1526if_config_write (struct vty *vty)
1527{
hasso52dc7ee2004-09-23 19:18:23 +00001528 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001529 struct interface *ifp;
1530 char buf[BUFSIZ];
1531
1532 for (node = listhead (iflist); node; nextnode (node))
1533 {
1534 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001535 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001536 struct connected *ifc;
1537 struct prefix *p;
1538
1539 ifp = getdata (node);
1540 if_data = ifp->info;
1541
1542 vty_out (vty, "interface %s%s", ifp->name,
1543 VTY_NEWLINE);
1544
1545 if (ifp->desc)
1546 vty_out (vty, " description %s%s", ifp->desc,
1547 VTY_NEWLINE);
1548
1549 /* Assign bandwidth here to avoid unnecessary interface flap
1550 while processing config script */
1551 if (ifp->bandwidth != 0)
1552 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1553
paul2e3b2e42002-12-13 21:03:13 +00001554 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1555 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1556
paul718e3742002-12-13 20:15:29 +00001557 for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
1558 {
1559 ifc = getdata (addrnode);
1560 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1561 {
1562 p = ifc->address;
1563 vty_out (vty, " ip%s address %s/%d",
1564 p->family == AF_INET ? "" : "v6",
1565 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1566 p->prefixlen);
1567
paul718e3742002-12-13 20:15:29 +00001568 if (ifc->label)
1569 vty_out (vty, " label %s", ifc->label);
1570
1571 vty_out (vty, "%s", VTY_NEWLINE);
1572 }
1573 }
1574
1575 if (if_data)
1576 {
1577 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1578 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1579
1580 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1581 vty_out (vty, " %smulticast%s",
1582 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1583 VTY_NEWLINE);
1584 }
1585
1586#ifdef RTADV
1587 rtadv_config_write (vty, ifp);
1588#endif /* RTADV */
1589
hassoca776982004-06-12 14:33:05 +00001590#ifdef HAVE_IRDP
1591 irdp_config_write (vty, ifp);
1592#endif /* IRDP */
1593
paul718e3742002-12-13 20:15:29 +00001594 vty_out (vty, "!%s", VTY_NEWLINE);
1595 }
1596 return 0;
1597}
1598
1599/* Allocate and initialize interface vector. */
1600void
1601zebra_if_init ()
1602{
1603 /* Initialize interface and new hook. */
1604 if_init ();
1605 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1606 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1607
1608 /* Install configuration write function. */
1609 install_node (&interface_node, if_config_write);
1610
1611 install_element (VIEW_NODE, &show_interface_cmd);
1612 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001613 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001614 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001615 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001616 install_default (INTERFACE_NODE);
1617 install_element (INTERFACE_NODE, &interface_desc_cmd);
1618 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1619 install_element (INTERFACE_NODE, &multicast_cmd);
1620 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001621 install_element (INTERFACE_NODE, &linkdetect_cmd);
1622 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001623 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1624 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1625 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1626 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1627 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1628 install_element (INTERFACE_NODE, &ip_address_cmd);
1629 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1630#ifdef HAVE_IPV6
1631 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1632 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1633#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001634#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001635 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001636 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001637#endif /* HAVE_NETLINK */
1638}