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