blob: 0f294a56fb17068117c7337bcf6ad0517a81c86a [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
paul718e3742002-12-13 20:15:29 +000044
45/* Called when new interface is added. */
46int
47if_zebra_new_hook (struct interface *ifp)
48{
49 struct zebra_if *zebra_if;
50
51 zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
52 memset (zebra_if, 0, sizeof (struct zebra_if));
53
54 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
55 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
56
57#ifdef RTADV
58 {
59 /* Set default router advertise values. */
60 struct rtadvconf *rtadv;
61
62 rtadv = &zebra_if->rtadv;
63
64 rtadv->AdvSendAdvertisements = 0;
65 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
66 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
67 rtadv->AdvIntervalTimer = 0;
68 rtadv->AdvManagedFlag = 0;
69 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000070 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000071 rtadv->AdvLinkMTU = 0;
72 rtadv->AdvReachableTime = 0;
73 rtadv->AdvRetransTimer = 0;
74 rtadv->AdvCurHopLimit = 0;
75 rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
vincent7cee1bb2005-03-25 13:08:53 +000076 rtadv->HomeAgentPreference = 0;
77 rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
78 rtadv->AdvIntervalOption = 0;
paul718e3742002-12-13 20:15:29 +000079
80 rtadv->AdvPrefixList = list_new ();
81 }
82#endif /* RTADV */
83
hassoeef1fe12004-10-03 18:46:08 +000084 /* Initialize installed address chains tree. */
85 zebra_if->ipv4_subnets = route_table_init ();
86
paul718e3742002-12-13 20:15:29 +000087 ifp->info = zebra_if;
88 return 0;
89}
90
91/* Called when interface is deleted. */
92int
93if_zebra_delete_hook (struct interface *ifp)
94{
hassoeef1fe12004-10-03 18:46:08 +000095 struct zebra_if *zebra_if;
96
paul718e3742002-12-13 20:15:29 +000097 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +000098 {
99 zebra_if = ifp->info;
100
101 /* Free installed address chains tree. */
102 if (zebra_if->ipv4_subnets)
103 route_table_finish (zebra_if->ipv4_subnets);
104
105 XFREE (MTYPE_TMP, zebra_if);
106 }
107
108 return 0;
109}
110
111/* Tie an interface address to its derived subnet list of addresses. */
112int
113if_subnet_add (struct interface *ifp, struct connected *ifc)
114{
115 struct route_node *rn;
116 struct zebra_if *zebra_if;
117 struct prefix cp;
118 struct list *addr_list;
119
120 assert (ifp && ifp->info && ifc);
121 zebra_if = ifp->info;
122
123 /* Get address derived subnet node and associated address list, while marking
124 address secondary attribute appropriately. */
125 cp = *ifc->address;
126 apply_mask (&cp);
127 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
128
129 if ((addr_list = rn->info))
130 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
131 else
132 {
133 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
134 rn->info = addr_list = list_new ();
135 route_lock_node (rn);
136 }
137
138 /* Tie address at the tail of address list. */
139 listnode_add (addr_list, ifc);
140
141 /* Return list element count. */
142 return (addr_list->count);
143}
144
145/* Untie an interface address from its derived subnet list of addresses. */
146int
147if_subnet_delete (struct interface *ifp, struct connected *ifc)
148{
149 struct route_node *rn;
150 struct zebra_if *zebra_if;
151 struct list *addr_list;
152
153 assert (ifp && ifp->info && ifc);
154 zebra_if = ifp->info;
155
156 /* Get address derived subnet node. */
157 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
158 if (! (rn && rn->info))
159 return -1;
160 route_unlock_node (rn);
161
162 /* Untie address from subnet's address list. */
163 addr_list = rn->info;
164 listnode_delete (addr_list, ifc);
165 route_unlock_node (rn);
166
167 /* Return list element count, if not empty. */
168 if (addr_list->count)
169 {
170 /* If deleted address is primary, mark subsequent one as such and distribute. */
171 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
172 {
173 ifc = (struct connected *) addr_list->head->data;
174 zebra_interface_address_delete_update (ifp, ifc);
175 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
176 zebra_interface_address_add_update (ifp, ifc);
177 }
178
179 return addr_list->count;
180 }
181
182 /* Otherwise, free list and route node. */
183 list_free (addr_list);
184 rn->info = NULL;
185 route_unlock_node (rn);
186
paul718e3742002-12-13 20:15:29 +0000187 return 0;
188}
189
190/* Wake up configured address if it is not in current kernel
191 address. */
192void
193if_addr_wakeup (struct interface *ifp)
194{
195 struct listnode *node;
196 struct connected *ifc;
197 struct prefix *p;
198 int ret;
199
200 for (node = listhead (ifp->connected); node; nextnode (node))
201 {
202 ifc = getdata (node);
203 p = ifc->address;
204
205 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
206 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
207 {
208 /* Address check. */
209 if (p->family == AF_INET)
210 {
211 if (! if_is_up (ifp))
212 {
213 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
214 if_refresh (ifp);
215 }
216
217 ret = if_set_prefix (ifp, ifc);
218 if (ret < 0)
219 {
220 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000221 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000222 continue;
223 }
hassoeef1fe12004-10-03 18:46:08 +0000224
225 /* Add to subnet chain list. */
226 if_subnet_add (ifp, ifc);
227
paul718e3742002-12-13 20:15:29 +0000228 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
229
230 zebra_interface_address_add_update (ifp, ifc);
231
paul2e3b2e42002-12-13 21:03:13 +0000232 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000233 connected_up_ipv4 (ifp, ifc);
234 }
235#ifdef HAVE_IPV6
236 if (p->family == AF_INET6)
237 {
238 if (! if_is_up (ifp))
239 {
240 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
241 if_refresh (ifp);
242 }
243
244 ret = if_prefix_add_ipv6 (ifp, ifc);
245 if (ret < 0)
246 {
247 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000248 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000249 continue;
250 }
251 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
252
253 zebra_interface_address_add_update (ifp, ifc);
254
paul2e3b2e42002-12-13 21:03:13 +0000255 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000256 connected_up_ipv6 (ifp, ifc);
257 }
258#endif /* HAVE_IPV6 */
259 }
260 }
261}
262
263/* Handle interface addition */
264void
265if_add_update (struct interface *ifp)
266{
paul48b33aa2002-12-13 20:52:52 +0000267 struct zebra_if *if_data;
268
269 if_data = ifp->info;
270 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
271 if_set_flags (ifp, IFF_MULTICAST);
272 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
273 if_unset_flags (ifp, IFF_MULTICAST);
274
paul718e3742002-12-13 20:15:29 +0000275 zebra_interface_add_update (ifp);
276
277 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
278 {
279 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
280
281 if_addr_wakeup (ifp);
282
283 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000284 zlog_debug ("interface %s index %d becomes active.",
285 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000286 }
287 else
288 {
289 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000290 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000291 }
292}
293
paul44145db2004-05-09 11:00:23 +0000294
295/* Handle an interface delete event
296 *
297 * This function is only called when support for
298 * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
299 * is available. It is not called on, eg, Solaris.
300 */
301#if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
paul718e3742002-12-13 20:15:29 +0000302void
303if_delete_update (struct interface *ifp)
304{
305 struct listnode *node;
306 struct listnode *next;
hassoeef1fe12004-10-03 18:46:08 +0000307 struct listnode *first;
308 struct listnode *last;
paul718e3742002-12-13 20:15:29 +0000309 struct connected *ifc;
310 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000311 struct route_node *rn;
312 struct zebra_if *zebra_if;
313 struct list *addr_list;
314
315 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000316
317 if (if_is_up(ifp))
318 {
319 zlog_err ("interface %s index %d is still up while being deleted.",
320 ifp->name, ifp->ifindex);
321 return;
322 }
323
324 /* Mark interface as inactive */
325 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
326
327 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000328 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000329 ifp->name, ifp->ifindex);
330
331 /* Delete connected routes from the kernel. */
332 if (ifp->connected)
333 {
hassoeef1fe12004-10-03 18:46:08 +0000334 last = NULL;
335 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000336 {
paul718e3742002-12-13 20:15:29 +0000337 ifc = getdata (node);
338 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000339
paul718e3742002-12-13 20:15:29 +0000340 if (p->family == AF_INET)
hassoeef1fe12004-10-03 18:46:08 +0000341 {
342 rn = route_node_lookup (zebra_if->ipv4_subnets, p);
343 route_unlock_node (rn);
344 addr_list = (struct list *) rn->info;
345
346 /* Remove addresses, secondaries first. */
347 first = listhead (addr_list);
348 for (node = first->next; node || first; node = next)
349 {
350 if (! node)
351 {
352 node = first;
353 first = NULL;
354 }
355 next = node->next;
356
357 ifc = getdata (node);
358 p = ifc->address;
359
360 connected_down_ipv4 (ifp, ifc);
361
362 zebra_interface_address_delete_update (ifp, ifc);
363
364 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
365
366 /* Remove from subnet chain. */
367 list_delete_node (addr_list, node);
368 route_unlock_node (rn);
369
370 /* Remove from interface address list (unconditionally). */
371 listnode_delete (ifp->connected, ifc);
372 connected_free (ifc);
373 }
374
375 /* Free chain list and respective route node. */
376 list_delete (addr_list);
377 rn->info = NULL;
378 route_unlock_node (rn);
379 }
paul718e3742002-12-13 20:15:29 +0000380#ifdef HAVE_IPV6
381 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000382 {
383 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000384
hassoeef1fe12004-10-03 18:46:08 +0000385 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000386
hassoeef1fe12004-10-03 18:46:08 +0000387 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
388
389 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
390 last = node;
391 else
392 {
393 listnode_delete (ifp->connected, ifc);
394 connected_free (ifc);
395 }
paul718e3742002-12-13 20:15:29 +0000396 }
hassoeef1fe12004-10-03 18:46:08 +0000397#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +0000398 }
399 }
400 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000401
402 /* Update ifindex after distributing the delete message. This is in
403 case any client needs to have the old value of ifindex available
404 while processing the deletion. Each client daemon is responsible
405 for setting ifindex to IFINDEX_INTERNAL after processing the
406 interface deletion message. */
407 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000408}
paul44145db2004-05-09 11:00:23 +0000409#endif /* (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK) */
paul718e3742002-12-13 20:15:29 +0000410
411/* Interface is up. */
412void
413if_up (struct interface *ifp)
414{
hasso52dc7ee2004-09-23 19:18:23 +0000415 struct listnode *node;
416 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000417 struct connected *ifc;
418 struct prefix *p;
419
420 /* Notify the protocol daemons. */
421 zebra_interface_up_update (ifp);
422
423 /* Install connected routes to the kernel. */
424 if (ifp->connected)
425 {
426 for (node = listhead (ifp->connected); node; node = next)
427 {
428 next = node->next;
429 ifc = getdata (node);
430 p = ifc->address;
431
432 if (p->family == AF_INET)
433 connected_up_ipv4 (ifp, ifc);
434#ifdef HAVE_IPV6
435 else if (p->family == AF_INET6)
436 connected_up_ipv6 (ifp, ifc);
437#endif /* HAVE_IPV6 */
438 }
439 }
440
441 /* Examine all static routes. */
442 rib_update ();
443}
444
445/* Interface goes down. We have to manage different behavior of based
446 OS. */
447void
448if_down (struct interface *ifp)
449{
hasso52dc7ee2004-09-23 19:18:23 +0000450 struct listnode *node;
451 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000452 struct connected *ifc;
453 struct prefix *p;
454
455 /* Notify to the protocol daemons. */
456 zebra_interface_down_update (ifp);
457
458 /* Delete connected routes from the kernel. */
459 if (ifp->connected)
460 {
461 for (node = listhead (ifp->connected); node; node = next)
462 {
463 next = node->next;
464 ifc = getdata (node);
465 p = ifc->address;
466
467 if (p->family == AF_INET)
468 connected_down_ipv4 (ifp, ifc);
469#ifdef HAVE_IPV6
470 else if (p->family == AF_INET6)
471 connected_down_ipv6 (ifp, ifc);
472#endif /* HAVE_IPV6 */
473 }
474 }
475
476 /* Examine all static routes which direct to the interface. */
477 rib_update ();
478}
479
480void
481if_refresh (struct interface *ifp)
482{
paul2e3b2e42002-12-13 21:03:13 +0000483 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000484 {
485 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000486 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000487 if_down (ifp);
488 }
489 else
490 {
491 if_get_flags (ifp);
paul2e3b2e42002-12-13 21:03:13 +0000492 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000493 if_up (ifp);
494 }
495}
496
497/* Printout flag information into vty */
498void
499if_flag_dump_vty (struct vty *vty, unsigned long flag)
500{
501 int separator = 0;
502
503#define IFF_OUT_VTY(X, Y) \
504 if ((X) && (flag & (X))) \
505 { \
506 if (separator) \
507 vty_out (vty, ","); \
508 else \
509 separator = 1; \
510 vty_out (vty, Y); \
511 }
512
513 vty_out (vty, "<");
514 IFF_OUT_VTY (IFF_UP, "UP");
515 IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST");
516 IFF_OUT_VTY (IFF_DEBUG, "DEBUG");
517 IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK");
518 IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT");
519 IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS");
520 IFF_OUT_VTY (IFF_RUNNING, "RUNNING");
521 IFF_OUT_VTY (IFF_NOARP, "NOARP");
522 IFF_OUT_VTY (IFF_PROMISC, "PROMISC");
523 IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI");
524 IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE");
525 IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX");
526 IFF_OUT_VTY (IFF_LINK0, "LINK0");
527 IFF_OUT_VTY (IFF_LINK1, "LINK1");
528 IFF_OUT_VTY (IFF_LINK2, "LINK2");
529 IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST");
paul44145db2004-05-09 11:00:23 +0000530#ifdef SOLARIS_IPV6
531 IFF_OUT_VTY (IFF_IPV4, "IFF_IPv4");
532 IFF_OUT_VTY (IFF_IPV6, "IFF_IPv6");
533#endif /* SOLARIS_IPV6 */
paul718e3742002-12-13 20:15:29 +0000534 vty_out (vty, ">");
535}
536
537/* Output prefix string to vty. */
538int
539prefix_vty_out (struct vty *vty, struct prefix *p)
540{
541 char str[INET6_ADDRSTRLEN];
542
543 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
544 vty_out (vty, "%s", str);
545 return strlen (str);
546}
547
548/* Dump if address information to vty. */
549void
550connected_dump_vty (struct vty *vty, struct connected *connected)
551{
552 struct prefix *p;
553 struct interface *ifp;
554
555 /* Set interface pointer. */
556 ifp = connected->ifp;
557
558 /* Print interface address. */
559 p = connected->address;
560 vty_out (vty, " %s ", prefix_family_str (p));
561 prefix_vty_out (vty, p);
562 vty_out (vty, "/%d", p->prefixlen);
563
564 /* If there is destination address, print it. */
565 p = connected->destination;
566 if (p)
567 {
568 if (p->family == AF_INET)
569 if (ifp->flags & IFF_BROADCAST)
570 {
571 vty_out (vty, " broadcast ");
572 prefix_vty_out (vty, p);
573 }
574
575 if (ifp->flags & IFF_POINTOPOINT)
576 {
577 vty_out (vty, " pointopoint ");
578 prefix_vty_out (vty, p);
579 }
580 }
581
582 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
583 vty_out (vty, " secondary");
584
585 if (connected->label)
586 vty_out (vty, " %s", connected->label);
587
588 vty_out (vty, "%s", VTY_NEWLINE);
589}
590
591#ifdef RTADV
592/* Dump interface ND information to vty. */
593void
594nd_dump_vty (struct vty *vty, struct interface *ifp)
595{
596 struct zebra_if *zif;
597 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000598 int interval;
paul718e3742002-12-13 20:15:29 +0000599
600 zif = (struct zebra_if *) ifp->info;
601 rtadv = &zif->rtadv;
602
603 if (rtadv->AdvSendAdvertisements)
604 {
605 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
606 rtadv->AdvReachableTime, VTY_NEWLINE);
607 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
608 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000609 interval = rtadv->MaxRtrAdvInterval;
610 if (interval % 1000)
611 vty_out (vty, " ND router advertisements are sent every "
612 "%d milliseconds%s", interval,
613 VTY_NEWLINE);
614 else
615 vty_out (vty, " ND router advertisements are sent every "
616 "%d seconds%s", interval / 1000,
617 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000618 vty_out (vty, " ND router advertisements live for %d seconds%s",
619 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
620 if (rtadv->AdvManagedFlag)
621 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
622 VTY_NEWLINE);
623 else
624 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
625 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000626 if (rtadv->AdvHomeAgentFlag)
627 vty_out (vty, " ND router advertisements with "
628 "Home Agent flag bit set.%s",
629 VTY_NEWLINE);
630 if (rtadv->AdvIntervalOption)
631 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
632 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000633 }
634}
635#endif /* RTADV */
636
637/* Interface's information print out to vty interface. */
638void
639if_dump_vty (struct vty *vty, struct interface *ifp)
640{
641#ifdef HAVE_SOCKADDR_DL
642 struct sockaddr_dl *sdl;
643#endif /* HAVE_SOCKADDR_DL */
644 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000645 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000646 struct route_node *rn;
647 struct zebra_if *zebra_if;
648
649 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000650
paul2e3b2e42002-12-13 21:03:13 +0000651 vty_out (vty, "Interface %s is ", ifp->name);
652 if (if_is_up(ifp)) {
653 vty_out (vty, "up, line protocol ");
654
655 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
656 if (if_is_running(ifp))
657 vty_out (vty, "is up%s", VTY_NEWLINE);
658 else
659 vty_out (vty, "is down%s", VTY_NEWLINE);
660 } else {
661 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
662 }
663 } else {
664 vty_out (vty, "down%s", VTY_NEWLINE);
665 }
666
paul718e3742002-12-13 20:15:29 +0000667 if (ifp->desc)
668 vty_out (vty, " Description: %s%s", ifp->desc,
669 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000670 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000671 {
ajsd2fc8892005-04-02 18:38:43 +0000672 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000673 return;
674 }
675 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
676 {
677 vty_out(vty, " index %d inactive interface%s",
678 ifp->ifindex,
679 VTY_NEWLINE);
680 return;
681 }
682
683 vty_out (vty, " index %d metric %d mtu %d ",
684 ifp->ifindex, ifp->metric, ifp->mtu);
685 if_flag_dump_vty (vty, ifp->flags);
paul44145db2004-05-09 11:00:23 +0000686#ifdef HAVE_IPV6
687 if (ifp->mtu6 != ifp->mtu)
688 vty_out (vty, "mtu6 %d ", ifp->mtu6);
689#endif
690
paul718e3742002-12-13 20:15:29 +0000691 vty_out (vty, "%s", VTY_NEWLINE);
692
693 /* Hardware address. */
694#ifdef HAVE_SOCKADDR_DL
695 sdl = &ifp->sdl;
696 if (sdl != NULL && sdl->sdl_alen != 0)
697 {
698 int i;
699 u_char *ptr;
700
701 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000702 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
703 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000704 vty_out (vty, "%s", VTY_NEWLINE);
705 }
706#else
707 if (ifp->hw_addr_len != 0)
708 {
709 int i;
710
711 vty_out (vty, " HWaddr: ");
712 for (i = 0; i < ifp->hw_addr_len; i++)
713 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
714 vty_out (vty, "%s", VTY_NEWLINE);
715 }
716#endif /* HAVE_SOCKADDR_DL */
717
718 /* Bandwidth in kbps */
719 if (ifp->bandwidth != 0)
720 {
721 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
722 vty_out(vty, "%s", VTY_NEWLINE);
723 }
724
hassoeef1fe12004-10-03 18:46:08 +0000725 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000726 {
hassoeef1fe12004-10-03 18:46:08 +0000727 if (! rn->info)
728 continue;
729
730 for (node = listhead ((struct list *) rn->info); node; nextnode (node))
731 {
732 connected = getdata (node);
733 connected_dump_vty (vty, connected);
734 }
paul718e3742002-12-13 20:15:29 +0000735 }
736
hasso39db97e2004-10-12 20:50:58 +0000737 for (node = listhead (ifp->connected); node; nextnode (node))
738 {
739 connected = getdata (node);
740 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
741 (connected->address->family == AF_INET6))
742 connected_dump_vty (vty, connected);
743 }
744
paul718e3742002-12-13 20:15:29 +0000745#ifdef RTADV
746 nd_dump_vty (vty, ifp);
747#endif /* RTADV */
748
749#ifdef HAVE_PROC_NET_DEV
750 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000751 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
752 "%lu dropped%s",
753 ifp->stats.rx_packets, ifp->stats.rx_multicast,
754 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000755
hasso6f2c27a2005-01-18 13:44:35 +0000756 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000757 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000758 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
759 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000760 ifp->stats.rx_frame_errors, VTY_NEWLINE);
761
762 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000763 ifp->stats.rx_missed_errors, VTY_NEWLINE);
764
hasso6f2c27a2005-01-18 13:44:35 +0000765 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000766 ifp->stats.tx_packets, ifp->stats.tx_bytes,
767 ifp->stats.tx_dropped, VTY_NEWLINE);
768
hasso6f2c27a2005-01-18 13:44:35 +0000769 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
770 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000771 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
772 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000773 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000774
hasso6f2c27a2005-01-18 13:44:35 +0000775 vty_out (vty, " %lu window, %lu collisions%s",
776 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000777#endif /* HAVE_PROC_NET_DEV */
778
779#ifdef HAVE_NET_RT_IFLIST
780#if defined (__bsdi__) || defined (__NetBSD__)
781 /* Statistics print out using sysctl (). */
782 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
783 " multicast packets %qu%s",
784 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
785 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
786 VTY_NEWLINE);
787
788 vty_out (vty, " input errors %qu%s",
789 ifp->stats.ifi_ierrors, VTY_NEWLINE);
790
791 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
792 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
793 ifp->stats.ifi_omcasts, VTY_NEWLINE);
794
795 vty_out (vty, " output errors %qu%s",
796 ifp->stats.ifi_oerrors, VTY_NEWLINE);
797
798 vty_out (vty, " collisions %qu%s",
799 ifp->stats.ifi_collisions, VTY_NEWLINE);
800#else
801 /* Statistics print out using sysctl (). */
802 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
803 " multicast packets %lu%s",
804 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
805 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
806 VTY_NEWLINE);
807
808 vty_out (vty, " input errors %lu%s",
809 ifp->stats.ifi_ierrors, VTY_NEWLINE);
810
811 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
812 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
813 ifp->stats.ifi_omcasts, VTY_NEWLINE);
814
815 vty_out (vty, " output errors %lu%s",
816 ifp->stats.ifi_oerrors, VTY_NEWLINE);
817
818 vty_out (vty, " collisions %lu%s",
819 ifp->stats.ifi_collisions, VTY_NEWLINE);
820#endif /* __bsdi__ || __NetBSD__ */
821#endif /* HAVE_NET_RT_IFLIST */
822}
823
824/* Check supported address family. */
825int
826if_supported_family (int family)
827{
828 if (family == AF_INET)
829 return 1;
830#ifdef HAVE_IPV6
831 if (family == AF_INET6)
832 return 1;
833#endif /* HAVE_IPV6 */
834 return 0;
835}
836
837/* Wrapper hook point for zebra daemon so that ifindex can be set
838 * DEFUN macro not used as extract.pl HAS to ignore this
839 * See also interface_cmd in lib/if.c
840 */
841DEFUN_NOSH (zebra_interface,
842 zebra_interface_cmd,
843 "interface IFNAME",
844 "Select an interface to configure\n"
845 "Interface's name\n")
846{
847 int ret;
848 struct interface * ifp;
849
850 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000851 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
852 return ret;
paul718e3742002-12-13 20:15:29 +0000853
854 ifp = vty->index;
855
ajsd2fc8892005-04-02 18:38:43 +0000856 if (ifp->ifindex == IFINDEX_INTERNAL)
857 /* Is this really necessary? Shouldn't status be initialized to 0
858 in that case? */
859 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000860
861 return ret;
862}
863
paul718e3742002-12-13 20:15:29 +0000864struct cmd_node interface_node =
865{
866 INTERFACE_NODE,
867 "%s(config-if)# ",
868 1
869};
870
871/* Show all or specified interface to vty. */
872DEFUN (show_interface, show_interface_cmd,
873 "show interface [IFNAME]",
874 SHOW_STR
875 "Interface status and configuration\n"
876 "Inteface name\n")
877{
hasso52dc7ee2004-09-23 19:18:23 +0000878 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000879 struct interface *ifp;
880
881#ifdef HAVE_PROC_NET_DEV
882 /* If system has interface statistics via proc file system, update
883 statistics. */
884 ifstat_update_proc ();
885#endif /* HAVE_PROC_NET_DEV */
886#ifdef HAVE_NET_RT_IFLIST
887 ifstat_update_sysctl ();
888#endif /* HAVE_NET_RT_IFLIST */
889
890 /* Specified interface print. */
891 if (argc != 0)
892 {
893 ifp = if_lookup_by_name (argv[0]);
894 if (ifp == NULL)
895 {
896 vty_out (vty, "%% Can't find interface %s%s", argv[0],
897 VTY_NEWLINE);
898 return CMD_WARNING;
899 }
900 if_dump_vty (vty, ifp);
901 return CMD_SUCCESS;
902 }
903
904 /* All interface print. */
905 for (node = listhead (iflist); node; nextnode (node))
906 if_dump_vty (vty, getdata (node));
907
908 return CMD_SUCCESS;
909}
910
hassoed9bb6d2005-03-13 19:17:21 +0000911DEFUN (show_interface_desc,
912 show_interface_desc_cmd,
913 "show interface description",
914 SHOW_STR
915 "Interface status and configuration\n"
916 "Interface description\n")
917{
918 struct listnode *node;
919 struct interface *ifp;
920
921 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
922 for (node = listhead (iflist); node; nextnode (node))
923 {
924 int len;
925 ifp = getdata (node);
926
927 len = vty_out (vty, "%s", ifp->name);
928 vty_out (vty, "%*s", (16 - len), " ");
929
930 if (if_is_up(ifp))
931 {
932 vty_out (vty, "up ");
933 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
934 {
935 if (if_is_running(ifp))
936 vty_out (vty, "up ");
937 else
938 vty_out (vty, "down ");
939 }
940 else
941 {
942 vty_out (vty, "unknown ");
943 }
944 }
945 else
946 {
947 vty_out (vty, "down down ");
948 }
949
950 if (ifp->desc)
951 vty_out (vty, "%s", ifp->desc);
952 vty_out (vty, "%s", VTY_NEWLINE);
953 }
954 return CMD_SUCCESS;
955}
956
paul718e3742002-12-13 20:15:29 +0000957DEFUN (multicast,
958 multicast_cmd,
959 "multicast",
960 "Set multicast flag to interface\n")
961{
962 int ret;
963 struct interface *ifp;
964 struct zebra_if *if_data;
965
966 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000967 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000968 {
paul48b33aa2002-12-13 20:52:52 +0000969 ret = if_set_flags (ifp, IFF_MULTICAST);
970 if (ret < 0)
971 {
972 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
973 return CMD_WARNING;
974 }
975 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000976 }
paul718e3742002-12-13 20:15:29 +0000977 if_data = ifp->info;
978 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000979
paul718e3742002-12-13 20:15:29 +0000980 return CMD_SUCCESS;
981}
982
983DEFUN (no_multicast,
984 no_multicast_cmd,
985 "no multicast",
986 NO_STR
987 "Unset multicast flag to interface\n")
988{
989 int ret;
990 struct interface *ifp;
991 struct zebra_if *if_data;
992
993 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000994 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000995 {
paul48b33aa2002-12-13 20:52:52 +0000996 ret = if_unset_flags (ifp, IFF_MULTICAST);
997 if (ret < 0)
998 {
999 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1000 return CMD_WARNING;
1001 }
1002 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001003 }
paul718e3742002-12-13 20:15:29 +00001004 if_data = ifp->info;
1005 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1006
1007 return CMD_SUCCESS;
1008}
1009
paul2e3b2e42002-12-13 21:03:13 +00001010DEFUN (linkdetect,
1011 linkdetect_cmd,
1012 "link-detect",
1013 "Enable link detection on interface\n")
1014{
paul2e3b2e42002-12-13 21:03:13 +00001015 struct interface *ifp;
1016 int if_was_operative;
1017
1018 ifp = (struct interface *) vty->index;
1019 if_was_operative = if_is_operative(ifp);
1020 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1021
1022 /* When linkdetection is enabled, if might come down */
1023 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1024
1025 /* FIXME: Will defer status change forwarding if interface
1026 does not come down! */
1027
1028 return CMD_SUCCESS;
1029}
1030
1031
1032DEFUN (no_linkdetect,
1033 no_linkdetect_cmd,
1034 "no link-detect",
1035 NO_STR
1036 "Disable link detection on interface\n")
1037{
paul2e3b2e42002-12-13 21:03:13 +00001038 struct interface *ifp;
1039 int if_was_operative;
1040
1041 ifp = (struct interface *) vty->index;
1042 if_was_operative = if_is_operative(ifp);
1043 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1044
1045 /* Interface may come up after disabling link detection */
1046 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1047
1048 /* FIXME: see linkdetect_cmd */
1049
1050 return CMD_SUCCESS;
1051}
1052
paul718e3742002-12-13 20:15:29 +00001053DEFUN (shutdown_if,
1054 shutdown_if_cmd,
1055 "shutdown",
1056 "Shutdown the selected interface\n")
1057{
1058 int ret;
1059 struct interface *ifp;
1060 struct zebra_if *if_data;
1061
1062 ifp = (struct interface *) vty->index;
1063 ret = if_unset_flags (ifp, IFF_UP);
1064 if (ret < 0)
1065 {
1066 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1067 return CMD_WARNING;
1068 }
1069 if_refresh (ifp);
1070 if_data = ifp->info;
1071 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1072
1073 return CMD_SUCCESS;
1074}
1075
1076DEFUN (no_shutdown_if,
1077 no_shutdown_if_cmd,
1078 "no shutdown",
1079 NO_STR
1080 "Shutdown the selected interface\n")
1081{
1082 int ret;
1083 struct interface *ifp;
1084 struct zebra_if *if_data;
1085
1086 ifp = (struct interface *) vty->index;
1087 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1088 if (ret < 0)
1089 {
1090 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1091 return CMD_WARNING;
1092 }
1093 if_refresh (ifp);
1094 if_data = ifp->info;
1095 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1096
1097 return CMD_SUCCESS;
1098}
1099
1100DEFUN (bandwidth_if,
1101 bandwidth_if_cmd,
1102 "bandwidth <1-10000000>",
1103 "Set bandwidth informational parameter\n"
1104 "Bandwidth in kilobits\n")
1105{
1106 struct interface *ifp;
1107 unsigned int bandwidth;
1108
1109 ifp = (struct interface *) vty->index;
1110 bandwidth = strtol(argv[0], NULL, 10);
1111
1112 /* bandwidth range is <1-10000000> */
1113 if (bandwidth < 1 || bandwidth > 10000000)
1114 {
1115 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1116 return CMD_WARNING;
1117 }
1118
1119 ifp->bandwidth = bandwidth;
1120
1121 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001122 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001123 zebra_interface_up_update (ifp);
1124
1125 return CMD_SUCCESS;
1126}
1127
1128DEFUN (no_bandwidth_if,
1129 no_bandwidth_if_cmd,
1130 "no bandwidth",
1131 NO_STR
1132 "Set bandwidth informational parameter\n")
1133{
1134 struct interface *ifp;
1135
1136 ifp = (struct interface *) vty->index;
1137
1138 ifp->bandwidth = 0;
1139
1140 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001141 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001142 zebra_interface_up_update (ifp);
1143
1144 return CMD_SUCCESS;
1145}
1146
1147ALIAS (no_bandwidth_if,
1148 no_bandwidth_if_val_cmd,
1149 "no bandwidth <1-10000000>",
1150 NO_STR
1151 "Set bandwidth informational parameter\n"
1152 "Bandwidth in kilobits\n")
1153
1154int
hasso39db97e2004-10-12 20:50:58 +00001155ip_address_install (struct vty *vty, struct interface *ifp,
1156 const char *addr_str, const char *peer_str,
1157 const char *label)
paul718e3742002-12-13 20:15:29 +00001158{
1159 struct prefix_ipv4 cp;
1160 struct connected *ifc;
1161 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001162 int ret;
1163
1164 ret = str2prefix_ipv4 (addr_str, &cp);
1165 if (ret <= 0)
1166 {
1167 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1168 return CMD_WARNING;
1169 }
1170
1171 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1172 if (! ifc)
1173 {
1174 ifc = connected_new ();
1175 ifc->ifp = ifp;
1176
1177 /* Address. */
1178 p = prefix_ipv4_new ();
1179 *p = cp;
1180 ifc->address = (struct prefix *) p;
1181
1182 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001183 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001184 {
1185 p = prefix_ipv4_new ();
1186 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001187 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001188 ifc->destination = (struct prefix *) p;
1189 }
1190
paul718e3742002-12-13 20:15:29 +00001191 /* Label. */
1192 if (label)
1193 ifc->label = strdup (label);
1194
1195 /* Add to linked list. */
1196 listnode_add (ifp->connected, ifc);
1197 }
1198
1199 /* This address is configured from zebra. */
1200 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1201 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1202
1203 /* In case of this route need to install kernel. */
1204 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1205 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1206 {
1207 /* Some system need to up the interface to set IP address. */
1208 if (! if_is_up (ifp))
1209 {
1210 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1211 if_refresh (ifp);
1212 }
1213
1214 ret = if_set_prefix (ifp, ifc);
1215 if (ret < 0)
1216 {
1217 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001218 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001219 return CMD_WARNING;
1220 }
1221
hassoeef1fe12004-10-03 18:46:08 +00001222 /* Add to subnet chain list (while marking secondary attribute). */
1223 if_subnet_add (ifp, ifc);
1224
paul718e3742002-12-13 20:15:29 +00001225 /* IP address propery set. */
1226 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1227
1228 /* Update interface address information to protocol daemon. */
1229 zebra_interface_address_add_update (ifp, ifc);
1230
1231 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001232 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001233 connected_up_ipv4 (ifp, ifc);
1234 }
1235
1236 return CMD_SUCCESS;
1237}
1238
1239int
hasso39db97e2004-10-12 20:50:58 +00001240ip_address_uninstall (struct vty *vty, struct interface *ifp,
1241 const char *addr_str, const char *peer_str,
1242 const char *label)
paul718e3742002-12-13 20:15:29 +00001243{
1244 struct prefix_ipv4 cp;
1245 struct connected *ifc;
1246 int ret;
1247
1248 /* Convert to prefix structure. */
1249 ret = str2prefix_ipv4 (addr_str, &cp);
1250 if (ret <= 0)
1251 {
1252 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1253 return CMD_WARNING;
1254 }
1255
1256 /* Check current interface address. */
1257 ifc = connected_check_ipv4 (ifp, (struct prefix *) &cp);
1258 if (! ifc)
1259 {
1260 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1261 return CMD_WARNING;
1262 }
1263
1264 /* This is not configured address. */
1265 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1266 return CMD_WARNING;
1267
1268 /* This is not real address or interface is not active. */
1269 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1270 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1271 {
1272 listnode_delete (ifp->connected, ifc);
1273 connected_free (ifc);
1274 return CMD_WARNING;
1275 }
1276
1277 /* This is real route. */
1278 ret = if_unset_prefix (ifp, ifc);
1279 if (ret < 0)
1280 {
1281 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001282 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001283 return CMD_WARNING;
1284 }
1285
hassoeef1fe12004-10-03 18:46:08 +00001286#if 0
paul718e3742002-12-13 20:15:29 +00001287 /* Redistribute this information. */
1288 zebra_interface_address_delete_update (ifp, ifc);
1289
1290 /* Remove connected route. */
1291 connected_down_ipv4 (ifp, ifc);
1292
1293 /* Free address information. */
1294 listnode_delete (ifp->connected, ifc);
1295 connected_free (ifc);
hassoeef1fe12004-10-03 18:46:08 +00001296#endif
paul718e3742002-12-13 20:15:29 +00001297
1298 return CMD_SUCCESS;
1299}
1300
1301DEFUN (ip_address,
1302 ip_address_cmd,
1303 "ip address A.B.C.D/M",
1304 "Interface Internet Protocol config commands\n"
1305 "Set the IP address of an interface\n"
1306 "IP address (e.g. 10.0.0.1/8)\n")
1307{
hassoeef1fe12004-10-03 18:46:08 +00001308 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001309}
1310
1311DEFUN (no_ip_address,
1312 no_ip_address_cmd,
1313 "no ip address A.B.C.D/M",
1314 NO_STR
1315 "Interface Internet Protocol config commands\n"
1316 "Set the IP address of an interface\n"
1317 "IP Address (e.g. 10.0.0.1/8)")
1318{
hassoeef1fe12004-10-03 18:46:08 +00001319 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001320}
1321
1322#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001323DEFUN (ip_address_label,
1324 ip_address_label_cmd,
1325 "ip address A.B.C.D/M label LINE",
1326 "Interface Internet Protocol config commands\n"
1327 "Set the IP address of an interface\n"
1328 "IP address (e.g. 10.0.0.1/8)\n"
1329 "Label of this address\n"
1330 "Label\n")
1331{
hassoeef1fe12004-10-03 18:46:08 +00001332 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001333}
1334
1335DEFUN (no_ip_address_label,
1336 no_ip_address_label_cmd,
1337 "no ip address A.B.C.D/M label LINE",
1338 NO_STR
1339 "Interface Internet Protocol config commands\n"
1340 "Set the IP address of an interface\n"
1341 "IP address (e.g. 10.0.0.1/8)\n"
1342 "Label of this address\n"
1343 "Label\n")
1344{
hassoeef1fe12004-10-03 18:46:08 +00001345 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001346}
1347#endif /* HAVE_NETLINK */
1348
1349#ifdef HAVE_IPV6
1350int
hasso39db97e2004-10-12 20:50:58 +00001351ipv6_address_install (struct vty *vty, struct interface *ifp,
1352 const char *addr_str, const char *peer_str,
1353 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001354{
1355 struct prefix_ipv6 cp;
1356 struct connected *ifc;
1357 struct prefix_ipv6 *p;
1358 int ret;
1359
1360 ret = str2prefix_ipv6 (addr_str, &cp);
1361 if (ret <= 0)
1362 {
1363 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1364 return CMD_WARNING;
1365 }
1366
1367 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1368 if (! ifc)
1369 {
1370 ifc = connected_new ();
1371 ifc->ifp = ifp;
1372
1373 /* Address. */
1374 p = prefix_ipv6_new ();
1375 *p = cp;
1376 ifc->address = (struct prefix *) p;
1377
1378 /* Secondary. */
1379 if (secondary)
1380 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1381
1382 /* Label. */
1383 if (label)
1384 ifc->label = strdup (label);
1385
1386 /* Add to linked list. */
1387 listnode_add (ifp->connected, ifc);
1388 }
1389
1390 /* This address is configured from zebra. */
1391 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1392 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1393
1394 /* In case of this route need to install kernel. */
1395 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1396 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1397 {
1398 /* Some system need to up the interface to set IP address. */
1399 if (! if_is_up (ifp))
1400 {
1401 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1402 if_refresh (ifp);
1403 }
1404
1405 ret = if_prefix_add_ipv6 (ifp, ifc);
1406
1407 if (ret < 0)
1408 {
1409 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001410 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001411 return CMD_WARNING;
1412 }
1413
1414 /* IP address propery set. */
1415 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1416
1417 /* Update interface address information to protocol daemon. */
1418 zebra_interface_address_add_update (ifp, ifc);
1419
1420 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001421 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001422 connected_up_ipv6 (ifp, ifc);
1423 }
1424
1425 return CMD_SUCCESS;
1426}
1427
1428int
hasso39db97e2004-10-12 20:50:58 +00001429ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1430 const char *addr_str, const char *peer_str,
1431 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001432{
1433 struct prefix_ipv6 cp;
1434 struct connected *ifc;
1435 int ret;
1436
1437 /* Convert to prefix structure. */
1438 ret = str2prefix_ipv6 (addr_str, &cp);
1439 if (ret <= 0)
1440 {
1441 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1442 return CMD_WARNING;
1443 }
1444
1445 /* Check current interface address. */
1446 ifc = connected_check_ipv6 (ifp, (struct prefix *) &cp);
1447 if (! ifc)
1448 {
1449 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1450 return CMD_WARNING;
1451 }
1452
1453 /* This is not configured address. */
1454 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1455 return CMD_WARNING;
1456
1457 /* This is not real address or interface is not active. */
1458 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1459 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1460 {
1461 listnode_delete (ifp->connected, ifc);
1462 connected_free (ifc);
1463 return CMD_WARNING;
1464 }
1465
1466 /* This is real route. */
1467 ret = if_prefix_delete_ipv6 (ifp, ifc);
1468 if (ret < 0)
1469 {
1470 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001471 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001472 return CMD_WARNING;
1473 }
1474
1475 /* Redistribute this information. */
1476 zebra_interface_address_delete_update (ifp, ifc);
1477
1478 /* Remove connected route. */
1479 connected_down_ipv6 (ifp, ifc);
1480
1481 /* Free address information. */
1482 listnode_delete (ifp->connected, ifc);
1483 connected_free (ifc);
1484
1485 return CMD_SUCCESS;
1486}
1487
1488DEFUN (ipv6_address,
1489 ipv6_address_cmd,
1490 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001491 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001492 "Set the IP address of an interface\n"
1493 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1494{
1495 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1496}
1497
1498DEFUN (no_ipv6_address,
1499 no_ipv6_address_cmd,
1500 "no ipv6 address X:X::X:X/M",
1501 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001502 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001503 "Set the IP address of an interface\n"
1504 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1505{
1506 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1507}
1508#endif /* HAVE_IPV6 */
1509
paul718e3742002-12-13 20:15:29 +00001510int
1511if_config_write (struct vty *vty)
1512{
hasso52dc7ee2004-09-23 19:18:23 +00001513 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001514 struct interface *ifp;
1515 char buf[BUFSIZ];
1516
1517 for (node = listhead (iflist); node; nextnode (node))
1518 {
1519 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001520 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001521 struct connected *ifc;
1522 struct prefix *p;
1523
1524 ifp = getdata (node);
1525 if_data = ifp->info;
1526
1527 vty_out (vty, "interface %s%s", ifp->name,
1528 VTY_NEWLINE);
1529
1530 if (ifp->desc)
1531 vty_out (vty, " description %s%s", ifp->desc,
1532 VTY_NEWLINE);
1533
1534 /* Assign bandwidth here to avoid unnecessary interface flap
1535 while processing config script */
1536 if (ifp->bandwidth != 0)
1537 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1538
paul2e3b2e42002-12-13 21:03:13 +00001539 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1540 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1541
paul718e3742002-12-13 20:15:29 +00001542 for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
1543 {
1544 ifc = getdata (addrnode);
1545 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1546 {
1547 p = ifc->address;
1548 vty_out (vty, " ip%s address %s/%d",
1549 p->family == AF_INET ? "" : "v6",
1550 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1551 p->prefixlen);
1552
paul718e3742002-12-13 20:15:29 +00001553 if (ifc->label)
1554 vty_out (vty, " label %s", ifc->label);
1555
1556 vty_out (vty, "%s", VTY_NEWLINE);
1557 }
1558 }
1559
1560 if (if_data)
1561 {
1562 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1563 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1564
1565 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1566 vty_out (vty, " %smulticast%s",
1567 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1568 VTY_NEWLINE);
1569 }
1570
1571#ifdef RTADV
1572 rtadv_config_write (vty, ifp);
1573#endif /* RTADV */
1574
hassoca776982004-06-12 14:33:05 +00001575#ifdef HAVE_IRDP
1576 irdp_config_write (vty, ifp);
1577#endif /* IRDP */
1578
paul718e3742002-12-13 20:15:29 +00001579 vty_out (vty, "!%s", VTY_NEWLINE);
1580 }
1581 return 0;
1582}
1583
1584/* Allocate and initialize interface vector. */
1585void
1586zebra_if_init ()
1587{
1588 /* Initialize interface and new hook. */
1589 if_init ();
1590 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1591 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1592
1593 /* Install configuration write function. */
1594 install_node (&interface_node, if_config_write);
1595
1596 install_element (VIEW_NODE, &show_interface_cmd);
1597 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001598 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001599 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001600 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001601 install_default (INTERFACE_NODE);
1602 install_element (INTERFACE_NODE, &interface_desc_cmd);
1603 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1604 install_element (INTERFACE_NODE, &multicast_cmd);
1605 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001606 install_element (INTERFACE_NODE, &linkdetect_cmd);
1607 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001608 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1609 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1610 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1611 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1612 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1613 install_element (INTERFACE_NODE, &ip_address_cmd);
1614 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1615#ifdef HAVE_IPV6
1616 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1617 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1618#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001619#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001620 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001621 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001622#endif /* HAVE_NETLINK */
1623}