]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
zebra: zebra-client-info-detail.patch
[mirror_frr.git] / zebra / interface.c
CommitLineData
718e3744 1/*
2 * Interface function.
3 * Copyright (C) 1997, 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "if.h"
26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "command.h"
30#include "memory.h"
31#include "ioctl.h"
32#include "connected.h"
33#include "log.h"
34#include "zclient.h"
35
36#include "zebra/interface.h"
37#include "zebra/rtadv.h"
38#include "zebra/rib.h"
39#include "zebra/zserv.h"
40#include "zebra/redistribute.h"
41#include "zebra/debug.h"
ca776988 42#include "zebra/irdp.h"
244c1cdc
DS
43#include "zebra/zebra_ptm.h"
44
45#define ZEBRA_PTM_SUPPORT
718e3744 46
b60668d0
CC
47#ifdef RTADV
48/* Order is intentional. Matches RFC4191. This array is also used for
49 command matching, so only modify with care. */
50const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
51#endif /* RTADV */
718e3744 52
53/* Called when new interface is added. */
a1ac18c4 54static int
718e3744 55if_zebra_new_hook (struct interface *ifp)
56{
57 struct zebra_if *zebra_if;
58
393deb9b 59 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
718e3744 60
61 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
bfac8dcd 62 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
718e3744 63
244c1cdc 64 ifp->ptm_enable = ptm_enable;
718e3744 65#ifdef RTADV
66 {
67 /* Set default router advertise values. */
68 struct rtadvconf *rtadv;
69
70 rtadv = &zebra_if->rtadv;
71
72 rtadv->AdvSendAdvertisements = 0;
73 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
74 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
75 rtadv->AdvIntervalTimer = 0;
76 rtadv->AdvManagedFlag = 0;
77 rtadv->AdvOtherConfigFlag = 0;
7cee1bb1 78 rtadv->AdvHomeAgentFlag = 0;
718e3744 79 rtadv->AdvLinkMTU = 0;
80 rtadv->AdvReachableTime = 0;
81 rtadv->AdvRetransTimer = 0;
82 rtadv->AdvCurHopLimit = 0;
d660f698 83 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
7cee1bb1 84 rtadv->HomeAgentPreference = 0;
d660f698 85 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
7cee1bb1 86 rtadv->AdvIntervalOption = 0;
b60668d0 87 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
718e3744 88
89 rtadv->AdvPrefixList = list_new ();
90 }
91#endif /* RTADV */
92
eef1fe11 93 /* Initialize installed address chains tree. */
94 zebra_if->ipv4_subnets = route_table_init ();
95
718e3744 96 ifp->info = zebra_if;
97 return 0;
98}
99
100/* Called when interface is deleted. */
a1ac18c4 101static int
718e3744 102if_zebra_delete_hook (struct interface *ifp)
103{
eef1fe11 104 struct zebra_if *zebra_if;
105
718e3744 106 if (ifp->info)
eef1fe11 107 {
108 zebra_if = ifp->info;
109
110 /* Free installed address chains tree. */
111 if (zebra_if->ipv4_subnets)
112 route_table_finish (zebra_if->ipv4_subnets);
113
114 XFREE (MTYPE_TMP, zebra_if);
115 }
116
117 return 0;
118}
119
120/* Tie an interface address to its derived subnet list of addresses. */
121int
122if_subnet_add (struct interface *ifp, struct connected *ifc)
123{
124 struct route_node *rn;
125 struct zebra_if *zebra_if;
126 struct prefix cp;
127 struct list *addr_list;
128
129 assert (ifp && ifp->info && ifc);
130 zebra_if = ifp->info;
131
132 /* Get address derived subnet node and associated address list, while marking
133 address secondary attribute appropriately. */
134 cp = *ifc->address;
135 apply_mask (&cp);
136 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
137
138 if ((addr_list = rn->info))
139 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
140 else
141 {
142 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
143 rn->info = addr_list = list_new ();
144 route_lock_node (rn);
145 }
146
147 /* Tie address at the tail of address list. */
148 listnode_add (addr_list, ifc);
149
150 /* Return list element count. */
151 return (addr_list->count);
152}
153
154/* Untie an interface address from its derived subnet list of addresses. */
155int
156if_subnet_delete (struct interface *ifp, struct connected *ifc)
157{
158 struct route_node *rn;
159 struct zebra_if *zebra_if;
160 struct list *addr_list;
161
162 assert (ifp && ifp->info && ifc);
163 zebra_if = ifp->info;
164
165 /* Get address derived subnet node. */
166 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
167 if (! (rn && rn->info))
9db047fc
CF
168 {
169 zlog_warn("Trying to remove an address from an unknown subnet."
170 " (please report this bug)");
171 return -1;
172 }
eef1fe11 173 route_unlock_node (rn);
174
175 /* Untie address from subnet's address list. */
176 addr_list = rn->info;
9db047fc
CF
177
178 /* Deleting an address that is not registered is a bug.
179 * In any case, we shouldn't decrement the lock counter if the address
180 * is unknown. */
181 if (!listnode_lookup(addr_list, ifc))
182 {
183 zlog_warn("Trying to remove an address from a subnet where it is not"
184 " currently registered. (please report this bug)");
185 return -1;
186 }
187
eef1fe11 188 listnode_delete (addr_list, ifc);
189 route_unlock_node (rn);
190
191 /* Return list element count, if not empty. */
192 if (addr_list->count)
193 {
194 /* If deleted address is primary, mark subsequent one as such and distribute. */
195 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
196 {
1eb8ef25 197 ifc = listgetdata (listhead (addr_list));
eef1fe11 198 zebra_interface_address_delete_update (ifp, ifc);
199 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
02b4805f
CF
200 /* XXX: Linux kernel removes all the secondary addresses when the primary
201 * address is removed. We could try to work around that, though this is
202 * non-trivial. */
eef1fe11 203 zebra_interface_address_add_update (ifp, ifc);
204 }
205
206 return addr_list->count;
207 }
208
209 /* Otherwise, free list and route node. */
210 list_free (addr_list);
211 rn->info = NULL;
212 route_unlock_node (rn);
213
718e3744 214 return 0;
215}
216
5c78b3d0 217/* if_flags_mangle: A place for hacks that require mangling
218 * or tweaking the interface flags.
219 *
220 * ******************** Solaris flags hacks **************************
221 *
222 * Solaris IFF_UP flag reflects only the primary interface as the
223 * routing socket only sends IFINFO for the primary interface. Hence
224 * ~IFF_UP does not per se imply all the logical interfaces are also
225 * down - which we only know of as addresses. Instead we must determine
226 * whether the interface really is up or not according to how many
227 * addresses are still attached. (Solaris always sends RTM_DELADDR if
228 * an interface, logical or not, goes ~IFF_UP).
229 *
230 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
231 * are addresses left in struct connected, not just the actual underlying
232 * IFF_UP flag.
233 *
234 * We must hence remember the real state of IFF_UP, which we do in
235 * struct zebra_if.primary_state.
236 *
237 * Setting IFF_UP within zebra to administratively shutdown the
238 * interface will affect only the primary interface/address on Solaris.
239 ************************End Solaris flags hacks ***********************
240 */
f63f06da 241static void
5c78b3d0 242if_flags_mangle (struct interface *ifp, uint64_t *newflags)
243{
244#ifdef SUNOS_5
245 struct zebra_if *zif = ifp->info;
246
247 zif->primary_state = *newflags & (IFF_UP & 0xff);
248
249 if (CHECK_FLAG (zif->primary_state, IFF_UP)
250 || listcount(ifp->connected) > 0)
251 SET_FLAG (*newflags, IFF_UP);
252 else
253 UNSET_FLAG (*newflags, IFF_UP);
254#endif /* SUNOS_5 */
255}
256
257/* Update the flags field of the ifp with the new flag set provided.
258 * Take whatever actions are required for any changes in flags we care
259 * about.
260 *
261 * newflags should be the raw value, as obtained from the OS.
262 */
263void
264if_flags_update (struct interface *ifp, uint64_t newflags)
265{
266 if_flags_mangle (ifp, &newflags);
267
244c1cdc 268 if (if_is_no_ptm_operative (ifp))
5c78b3d0 269 {
270 /* operative -> inoperative? */
271 ifp->flags = newflags;
272 if (!if_is_operative (ifp))
273 if_down (ifp);
274 }
275 else
276 {
277 /* inoperative -> operative? */
278 ifp->flags = newflags;
279 if (if_is_operative (ifp))
280 if_up (ifp);
281 }
282}
283
718e3744 284/* Wake up configured address if it is not in current kernel
285 address. */
a1ac18c4 286static void
718e3744 287if_addr_wakeup (struct interface *ifp)
288{
1eb8ef25 289 struct listnode *node, *nnode;
718e3744 290 struct connected *ifc;
291 struct prefix *p;
292 int ret;
293
1eb8ef25 294 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
718e3744 295 {
718e3744 296 p = ifc->address;
297
298 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
f7f740fe 299 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
718e3744 300 {
301 /* Address check. */
302 if (p->family == AF_INET)
303 {
304 if (! if_is_up (ifp))
305 {
02b4805f
CF
306 /* Assume zebra is configured like following:
307 *
308 * interface gre0
309 * ip addr 192.0.2.1/24
310 * !
311 *
312 * As soon as zebra becomes first aware that gre0 exists in the
313 * kernel, it will set gre0 up and configure its addresses.
314 *
315 * (This may happen at startup when the interface already exists
316 * or during runtime when the interface is added to the kernel)
317 *
318 * XXX: IRDP code is calling here via if_add_update - this seems
319 * somewhat weird.
320 * XXX: RUNNING is not a settable flag on any system
321 * I (paulj) am aware of.
322 */
718e3744 323 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
324 if_refresh (ifp);
325 }
326
327 ret = if_set_prefix (ifp, ifc);
328 if (ret < 0)
329 {
330 zlog_warn ("Can't set interface's address: %s",
6099b3b5 331 safe_strerror(errno));
718e3744 332 continue;
333 }
eef1fe11 334
f7f740fe 335 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
336 /* The address will be advertised to zebra clients when the notification
337 * from the kernel has been received.
338 * It will also be added to the interface's subnet list then. */
718e3744 339 }
340#ifdef HAVE_IPV6
341 if (p->family == AF_INET6)
342 {
343 if (! if_is_up (ifp))
344 {
02b4805f 345 /* See long comment above */
718e3744 346 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
347 if_refresh (ifp);
348 }
349
350 ret = if_prefix_add_ipv6 (ifp, ifc);
351 if (ret < 0)
352 {
353 zlog_warn ("Can't set interface's address: %s",
6099b3b5 354 safe_strerror(errno));
718e3744 355 continue;
356 }
718e3744 357
02b4805f
CF
358 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
359 /* The address will be advertised to zebra clients when the notification
360 * from the kernel has been received. */
718e3744 361 }
362#endif /* HAVE_IPV6 */
363 }
364 }
365}
366
367/* Handle interface addition */
368void
369if_add_update (struct interface *ifp)
370{
48b33aaf 371 struct zebra_if *if_data;
372
373 if_data = ifp->info;
374 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
375 if_set_flags (ifp, IFF_MULTICAST);
376 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
377 if_unset_flags (ifp, IFF_MULTICAST);
378
718e3744 379 zebra_interface_add_update (ifp);
380
381 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
382 {
383 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
384
bfac8dcd
CF
385 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
386 {
387 if (IS_ZEBRA_DEBUG_KERNEL)
388 zlog_debug ("interface %s index %d is shutdown. Won't wake it up.",
389 ifp->name, ifp->ifindex);
390 return;
391 }
392
718e3744 393 if_addr_wakeup (ifp);
394
395 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 396 zlog_debug ("interface %s index %d becomes active.",
397 ifp->name, ifp->ifindex);
718e3744 398 }
399 else
400 {
401 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 402 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
718e3744 403 }
404}
405
6eb8827d 406/* Handle an interface delete event */
718e3744 407void
408if_delete_update (struct interface *ifp)
409{
718e3744 410 struct connected *ifc;
411 struct prefix *p;
eef1fe11 412 struct route_node *rn;
413 struct zebra_if *zebra_if;
eef1fe11 414
415 zebra_if = ifp->info;
718e3744 416
417 if (if_is_up(ifp))
418 {
419 zlog_err ("interface %s index %d is still up while being deleted.",
420 ifp->name, ifp->ifindex);
421 return;
422 }
423
424 /* Mark interface as inactive */
425 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
426
427 if (IS_ZEBRA_DEBUG_KERNEL)
b6178002 428 zlog_debug ("interface %s index %d is now inactive.",
718e3744 429 ifp->name, ifp->ifindex);
430
431 /* Delete connected routes from the kernel. */
432 if (ifp->connected)
433 {
d9a18f11
PJ
434 struct listnode *node;
435 struct listnode *last = NULL;
436
eef1fe11 437 while ((node = (last ? last->next : listhead (ifp->connected))))
718e3744 438 {
1eb8ef25 439 ifc = listgetdata (node);
718e3744 440 p = ifc->address;
eef1fe11 441
beb56336
PJ
442 if (p->family == AF_INET
443 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
eef1fe11 444 {
d9a18f11
PJ
445 struct listnode *anode;
446 struct listnode *next;
447 struct listnode *first;
448 struct list *addr_list;
449
eef1fe11 450 route_unlock_node (rn);
451 addr_list = (struct list *) rn->info;
452
453 /* Remove addresses, secondaries first. */
454 first = listhead (addr_list);
d9a18f11 455 for (anode = first->next; anode || first; anode = next)
eef1fe11 456 {
d9a18f11 457 if (!anode)
eef1fe11 458 {
d9a18f11 459 anode = first;
eef1fe11 460 first = NULL;
461 }
d9a18f11 462 next = anode->next;
eef1fe11 463
d9a18f11 464 ifc = listgetdata (anode);
eef1fe11 465 p = ifc->address;
eef1fe11 466 connected_down_ipv4 (ifp, ifc);
467
02b4805f
CF
468 /* XXX: We have to send notifications here explicitly, because we destroy
469 * the ifc before receiving the notification about the address being deleted.
470 */
eef1fe11 471 zebra_interface_address_delete_update (ifp, ifc);
472
473 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 474 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 475
476 /* Remove from subnet chain. */
d9a18f11 477 list_delete_node (addr_list, anode);
eef1fe11 478 route_unlock_node (rn);
479
480 /* Remove from interface address list (unconditionally). */
d9a18f11
PJ
481 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
482 {
483 listnode_delete (ifp->connected, ifc);
484 connected_free (ifc);
485 }
486 else
487 last = node;
eef1fe11 488 }
489
490 /* Free chain list and respective route node. */
491 list_delete (addr_list);
492 rn->info = NULL;
493 route_unlock_node (rn);
494 }
718e3744 495#ifdef HAVE_IPV6
496 else if (p->family == AF_INET6)
eef1fe11 497 {
498 connected_down_ipv6 (ifp, ifc);
718e3744 499
eef1fe11 500 zebra_interface_address_delete_update (ifp, ifc);
718e3744 501
eef1fe11 502 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 503 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 504
505 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
506 last = node;
507 else
508 {
509 listnode_delete (ifp->connected, ifc);
510 connected_free (ifc);
511 }
718e3744 512 }
eef1fe11 513#endif /* HAVE_IPV6 */
e26873fd
RHA
514 else
515 {
516 last = node;
517 }
718e3744 518 }
519 }
520 zebra_interface_delete_update (ifp);
d2fc8896 521
522 /* Update ifindex after distributing the delete message. This is in
523 case any client needs to have the old value of ifindex available
524 while processing the deletion. Each client daemon is responsible
525 for setting ifindex to IFINDEX_INTERNAL after processing the
526 interface deletion message. */
527 ifp->ifindex = IFINDEX_INTERNAL;
718e3744 528}
529
530/* Interface is up. */
531void
532if_up (struct interface *ifp)
533{
52dc7ee6 534 struct listnode *node;
535 struct listnode *next;
718e3744 536 struct connected *ifc;
537 struct prefix *p;
538
539 /* Notify the protocol daemons. */
244c1cdc
DS
540 if (ifp->ptm_enable && !ifp->ptm_status) {
541 zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
542 ifp->name);
543 return;
544 }
718e3744 545 zebra_interface_up_update (ifp);
546
244c1cdc 547
718e3744 548 /* Install connected routes to the kernel. */
549 if (ifp->connected)
550 {
1eb8ef25 551 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
718e3744 552 {
718e3744 553 p = ifc->address;
554
555 if (p->family == AF_INET)
556 connected_up_ipv4 (ifp, ifc);
557#ifdef HAVE_IPV6
558 else if (p->family == AF_INET6)
559 connected_up_ipv6 (ifp, ifc);
560#endif /* HAVE_IPV6 */
561 }
562 }
563
564 /* Examine all static routes. */
565 rib_update ();
566}
567
568/* Interface goes down. We have to manage different behavior of based
569 OS. */
570void
571if_down (struct interface *ifp)
572{
52dc7ee6 573 struct listnode *node;
574 struct listnode *next;
718e3744 575 struct connected *ifc;
576 struct prefix *p;
577
578 /* Notify to the protocol daemons. */
579 zebra_interface_down_update (ifp);
580
581 /* Delete connected routes from the kernel. */
582 if (ifp->connected)
583 {
1eb8ef25 584 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
718e3744 585 {
718e3744 586 p = ifc->address;
587
588 if (p->family == AF_INET)
589 connected_down_ipv4 (ifp, ifc);
590#ifdef HAVE_IPV6
591 else if (p->family == AF_INET6)
592 connected_down_ipv6 (ifp, ifc);
593#endif /* HAVE_IPV6 */
594 }
595 }
596
597 /* Examine all static routes which direct to the interface. */
598 rib_update ();
599}
600
601void
602if_refresh (struct interface *ifp)
603{
5c78b3d0 604 if_get_flags (ifp);
718e3744 605}
606
718e3744 607/* Output prefix string to vty. */
a1ac18c4 608static int
718e3744 609prefix_vty_out (struct vty *vty, struct prefix *p)
610{
611 char str[INET6_ADDRSTRLEN];
612
613 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
614 vty_out (vty, "%s", str);
615 return strlen (str);
616}
617
618/* Dump if address information to vty. */
a1ac18c4 619static void
718e3744 620connected_dump_vty (struct vty *vty, struct connected *connected)
621{
622 struct prefix *p;
718e3744 623
624 /* Print interface address. */
625 p = connected->address;
626 vty_out (vty, " %s ", prefix_family_str (p));
627 prefix_vty_out (vty, p);
628 vty_out (vty, "/%d", p->prefixlen);
629
630 /* If there is destination address, print it. */
e4529636 631 if (connected->destination)
718e3744 632 {
e4529636
AS
633 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
634 prefix_vty_out (vty, connected->destination);
718e3744 635 }
636
637 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
638 vty_out (vty, " secondary");
639
640 if (connected->label)
641 vty_out (vty, " %s", connected->label);
642
643 vty_out (vty, "%s", VTY_NEWLINE);
644}
645
a80beece
DS
646/* Dump interface neighbor address information to vty. */
647static void
648nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected)
649{
650 struct prefix *p;
651
652 /* Print interface address. */
653 p = connected->address;
654 vty_out (vty, " %s ", prefix_family_str (p));
655 prefix_vty_out (vty, p);
656 vty_out (vty, "/%d", p->prefixlen);
657
658 vty_out (vty, "%s", VTY_NEWLINE);
659}
660
718e3744 661#ifdef RTADV
662/* Dump interface ND information to vty. */
a1ac18c4 663static void
718e3744 664nd_dump_vty (struct vty *vty, struct interface *ifp)
665{
666 struct zebra_if *zif;
667 struct rtadvconf *rtadv;
7cee1bb1 668 int interval;
718e3744 669
670 zif = (struct zebra_if *) ifp->info;
671 rtadv = &zif->rtadv;
672
673 if (rtadv->AdvSendAdvertisements)
674 {
675 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
676 rtadv->AdvReachableTime, VTY_NEWLINE);
677 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
678 rtadv->AdvRetransTimer, VTY_NEWLINE);
7cee1bb1 679 interval = rtadv->MaxRtrAdvInterval;
680 if (interval % 1000)
681 vty_out (vty, " ND router advertisements are sent every "
682 "%d milliseconds%s", interval,
683 VTY_NEWLINE);
684 else
685 vty_out (vty, " ND router advertisements are sent every "
686 "%d seconds%s", interval / 1000,
687 VTY_NEWLINE);
d660f698
DO
688 if (rtadv->AdvDefaultLifetime != -1)
689 vty_out (vty, " ND router advertisements live for %d seconds%s",
690 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
691 else
692 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
693 VTY_NEWLINE);
b60668d0
CC
694 vty_out (vty, " ND router advertisement default router preference is "
695 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
696 VTY_NEWLINE);
718e3744 697 if (rtadv->AdvManagedFlag)
698 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
699 VTY_NEWLINE);
700 else
701 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
702 VTY_NEWLINE);
7cee1bb1 703 if (rtadv->AdvHomeAgentFlag)
d660f698 704 {
7cee1bb1 705 vty_out (vty, " ND router advertisements with "
706 "Home Agent flag bit set.%s",
707 VTY_NEWLINE);
d660f698
DO
708 if (rtadv->HomeAgentLifetime != -1)
709 vty_out (vty, " Home Agent lifetime is %u seconds%s",
710 rtadv->HomeAgentLifetime, VTY_NEWLINE);
711 else
712 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
713 VTY_NEWLINE);
714 vty_out (vty, " Home Agent preference is %u%s",
715 rtadv->HomeAgentPreference, VTY_NEWLINE);
716 }
7cee1bb1 717 if (rtadv->AdvIntervalOption)
718 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
719 VTY_NEWLINE);
718e3744 720 }
721}
722#endif /* RTADV */
723
724/* Interface's information print out to vty interface. */
a1ac18c4 725static void
718e3744 726if_dump_vty (struct vty *vty, struct interface *ifp)
727{
6f0e3f6e 728#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 729 struct sockaddr_dl *sdl;
6f0e3f6e 730#endif /* HAVE_STRUCT_SOCKADDR_DL */
718e3744 731 struct connected *connected;
a80beece 732 struct nbr_connected *nbr_connected;
52dc7ee6 733 struct listnode *node;
eef1fe11 734 struct route_node *rn;
735 struct zebra_if *zebra_if;
736
737 zebra_if = ifp->info;
718e3744 738
2e3b2e47 739 vty_out (vty, "Interface %s is ", ifp->name);
740 if (if_is_up(ifp)) {
741 vty_out (vty, "up, line protocol ");
742
743 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
744 if (if_is_running(ifp))
745 vty_out (vty, "is up%s", VTY_NEWLINE);
746 else
747 vty_out (vty, "is down%s", VTY_NEWLINE);
748 } else {
749 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
750 }
751 } else {
752 vty_out (vty, "down%s", VTY_NEWLINE);
753 }
754
244c1cdc
DS
755 vty_out (vty, " PTM status: ");
756 if (ifp->ptm_enable) {
757 if (ifp->ptm_status) {
758 vty_out (vty, "pass%s", VTY_NEWLINE);
759 } else {
760 vty_out (vty, "fail%s", VTY_NEWLINE);
761 }
762 } else {
763 vty_out (vty, "disabled%s", VTY_NEWLINE);
764 }
765
718e3744 766 if (ifp->desc)
767 vty_out (vty, " Description: %s%s", ifp->desc,
768 VTY_NEWLINE);
d2fc8896 769 if (ifp->ifindex == IFINDEX_INTERNAL)
718e3744 770 {
d2fc8896 771 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
718e3744 772 return;
773 }
774 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
775 {
776 vty_out(vty, " index %d inactive interface%s",
777 ifp->ifindex,
778 VTY_NEWLINE);
779 return;
780 }
781
782 vty_out (vty, " index %d metric %d mtu %d ",
783 ifp->ifindex, ifp->metric, ifp->mtu);
44145db3 784#ifdef HAVE_IPV6
785 if (ifp->mtu6 != ifp->mtu)
786 vty_out (vty, "mtu6 %d ", ifp->mtu6);
787#endif
630c97ce
PJ
788 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
789 if_flag_dump (ifp->flags), VTY_NEWLINE);
3a570c8b 790
718e3744 791 /* Hardware address. */
6f0e3f6e 792#ifdef HAVE_STRUCT_SOCKADDR_DL
718e3744 793 sdl = &ifp->sdl;
794 if (sdl != NULL && sdl->sdl_alen != 0)
795 {
796 int i;
797 u_char *ptr;
798
799 vty_out (vty, " HWaddr: ");
5b73a671 800 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
801 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
718e3744 802 vty_out (vty, "%s", VTY_NEWLINE);
803 }
804#else
805 if (ifp->hw_addr_len != 0)
806 {
807 int i;
808
809 vty_out (vty, " HWaddr: ");
810 for (i = 0; i < ifp->hw_addr_len; i++)
811 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
812 vty_out (vty, "%s", VTY_NEWLINE);
813 }
6f0e3f6e 814#endif /* HAVE_STRUCT_SOCKADDR_DL */
718e3744 815
816 /* Bandwidth in kbps */
817 if (ifp->bandwidth != 0)
818 {
819 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
820 vty_out(vty, "%s", VTY_NEWLINE);
821 }
822
eef1fe11 823 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
718e3744 824 {
eef1fe11 825 if (! rn->info)
826 continue;
827
1eb8ef25 828 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
829 connected_dump_vty (vty, connected);
718e3744 830 }
831
1eb8ef25 832 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
39db97e4 833 {
39db97e4 834 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
835 (connected->address->family == AF_INET6))
836 connected_dump_vty (vty, connected);
837 }
838
718e3744 839#ifdef RTADV
840 nd_dump_vty (vty, ifp);
841#endif /* RTADV */
a80beece
DS
842 if (listhead(ifp->nbr_connected))
843 vty_out (vty, " Neighbor address(s):%s", VTY_NEWLINE);
844 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
845 nbr_connected_dump_vty (vty, nbr_connected);
718e3744 846
847#ifdef HAVE_PROC_NET_DEV
848 /* Statistics print out using proc file system. */
6f2c27af 849 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
850 "%lu dropped%s",
851 ifp->stats.rx_packets, ifp->stats.rx_multicast,
852 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
718e3744 853
6f2c27af 854 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
3452d475 855 " %lu CRC, %lu frame%s",
718e3744 856 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
857 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
6f2c27af 858 ifp->stats.rx_frame_errors, VTY_NEWLINE);
859
860 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
718e3744 861 ifp->stats.rx_missed_errors, VTY_NEWLINE);
862
6f2c27af 863 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
718e3744 864 ifp->stats.tx_packets, ifp->stats.tx_bytes,
865 ifp->stats.tx_dropped, VTY_NEWLINE);
866
6f2c27af 867 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
868 " %lu fifo, %lu heartbeat%s",
718e3744 869 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
870 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
6f2c27af 871 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
718e3744 872
6f2c27af 873 vty_out (vty, " %lu window, %lu collisions%s",
874 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
718e3744 875#endif /* HAVE_PROC_NET_DEV */
876
877#ifdef HAVE_NET_RT_IFLIST
878#if defined (__bsdi__) || defined (__NetBSD__)
879 /* Statistics print out using sysctl (). */
880 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
881 " multicast packets %qu%s",
882 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
883 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
884 VTY_NEWLINE);
885
886 vty_out (vty, " input errors %qu%s",
887 ifp->stats.ifi_ierrors, VTY_NEWLINE);
888
889 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
890 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
891 ifp->stats.ifi_omcasts, VTY_NEWLINE);
892
893 vty_out (vty, " output errors %qu%s",
894 ifp->stats.ifi_oerrors, VTY_NEWLINE);
895
896 vty_out (vty, " collisions %qu%s",
897 ifp->stats.ifi_collisions, VTY_NEWLINE);
898#else
899 /* Statistics print out using sysctl (). */
900 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
901 " multicast packets %lu%s",
902 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
903 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
904 VTY_NEWLINE);
905
906 vty_out (vty, " input errors %lu%s",
907 ifp->stats.ifi_ierrors, VTY_NEWLINE);
908
909 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
910 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
911 ifp->stats.ifi_omcasts, VTY_NEWLINE);
912
913 vty_out (vty, " output errors %lu%s",
914 ifp->stats.ifi_oerrors, VTY_NEWLINE);
915
916 vty_out (vty, " collisions %lu%s",
917 ifp->stats.ifi_collisions, VTY_NEWLINE);
918#endif /* __bsdi__ || __NetBSD__ */
919#endif /* HAVE_NET_RT_IFLIST */
920}
921
718e3744 922/* Wrapper hook point for zebra daemon so that ifindex can be set
923 * DEFUN macro not used as extract.pl HAS to ignore this
924 * See also interface_cmd in lib/if.c
925 */
926DEFUN_NOSH (zebra_interface,
927 zebra_interface_cmd,
928 "interface IFNAME",
929 "Select an interface to configure\n"
930 "Interface's name\n")
931{
932 int ret;
933 struct interface * ifp;
934
935 /* Call lib interface() */
d2fc8896 936 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
937 return ret;
718e3744 938
939 ifp = vty->index;
940
d2fc8896 941 if (ifp->ifindex == IFINDEX_INTERNAL)
942 /* Is this really necessary? Shouldn't status be initialized to 0
943 in that case? */
944 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
718e3744 945
946 return ret;
947}
948
718e3744 949struct cmd_node interface_node =
950{
951 INTERFACE_NODE,
952 "%s(config-if)# ",
953 1
954};
955
956/* Show all or specified interface to vty. */
957DEFUN (show_interface, show_interface_cmd,
958 "show interface [IFNAME]",
959 SHOW_STR
960 "Interface status and configuration\n"
961 "Inteface name\n")
962{
52dc7ee6 963 struct listnode *node;
718e3744 964 struct interface *ifp;
965
966#ifdef HAVE_PROC_NET_DEV
967 /* If system has interface statistics via proc file system, update
968 statistics. */
969 ifstat_update_proc ();
970#endif /* HAVE_PROC_NET_DEV */
971#ifdef HAVE_NET_RT_IFLIST
972 ifstat_update_sysctl ();
973#endif /* HAVE_NET_RT_IFLIST */
974
975 /* Specified interface print. */
976 if (argc != 0)
977 {
978 ifp = if_lookup_by_name (argv[0]);
979 if (ifp == NULL)
980 {
981 vty_out (vty, "%% Can't find interface %s%s", argv[0],
982 VTY_NEWLINE);
983 return CMD_WARNING;
984 }
985 if_dump_vty (vty, ifp);
986 return CMD_SUCCESS;
987 }
988
989 /* All interface print. */
1eb8ef25 990 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
991 if_dump_vty (vty, ifp);
718e3744 992
993 return CMD_SUCCESS;
994}
995
ed9bb6d5 996DEFUN (show_interface_desc,
997 show_interface_desc_cmd,
998 "show interface description",
999 SHOW_STR
1000 "Interface status and configuration\n"
1001 "Interface description\n")
1002{
1003 struct listnode *node;
1004 struct interface *ifp;
1005
1006 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
1eb8ef25 1007 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
ed9bb6d5 1008 {
1009 int len;
ed9bb6d5 1010
1011 len = vty_out (vty, "%s", ifp->name);
1012 vty_out (vty, "%*s", (16 - len), " ");
1013
1014 if (if_is_up(ifp))
1015 {
1016 vty_out (vty, "up ");
1017 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1018 {
1019 if (if_is_running(ifp))
1020 vty_out (vty, "up ");
1021 else
1022 vty_out (vty, "down ");
1023 }
1024 else
1025 {
1026 vty_out (vty, "unknown ");
1027 }
1028 }
1029 else
1030 {
1031 vty_out (vty, "down down ");
1032 }
1033
1034 if (ifp->desc)
1035 vty_out (vty, "%s", ifp->desc);
1036 vty_out (vty, "%s", VTY_NEWLINE);
1037 }
1038 return CMD_SUCCESS;
1039}
1040
718e3744 1041DEFUN (multicast,
1042 multicast_cmd,
1043 "multicast",
1044 "Set multicast flag to interface\n")
1045{
1046 int ret;
1047 struct interface *ifp;
1048 struct zebra_if *if_data;
1049
1050 ifp = (struct interface *) vty->index;
48b33aaf 1051 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1052 {
48b33aaf 1053 ret = if_set_flags (ifp, IFF_MULTICAST);
1054 if (ret < 0)
1055 {
1056 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1057 return CMD_WARNING;
1058 }
1059 if_refresh (ifp);
718e3744 1060 }
718e3744 1061 if_data = ifp->info;
1062 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1063
718e3744 1064 return CMD_SUCCESS;
1065}
1066
1067DEFUN (no_multicast,
1068 no_multicast_cmd,
1069 "no multicast",
1070 NO_STR
1071 "Unset multicast flag to interface\n")
1072{
1073 int ret;
1074 struct interface *ifp;
1075 struct zebra_if *if_data;
1076
1077 ifp = (struct interface *) vty->index;
48b33aaf 1078 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1079 {
48b33aaf 1080 ret = if_unset_flags (ifp, IFF_MULTICAST);
1081 if (ret < 0)
1082 {
1083 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1084 return CMD_WARNING;
1085 }
1086 if_refresh (ifp);
718e3744 1087 }
718e3744 1088 if_data = ifp->info;
1089 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1090
1091 return CMD_SUCCESS;
1092}
1093
2e3b2e47 1094DEFUN (linkdetect,
1095 linkdetect_cmd,
1096 "link-detect",
1097 "Enable link detection on interface\n")
1098{
2e3b2e47 1099 struct interface *ifp;
1100 int if_was_operative;
1101
1102 ifp = (struct interface *) vty->index;
244c1cdc 1103 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1104 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1105
1106 /* When linkdetection is enabled, if might come down */
244c1cdc 1107 if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp);
2e3b2e47 1108
1109 /* FIXME: Will defer status change forwarding if interface
1110 does not come down! */
1111
1112 return CMD_SUCCESS;
1113}
1114
1115
1116DEFUN (no_linkdetect,
1117 no_linkdetect_cmd,
1118 "no link-detect",
1119 NO_STR
1120 "Disable link detection on interface\n")
1121{
2e3b2e47 1122 struct interface *ifp;
1123 int if_was_operative;
1124
1125 ifp = (struct interface *) vty->index;
244c1cdc 1126 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1127 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1128
1129 /* Interface may come up after disabling link detection */
1130 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1131
1132 /* FIXME: see linkdetect_cmd */
1133
1134 return CMD_SUCCESS;
1135}
1136
718e3744 1137DEFUN (shutdown_if,
1138 shutdown_if_cmd,
1139 "shutdown",
1140 "Shutdown the selected interface\n")
1141{
1142 int ret;
1143 struct interface *ifp;
1144 struct zebra_if *if_data;
1145
1146 ifp = (struct interface *) vty->index;
bfac8dcd 1147 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1148 {
bfac8dcd
CF
1149 ret = if_unset_flags (ifp, IFF_UP);
1150 if (ret < 0)
1151 {
1152 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1153 return CMD_WARNING;
1154 }
1155 if_refresh (ifp);
718e3744 1156 }
718e3744 1157 if_data = ifp->info;
1158 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1159
1160 return CMD_SUCCESS;
1161}
1162
1163DEFUN (no_shutdown_if,
1164 no_shutdown_if_cmd,
1165 "no shutdown",
1166 NO_STR
1167 "Shutdown the selected interface\n")
1168{
1169 int ret;
1170 struct interface *ifp;
1171 struct zebra_if *if_data;
1172
1173 ifp = (struct interface *) vty->index;
bfac8dcd
CF
1174
1175 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1176 {
bfac8dcd
CF
1177 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1178 if (ret < 0)
1179 {
1180 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1181 return CMD_WARNING;
1182 }
1183 if_refresh (ifp);
1184
1185 /* Some addresses (in particular, IPv6 addresses on Linux) get
1186 * removed when the interface goes down. They need to be readded.
1187 */
1188 if_addr_wakeup(ifp);
718e3744 1189 }
bfac8dcd 1190
718e3744 1191 if_data = ifp->info;
1192 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1193
1194 return CMD_SUCCESS;
1195}
1196
1197DEFUN (bandwidth_if,
1198 bandwidth_if_cmd,
1199 "bandwidth <1-10000000>",
1200 "Set bandwidth informational parameter\n"
1201 "Bandwidth in kilobits\n")
1202{
1203 struct interface *ifp;
1204 unsigned int bandwidth;
1205
1206 ifp = (struct interface *) vty->index;
1207 bandwidth = strtol(argv[0], NULL, 10);
1208
1209 /* bandwidth range is <1-10000000> */
1210 if (bandwidth < 1 || bandwidth > 10000000)
1211 {
1212 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1213 return CMD_WARNING;
1214 }
1215
1216 ifp->bandwidth = bandwidth;
1217
1218 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1219 if (if_is_operative (ifp))
718e3744 1220 zebra_interface_up_update (ifp);
1221
1222 return CMD_SUCCESS;
1223}
1224
1225DEFUN (no_bandwidth_if,
1226 no_bandwidth_if_cmd,
1227 "no bandwidth",
1228 NO_STR
1229 "Set bandwidth informational parameter\n")
1230{
1231 struct interface *ifp;
1232
1233 ifp = (struct interface *) vty->index;
1234
1235 ifp->bandwidth = 0;
1236
1237 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1238 if (if_is_operative (ifp))
718e3744 1239 zebra_interface_up_update (ifp);
1240
1241 return CMD_SUCCESS;
1242}
1243
1244ALIAS (no_bandwidth_if,
1245 no_bandwidth_if_val_cmd,
1246 "no bandwidth <1-10000000>",
1247 NO_STR
1248 "Set bandwidth informational parameter\n"
1249 "Bandwidth in kilobits\n")
6b0655a2 1250
a1ac18c4 1251static int
39db97e4 1252ip_address_install (struct vty *vty, struct interface *ifp,
1253 const char *addr_str, const char *peer_str,
1254 const char *label)
718e3744 1255{
bfac8dcd 1256 struct zebra_if *if_data;
718e3744 1257 struct prefix_ipv4 cp;
1258 struct connected *ifc;
1259 struct prefix_ipv4 *p;
718e3744 1260 int ret;
1261
bfac8dcd
CF
1262 if_data = ifp->info;
1263
718e3744 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
ca16218d 1271 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1272 if (! ifc)
1273 {
1274 ifc = connected_new ();
1275 ifc->ifp = ifp;
1276
1277 /* Address. */
1278 p = prefix_ipv4_new ();
1279 *p = cp;
1280 ifc->address = (struct prefix *) p;
1281
1282 /* Broadcast. */
3fb9cd6e 1283 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
718e3744 1284 {
1285 p = prefix_ipv4_new ();
1286 *p = cp;
3fb9cd6e 1287 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
718e3744 1288 ifc->destination = (struct prefix *) p;
1289 }
1290
718e3744 1291 /* Label. */
1292 if (label)
0752ef0b 1293 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1294
1295 /* Add to linked list. */
1296 listnode_add (ifp->connected, ifc);
1297 }
1298
1299 /* This address is configured from zebra. */
1300 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1301 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1302
1303 /* In case of this route need to install kernel. */
f7f740fe 1304 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
1305 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1306 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 1307 {
1308 /* Some system need to up the interface to set IP address. */
1309 if (! if_is_up (ifp))
1310 {
1311 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1312 if_refresh (ifp);
1313 }
1314
1315 ret = if_set_prefix (ifp, ifc);
1316 if (ret < 0)
1317 {
1318 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1319 safe_strerror(errno), VTY_NEWLINE);
718e3744 1320 return CMD_WARNING;
1321 }
1322
f7f740fe 1323 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1324 /* The address will be advertised to zebra clients when the notification
1325 * from the kernel has been received.
1326 * It will also be added to the subnet chain list, then. */
718e3744 1327 }
1328
1329 return CMD_SUCCESS;
1330}
1331
a1ac18c4 1332static int
39db97e4 1333ip_address_uninstall (struct vty *vty, struct interface *ifp,
1334 const char *addr_str, const char *peer_str,
1335 const char *label)
718e3744 1336{
1337 struct prefix_ipv4 cp;
1338 struct connected *ifc;
1339 int ret;
1340
1341 /* Convert to prefix structure. */
1342 ret = str2prefix_ipv4 (addr_str, &cp);
1343 if (ret <= 0)
1344 {
1345 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1346 return CMD_WARNING;
1347 }
1348
1349 /* Check current interface address. */
ca16218d 1350 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1351 if (! ifc)
1352 {
1353 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1354 return CMD_WARNING;
1355 }
1356
1357 /* This is not configured address. */
1358 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1359 return CMD_WARNING;
1360
74ecdc9e
PJ
1361 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1362
718e3744 1363 /* This is not real address or interface is not active. */
f7f740fe 1364 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 1365 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1366 {
1367 listnode_delete (ifp->connected, ifc);
1368 connected_free (ifc);
1369 return CMD_WARNING;
1370 }
1371
1372 /* This is real route. */
1373 ret = if_unset_prefix (ifp, ifc);
1374 if (ret < 0)
1375 {
1376 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 1377 safe_strerror(errno), VTY_NEWLINE);
718e3744 1378 return CMD_WARNING;
1379 }
f7f740fe 1380 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1381 /* we will receive a kernel notification about this route being removed.
1382 * this will trigger its removal from the connected list. */
718e3744 1383 return CMD_SUCCESS;
1384}
1385
1386DEFUN (ip_address,
1387 ip_address_cmd,
1388 "ip address A.B.C.D/M",
1389 "Interface Internet Protocol config commands\n"
1390 "Set the IP address of an interface\n"
1391 "IP address (e.g. 10.0.0.1/8)\n")
1392{
eef1fe11 1393 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
718e3744 1394}
1395
1396DEFUN (no_ip_address,
1397 no_ip_address_cmd,
1398 "no ip address A.B.C.D/M",
1399 NO_STR
1400 "Interface Internet Protocol config commands\n"
1401 "Set the IP address of an interface\n"
1402 "IP Address (e.g. 10.0.0.1/8)")
1403{
eef1fe11 1404 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
718e3744 1405}
1406
1407#ifdef HAVE_NETLINK
718e3744 1408DEFUN (ip_address_label,
1409 ip_address_label_cmd,
1410 "ip address A.B.C.D/M label LINE",
1411 "Interface Internet Protocol config commands\n"
1412 "Set the IP address of an interface\n"
1413 "IP address (e.g. 10.0.0.1/8)\n"
1414 "Label of this address\n"
1415 "Label\n")
1416{
eef1fe11 1417 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1418}
1419
1420DEFUN (no_ip_address_label,
1421 no_ip_address_label_cmd,
1422 "no ip address A.B.C.D/M label LINE",
1423 NO_STR
1424 "Interface Internet Protocol config commands\n"
1425 "Set the IP address of an interface\n"
1426 "IP address (e.g. 10.0.0.1/8)\n"
1427 "Label of this address\n"
1428 "Label\n")
1429{
eef1fe11 1430 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
718e3744 1431}
1432#endif /* HAVE_NETLINK */
1433
1434#ifdef HAVE_IPV6
a1ac18c4 1435static int
39db97e4 1436ipv6_address_install (struct vty *vty, struct interface *ifp,
1437 const char *addr_str, const char *peer_str,
1438 const char *label, int secondary)
718e3744 1439{
bfac8dcd 1440 struct zebra_if *if_data;
718e3744 1441 struct prefix_ipv6 cp;
1442 struct connected *ifc;
1443 struct prefix_ipv6 *p;
1444 int ret;
1445
bfac8dcd
CF
1446 if_data = ifp->info;
1447
718e3744 1448 ret = str2prefix_ipv6 (addr_str, &cp);
1449 if (ret <= 0)
1450 {
1451 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1452 return CMD_WARNING;
1453 }
1454
ca16218d 1455 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1456 if (! ifc)
1457 {
1458 ifc = connected_new ();
1459 ifc->ifp = ifp;
1460
1461 /* Address. */
1462 p = prefix_ipv6_new ();
1463 *p = cp;
1464 ifc->address = (struct prefix *) p;
1465
1466 /* Secondary. */
1467 if (secondary)
1468 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1469
1470 /* Label. */
1471 if (label)
0752ef0b 1472 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 1473
1474 /* Add to linked list. */
1475 listnode_add (ifp->connected, ifc);
1476 }
1477
1478 /* This address is configured from zebra. */
1479 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1480 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1481
1482 /* In case of this route need to install kernel. */
f7f740fe 1483 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
1484 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1485 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 1486 {
1487 /* Some system need to up the interface to set IP address. */
1488 if (! if_is_up (ifp))
1489 {
1490 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1491 if_refresh (ifp);
1492 }
1493
1494 ret = if_prefix_add_ipv6 (ifp, ifc);
1495
1496 if (ret < 0)
1497 {
1498 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 1499 safe_strerror(errno), VTY_NEWLINE);
718e3744 1500 return CMD_WARNING;
1501 }
1502
f7f740fe 1503 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1504 /* The address will be advertised to zebra clients when the notification
1505 * from the kernel has been received. */
718e3744 1506 }
1507
1508 return CMD_SUCCESS;
1509}
1510
a1ac18c4 1511static int
39db97e4 1512ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1513 const char *addr_str, const char *peer_str,
1514 const char *label, int secondry)
718e3744 1515{
1516 struct prefix_ipv6 cp;
1517 struct connected *ifc;
1518 int ret;
1519
1520 /* Convert to prefix structure. */
1521 ret = str2prefix_ipv6 (addr_str, &cp);
1522 if (ret <= 0)
1523 {
1524 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1525 return CMD_WARNING;
1526 }
1527
1528 /* Check current interface address. */
ca16218d 1529 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 1530 if (! ifc)
1531 {
1532 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1533 return CMD_WARNING;
1534 }
1535
1536 /* This is not configured address. */
1537 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1538 return CMD_WARNING;
1539
676e1a01
CF
1540 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1541
718e3744 1542 /* This is not real address or interface is not active. */
f7f740fe 1543 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 1544 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1545 {
1546 listnode_delete (ifp->connected, ifc);
1547 connected_free (ifc);
1548 return CMD_WARNING;
1549 }
1550
1551 /* This is real route. */
1552 ret = if_prefix_delete_ipv6 (ifp, ifc);
1553 if (ret < 0)
1554 {
1555 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 1556 safe_strerror(errno), VTY_NEWLINE);
718e3744 1557 return CMD_WARNING;
1558 }
1559
f7f740fe 1560 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
1561 /* This information will be propagated to the zclients when the
1562 * kernel notification is received. */
718e3744 1563 return CMD_SUCCESS;
1564}
1565
1566DEFUN (ipv6_address,
1567 ipv6_address_cmd,
1568 "ipv6 address X:X::X:X/M",
e23949c0 1569 "Interface IPv6 config commands\n"
718e3744 1570 "Set the IP address of an interface\n"
1571 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1572{
1573 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1574}
1575
1576DEFUN (no_ipv6_address,
1577 no_ipv6_address_cmd,
1578 "no ipv6 address X:X::X:X/M",
1579 NO_STR
e23949c0 1580 "Interface IPv6 config commands\n"
718e3744 1581 "Set the IP address of an interface\n"
1582 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1583{
1584 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1585}
1586#endif /* HAVE_IPV6 */
1587
a1ac18c4 1588static int
718e3744 1589if_config_write (struct vty *vty)
1590{
52dc7ee6 1591 struct listnode *node;
718e3744 1592 struct interface *ifp;
718e3744 1593
244c1cdc
DS
1594 zebra_ptm_write (vty);
1595
1eb8ef25 1596 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
718e3744 1597 {
1598 struct zebra_if *if_data;
52dc7ee6 1599 struct listnode *addrnode;
718e3744 1600 struct connected *ifc;
1601 struct prefix *p;
1602
718e3744 1603 if_data = ifp->info;
1604
1605 vty_out (vty, "interface %s%s", ifp->name,
1606 VTY_NEWLINE);
1607
bfac8dcd
CF
1608 if (if_data)
1609 {
1610 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1611 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1612 }
1613
718e3744 1614 if (ifp->desc)
1615 vty_out (vty, " description %s%s", ifp->desc,
1616 VTY_NEWLINE);
1617
1618 /* Assign bandwidth here to avoid unnecessary interface flap
1619 while processing config script */
1620 if (ifp->bandwidth != 0)
1621 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1622
2e3b2e47 1623 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1624 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1625
1eb8ef25 1626 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
718e3744 1627 {
718e3744 1628 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1629 {
81cce018 1630 char buf[INET6_ADDRSTRLEN];
718e3744 1631 p = ifc->address;
1632 vty_out (vty, " ip%s address %s/%d",
1633 p->family == AF_INET ? "" : "v6",
81cce018 1634 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
718e3744 1635 p->prefixlen);
1636
718e3744 1637 if (ifc->label)
1638 vty_out (vty, " label %s", ifc->label);
1639
1640 vty_out (vty, "%s", VTY_NEWLINE);
1641 }
1642 }
1643
1644 if (if_data)
1645 {
718e3744 1646 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1647 vty_out (vty, " %smulticast%s",
1648 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1649 VTY_NEWLINE);
1650 }
1651
1652#ifdef RTADV
1653 rtadv_config_write (vty, ifp);
1654#endif /* RTADV */
1655
ca776988 1656#ifdef HAVE_IRDP
1657 irdp_config_write (vty, ifp);
1658#endif /* IRDP */
1659
718e3744 1660 vty_out (vty, "!%s", VTY_NEWLINE);
1661 }
1662 return 0;
1663}
1664
1665/* Allocate and initialize interface vector. */
1666void
a1ac18c4 1667zebra_if_init (void)
718e3744 1668{
1669 /* Initialize interface and new hook. */
1670 if_init ();
1671 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1672 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1673
1674 /* Install configuration write function. */
1675 install_node (&interface_node, if_config_write);
1676
1677 install_element (VIEW_NODE, &show_interface_cmd);
1678 install_element (ENABLE_NODE, &show_interface_cmd);
ed9bb6d5 1679 install_element (ENABLE_NODE, &show_interface_desc_cmd);
718e3744 1680 install_element (CONFIG_NODE, &zebra_interface_cmd);
bfc13532 1681 install_element (CONFIG_NODE, &no_interface_cmd);
718e3744 1682 install_default (INTERFACE_NODE);
1683 install_element (INTERFACE_NODE, &interface_desc_cmd);
1684 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1685 install_element (INTERFACE_NODE, &multicast_cmd);
1686 install_element (INTERFACE_NODE, &no_multicast_cmd);
2e3b2e47 1687 install_element (INTERFACE_NODE, &linkdetect_cmd);
1688 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
718e3744 1689 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1690 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1691 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1692 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1693 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1694 install_element (INTERFACE_NODE, &ip_address_cmd);
1695 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1696#ifdef HAVE_IPV6
1697 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1698 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1699#endif /* HAVE_IPV6 */
718e3744 1700#ifdef HAVE_NETLINK
718e3744 1701 install_element (INTERFACE_NODE, &ip_address_label_cmd);
718e3744 1702 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
1703#endif /* HAVE_NETLINK */
1704}