]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - zebra/interface.c
Merge tag 'upstream/1.2.3'
[quagga-debian.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 #include "vrf.h"
36 #include "command.h"
37
38 #include "zebra/interface.h"
39 #include "zebra/rtadv.h"
40 #include "zebra/rib.h"
41 #include "zebra/zserv.h"
42 #include "zebra/redistribute.h"
43 #include "zebra/debug.h"
44 #include "zebra/irdp.h"
45
46 #if defined (HAVE_RTADV)
47 /* Order is intentional.  Matches RFC4191.  This array is also used for
48    command matching, so only modify with care. */
49 const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
50 #endif /* HAVE_RTADV */
51
52 /* We don't have a tidy top-level instance object for zebra, or interfaces */
53 static struct zebra_if_defaults zif_defaults = {
54   .linkdetect = IF_LINKDETECT_UNSPEC,
55 };
56
57 /* helper only for if_zebra_linkdetect */
58 static void
59 if_zebra_linkdetect_set_val (struct interface *ifp, zebra_if_linkdetect val)
60 {
61   switch (val)
62     {
63       case IF_LINKDETECT_ON:
64         SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
65         break;
66       case IF_LINKDETECT_OFF:
67         UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
68         break;
69       default: break;
70     }
71 }
72
73 static void
74 if_zebra_linkdetect_set (struct interface *ifp)
75 {
76   struct zebra_if *zif = ifp->info;
77   assert (zif != NULL);
78   int if_was_operative = if_is_operative(ifp);
79   
80   /* If user has explicitly configured for the interface, let that set */
81   if (zif->linkdetect != IF_LINKDETECT_UNSPEC)
82     if_zebra_linkdetect_set_val (ifp, zif->linkdetect);
83   else 
84     {
85       /* general compiled in default is to set */
86       SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
87       /* but user can specify a default too */
88       if_zebra_linkdetect_set_val (ifp, zif_defaults.linkdetect);
89     }
90   /* When linkdetection is enabled, interface might come down */
91   if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
92   /* Alternatively, it may come up after disabling link detection */
93   if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
94 }
95
96 /* Called when new interface is added. */
97 static int
98 if_zebra_new_hook (struct interface *ifp)
99 {
100   struct zebra_if *zebra_if;
101
102   zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
103
104   zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
105   zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
106
107   switch (zif_defaults.linkdetect)
108     {
109       case IF_LINKDETECT_OFF:
110         UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
111         break;
112       case IF_LINKDETECT_UNSPEC:
113       case IF_LINKDETECT_ON:
114       default:
115         SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
116         break;
117     }
118   
119 #if defined (HAVE_RTADV)
120   {
121     /* Set default router advertise values. */
122     struct rtadvconf *rtadv;
123
124     rtadv = &zebra_if->rtadv;
125
126     rtadv->AdvSendAdvertisements = 0;
127     rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
128     rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
129     rtadv->AdvIntervalTimer = 0;
130     rtadv->AdvManagedFlag = 0;
131     rtadv->AdvOtherConfigFlag = 0;
132     rtadv->AdvHomeAgentFlag = 0;
133     rtadv->AdvLinkMTU = 0;
134     rtadv->AdvReachableTime = 0;
135     rtadv->AdvRetransTimer = 0;
136     rtadv->AdvCurHopLimit = 0;
137     rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
138     rtadv->HomeAgentPreference = 0;
139     rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
140     rtadv->AdvIntervalOption = 0;
141     rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
142
143     rtadv->AdvPrefixList = list_new ();
144   }    
145 #endif /* HAVE_RTADV */
146
147   /* Initialize installed address chains tree. */
148   zebra_if->ipv4_subnets = route_table_init ();
149
150   ifp->info = zebra_if;
151   return 0;
152 }
153
154 /* Called when interface is deleted. */
155 static int
156 if_zebra_delete_hook (struct interface *ifp)
157 {
158   struct zebra_if *zebra_if;
159   
160   if (ifp->info)
161     {
162       zebra_if = ifp->info;
163
164       /* Free installed address chains tree. */
165       if (zebra_if->ipv4_subnets)
166         route_table_finish (zebra_if->ipv4_subnets);
167
168       XFREE (MTYPE_TMP, zebra_if);
169     }
170
171   return 0;
172 }
173
174 /* Tie an interface address to its derived subnet list of addresses. */
175 int
176 if_subnet_add (struct interface *ifp, struct connected *ifc)
177 {
178   struct route_node *rn;
179   struct zebra_if *zebra_if;
180   struct prefix cp;
181   struct list *addr_list;
182
183   assert (ifp && ifp->info && ifc);
184   zebra_if = ifp->info;
185
186   /* Get address derived subnet node and associated address list, while marking
187      address secondary attribute appropriately. */
188   cp = *ifc->address;
189   apply_mask (&cp);
190   rn = route_node_get (zebra_if->ipv4_subnets, &cp);
191
192   if ((addr_list = rn->info))
193     SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
194   else
195     {
196       UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
197       rn->info = addr_list = list_new ();
198       route_lock_node (rn);
199     }
200
201   /* Tie address at the tail of address list. */
202   listnode_add (addr_list, ifc);
203   
204   /* Return list element count. */
205   return (addr_list->count);
206 }
207
208 /* Untie an interface address from its derived subnet list of addresses. */
209 int
210 if_subnet_delete (struct interface *ifp, struct connected *ifc)
211 {
212   struct route_node *rn;
213   struct zebra_if *zebra_if;
214   struct list *addr_list;
215
216   assert (ifp && ifp->info && ifc);
217   zebra_if = ifp->info;
218
219   /* Get address derived subnet node. */
220   rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
221   if (! (rn && rn->info))
222     {
223       zlog_warn("Trying to remove an address from an unknown subnet."
224                 " (please report this bug)");
225       return -1;
226     }
227   route_unlock_node (rn);
228   
229   /* Untie address from subnet's address list. */
230   addr_list = rn->info;
231
232   /* Deleting an address that is not registered is a bug.
233    * In any case, we shouldn't decrement the lock counter if the address
234    * is unknown. */
235   if (!listnode_lookup(addr_list, ifc))
236     {
237       zlog_warn("Trying to remove an address from a subnet where it is not"
238                 " currently registered. (please report this bug)");
239       return -1;
240     }
241
242   listnode_delete (addr_list, ifc);
243   route_unlock_node (rn);
244
245   /* Return list element count, if not empty. */
246   if (addr_list->count)
247     {
248       /* If deleted address is primary, mark subsequent one as such and distribute. */
249       if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
250         {
251           ifc = listgetdata ((struct listnode *)listhead (addr_list));
252           zebra_interface_address_delete_update (ifp, ifc);
253           UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
254           /* XXX: Linux kernel removes all the secondary addresses when the primary
255            * address is removed. We could try to work around that, though this is
256            * non-trivial. */
257           zebra_interface_address_add_update (ifp, ifc);
258         }
259       
260       return addr_list->count;
261     }
262   
263   /* Otherwise, free list and route node. */
264   list_free (addr_list);
265   rn->info = NULL;
266   route_unlock_node (rn);
267
268   return 0;
269 }
270
271 /* if_flags_mangle: A place for hacks that require mangling
272  * or tweaking the interface flags.
273  *
274  * ******************** Solaris flags hacks **************************
275  *
276  * Solaris IFF_UP flag reflects only the primary interface as the
277  * routing socket only sends IFINFO for the primary interface.  Hence  
278  * ~IFF_UP does not per se imply all the logical interfaces are also   
279  * down - which we only know of as addresses. Instead we must determine
280  * whether the interface really is up or not according to how many   
281  * addresses are still attached. (Solaris always sends RTM_DELADDR if
282  * an interface, logical or not, goes ~IFF_UP).
283  *
284  * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
285  * are addresses left in struct connected, not just the actual underlying
286  * IFF_UP flag.
287  *
288  * We must hence remember the real state of IFF_UP, which we do in
289  * struct zebra_if.primary_state.
290  *
291  * Setting IFF_UP within zebra to administratively shutdown the
292  * interface will affect only the primary interface/address on Solaris.
293  ************************End Solaris flags hacks ***********************
294  */
295 static void
296 if_flags_mangle (struct interface *ifp, uint64_t *newflags)
297 {
298 #ifdef SUNOS_5
299   struct zebra_if *zif = ifp->info;
300   
301   zif->primary_state = *newflags & (IFF_UP & 0xff);
302   
303   if (CHECK_FLAG (zif->primary_state, IFF_UP)
304       || listcount(ifp->connected) > 0)
305     SET_FLAG (*newflags, IFF_UP);
306   else
307     UNSET_FLAG (*newflags, IFF_UP);
308 #endif /* SUNOS_5 */
309 }
310
311 /* Update the flags field of the ifp with the new flag set provided.
312  * Take whatever actions are required for any changes in flags we care
313  * about.
314  *
315  * newflags should be the raw value, as obtained from the OS.
316  */
317 void
318 if_flags_update (struct interface *ifp, uint64_t newflags)
319 {
320   if_flags_mangle (ifp, &newflags);
321     
322   if (if_is_operative (ifp))
323     {
324       /* operative -> inoperative? */
325       ifp->flags = newflags;
326       if (!if_is_operative (ifp))
327         if_down (ifp);
328     }
329   else
330     {
331       /* inoperative -> operative? */
332       ifp->flags = newflags;
333       if (if_is_operative (ifp))
334         if_up (ifp);
335     }
336 }
337
338 /* Wake up configured address if it is not in current kernel
339    address. */
340 static void
341 if_addr_wakeup (struct interface *ifp)
342 {
343   struct listnode *node, *nnode;
344   struct connected *ifc;
345   struct prefix *p;
346   int ret;
347
348   for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
349     {
350       p = ifc->address;
351         
352       if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
353           && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
354         {
355           /* Address check. */
356           if (p->family == AF_INET)
357             {
358               if (! if_is_up (ifp))
359                 {
360                   /* Assume zebra is configured like following:
361                    *
362                    *   interface gre0
363                    *    ip addr 192.0.2.1/24
364                    *   !
365                    *
366                    * As soon as zebra becomes first aware that gre0 exists in the
367                    * kernel, it will set gre0 up and configure its addresses.
368                    *
369                    * (This may happen at startup when the interface already exists
370                    * or during runtime when the interface is added to the kernel)
371                    *
372                    * XXX: IRDP code is calling here via if_add_update - this seems
373                    * somewhat weird.
374                    * XXX: RUNNING is not a settable flag on any system
375                    * I (paulj) am aware of.
376                   */
377                   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
378                   if_refresh (ifp);
379                 }
380
381               ret = if_set_prefix (ifp, ifc);
382               if (ret < 0)
383                 {
384                   zlog_warn ("Can't set interface's address: %s", 
385                              safe_strerror(errno));
386                   continue;
387                 }
388
389               SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
390               /* The address will be advertised to zebra clients when the notification
391                * from the kernel has been received.
392                * It will also be added to the interface's subnet list then. */
393             }
394 #ifdef HAVE_IPV6
395           if (p->family == AF_INET6)
396             {
397               if (! if_is_up (ifp))
398                 {
399                   /* See long comment above */
400                   if_set_flags (ifp, IFF_UP | IFF_RUNNING);
401                   if_refresh (ifp);
402                 }
403
404               ret = if_prefix_add_ipv6 (ifp, ifc);
405               if (ret < 0)
406                 {
407                   zlog_warn ("Can't set interface's address: %s", 
408                              safe_strerror(errno));
409                   continue;
410                 }
411
412               SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
413               /* The address will be advertised to zebra clients when the notification
414                * from the kernel has been received. */
415             }
416 #endif /* HAVE_IPV6 */
417         }
418     }
419 }
420
421 static void if_count_up(struct zebra_if *zif)
422 {
423   event_counter_inc(&zif->up_events);
424 }
425
426 static void if_count_down(struct zebra_if *zif)
427 {
428   event_counter_inc(&zif->down_events);
429 }
430
431 void
432 if_startup_count_up (void)
433 {
434   vrf_iter_t iter;
435   struct interface *ifp;
436   struct zebra_if *zif;
437   struct listnode *node;
438
439   for (iter = vrf_first(); iter != VRF_ITER_INVALID; iter = vrf_next(iter))
440     {
441       for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist(iter), node, ifp))
442         {
443           zif = ifp->info;
444           if (!zif->up_events.count && if_is_operative(ifp))
445             if_count_up(zif);
446         }
447     }
448 }
449
450 /* Handle interface addition */
451 void
452 if_add_update (struct interface *ifp)
453 {
454   struct zebra_if *if_data;
455
456   if_data = ifp->info;
457   assert(if_data);
458
459   if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
460     if_set_flags (ifp, IFF_MULTICAST);
461   else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
462     if_unset_flags (ifp, IFF_MULTICAST);
463
464   zebra_interface_add_update (ifp);
465
466   if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
467     {
468       SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
469
470       if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
471         {
472           if (IS_ZEBRA_DEBUG_KERNEL)
473             zlog_debug ("interface %s vrf %u index %d is shutdown. "
474                         "Won't wake it up.",
475                         ifp->name, ifp->vrf_id, ifp->ifindex);
476           return;
477         }
478
479       if_addr_wakeup (ifp);
480
481       if (IS_ZEBRA_DEBUG_KERNEL)
482         zlog_debug ("interface %s vrf %u index %d becomes active.",
483                     ifp->name, ifp->vrf_id, ifp->ifindex);
484     }
485   else
486     {
487       if (IS_ZEBRA_DEBUG_KERNEL)
488         zlog_debug ("interface %s vrf %u index %d is added.",
489                     ifp->name, ifp->vrf_id, ifp->ifindex);
490     }
491
492   if (host_config_get())
493     {
494       /* If configuration and therefore link-detect have already been
495        * loaded, count an initial up event when new interfaces are added
496        * in up state.
497        * If configuration has not been loaded yet, this is handled by
498        * if_startup_count_up which is called after reading the config. */
499       if (!if_data->up_events.count && if_is_operative(ifp))
500         if_count_up(if_data);
501     }
502 }
503
504 /* Handle an interface delete event */
505 void 
506 if_delete_update (struct interface *ifp)
507 {
508   struct connected *ifc;
509   struct prefix *p;
510   struct route_node *rn;
511   struct zebra_if *zebra_if;
512
513   zebra_if = ifp->info;
514
515   if (if_is_up(ifp))
516     {
517       zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
518                 ifp->name, ifp->vrf_id, ifp->ifindex);
519       return;
520     }
521
522   /* Mark interface as inactive */
523   UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
524   
525   if (IS_ZEBRA_DEBUG_KERNEL)
526     zlog_debug ("interface %s vrf %u index %d is now inactive.",
527                 ifp->name, ifp->vrf_id, ifp->ifindex);
528
529   /* Delete connected routes from the kernel. */
530   if (ifp->connected)
531     {
532       struct listnode *node;
533       struct listnode *last = NULL;
534
535       while ((node = (last ? last->next : listhead (ifp->connected))))
536         {
537           ifc = listgetdata (node);
538           p = ifc->address;
539           
540           if (p->family == AF_INET
541               && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
542             {
543               struct listnode *anode;
544               struct listnode *next;
545               struct listnode *first;
546               struct list *addr_list;
547               
548               route_unlock_node (rn);
549               addr_list = (struct list *) rn->info;
550               
551               /* Remove addresses, secondaries first. */
552               first = listhead (addr_list);
553               for (anode = first->next; anode || first; anode = next)
554                 {
555                   if (!anode)
556                     {
557                       anode = first;
558                       first = NULL;
559                     }
560                   next = anode->next;
561
562                   ifc = listgetdata (anode);
563                   p = ifc->address;
564                   connected_down_ipv4 (ifp, ifc);
565
566                   /* XXX: We have to send notifications here explicitly, because we destroy
567                    * the ifc before receiving the notification about the address being deleted.
568                    */
569                   zebra_interface_address_delete_update (ifp, ifc);
570
571                   UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
572                   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
573
574                   /* Remove from subnet chain. */
575                   list_delete_node (addr_list, anode);
576                   route_unlock_node (rn);
577                   
578                   /* Remove from interface address list (unconditionally). */
579                   if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
580                     {
581                       listnode_delete (ifp->connected, ifc);
582                       connected_free (ifc);
583                     }
584                   else
585                     last = node;
586                 }
587
588               /* Free chain list and respective route node. */
589               list_delete (addr_list);
590               rn->info = NULL;
591               route_unlock_node (rn);
592             }
593 #ifdef HAVE_IPV6
594           else if (p->family == AF_INET6)
595             {
596               connected_down_ipv6 (ifp, ifc);
597
598               zebra_interface_address_delete_update (ifp, ifc);
599
600               UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
601               UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
602
603               if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
604                 last = node;
605               else
606                 {
607                   listnode_delete (ifp->connected, ifc);
608                   connected_free (ifc);
609                 }
610             }
611 #endif /* HAVE_IPV6 */
612           else
613             {
614               last = node;
615             }
616         }
617     }
618   zebra_interface_delete_update (ifp);
619
620   /* Update ifindex after distributing the delete message.  This is in
621      case any client needs to have the old value of ifindex available
622      while processing the deletion.  Each client daemon is responsible
623      for setting ifindex to IFINDEX_INTERNAL after processing the
624      interface deletion message. */
625   ifp->ifindex = IFINDEX_INTERNAL;
626 }
627
628 /* Interface is up. */
629 void
630 if_up (struct interface *ifp)
631 {
632   struct listnode *node;
633   struct listnode *next;
634   struct connected *ifc;
635   struct prefix *p;
636
637   if_count_up(ifp->info);
638
639   /* Notify the protocol daemons. */
640   zebra_interface_up_update (ifp);
641
642   /* Install connected routes to the kernel. */
643   if (ifp->connected)
644     {
645       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
646         {
647           p = ifc->address;
648
649           if (p->family == AF_INET)
650             connected_up_ipv4 (ifp, ifc);
651 #ifdef HAVE_IPV6
652           else if (p->family == AF_INET6)
653             connected_up_ipv6 (ifp, ifc);
654 #endif /* HAVE_IPV6 */
655         }
656     }
657
658   /* Examine all static routes. */
659   rib_update (ifp->vrf_id);
660 }
661
662 /* Interface goes down.  We have to manage different behavior of based
663    OS. */
664 void
665 if_down (struct interface *ifp)
666 {
667   struct listnode *node;
668   struct listnode *next;
669   struct connected *ifc;
670   struct prefix *p;
671   struct zebra_if *zif;
672
673   zif = ifp->info;
674   if (zif->up_events.count)
675     if_count_down(zif);
676
677   /* Notify to the protocol daemons. */
678   zebra_interface_down_update (ifp);
679
680   /* Delete connected routes from the kernel. */
681   if (ifp->connected)
682     {
683       for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
684         {
685           p = ifc->address;
686
687           if (p->family == AF_INET)
688             connected_down_ipv4 (ifp, ifc);
689 #ifdef HAVE_IPV6
690           else if (p->family == AF_INET6)
691             connected_down_ipv6 (ifp, ifc);
692 #endif /* HAVE_IPV6 */
693         }
694     }
695
696   /* Examine all static routes which direct to the interface. */
697   rib_update (ifp->vrf_id);
698 }
699
700 void
701 if_refresh (struct interface *ifp)
702 {
703   if_get_flags (ifp);
704 }
705
706 /* Output prefix string to vty. */
707 static int
708 prefix_vty_out (struct vty *vty, struct prefix *p)
709 {
710   char str[INET6_ADDRSTRLEN];
711
712   inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
713   vty_out (vty, "%s", str);
714   return strlen (str);
715 }
716
717 /* Dump if address information to vty. */
718 static void
719 connected_dump_vty (struct vty *vty, struct connected *connected)
720 {
721   struct prefix *p;
722
723   /* Print interface address. */
724   p = connected->address;
725   vty_out (vty, "  %s ", prefix_family_str (p));
726   prefix_vty_out (vty, p);
727   vty_out (vty, "/%d", p->prefixlen);
728
729   /* If there is destination address, print it. */
730   if (connected->destination)
731     {
732       vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
733       prefix_vty_out (vty, connected->destination);
734     }
735
736   if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
737     vty_out (vty, " secondary");
738
739   if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED))
740     vty_out (vty, " unnumbered");
741
742   if (connected->label)
743     vty_out (vty, " %s", connected->label);
744
745   vty_out (vty, "%s", VTY_NEWLINE);
746 }
747
748 #if defined (HAVE_RTADV)
749 /* Dump interface ND information to vty. */
750 static void
751 nd_dump_vty (struct vty *vty, struct interface *ifp)
752 {
753   struct zebra_if *zif;
754   struct rtadvconf *rtadv;
755   int interval;
756
757   zif = (struct zebra_if *) ifp->info;
758   rtadv = &zif->rtadv;
759
760   if (rtadv->AdvSendAdvertisements)
761     {
762       vty_out (vty, "  ND advertised reachable time is %d milliseconds%s",
763                rtadv->AdvReachableTime, VTY_NEWLINE);
764       vty_out (vty, "  ND advertised retransmit interval is %d milliseconds%s",
765                rtadv->AdvRetransTimer, VTY_NEWLINE);
766       interval = rtadv->MaxRtrAdvInterval;
767       if (interval % 1000)
768         vty_out (vty, "  ND router advertisements are sent every "
769                         "%d milliseconds%s", interval,
770                  VTY_NEWLINE);
771       else
772         vty_out (vty, "  ND router advertisements are sent every "
773                         "%d seconds%s", interval / 1000,
774                  VTY_NEWLINE);
775       if (rtadv->AdvDefaultLifetime != -1)
776         vty_out (vty, "  ND router advertisements live for %d seconds%s",
777                  rtadv->AdvDefaultLifetime, VTY_NEWLINE);
778       else
779         vty_out (vty, "  ND router advertisements lifetime tracks ra-interval%s",
780                  VTY_NEWLINE);
781       vty_out (vty, "  ND router advertisement default router preference is "
782                         "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
783                  VTY_NEWLINE);
784       if (rtadv->AdvManagedFlag)
785         vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s",
786                  VTY_NEWLINE);
787       else
788         vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s",
789                  VTY_NEWLINE);
790       if (rtadv->AdvHomeAgentFlag)
791       {
792         vty_out (vty, "  ND router advertisements with "
793                                 "Home Agent flag bit set.%s",
794                  VTY_NEWLINE);
795         if (rtadv->HomeAgentLifetime != -1)
796           vty_out (vty, "  Home Agent lifetime is %u seconds%s",
797                    rtadv->HomeAgentLifetime, VTY_NEWLINE);
798         else
799           vty_out (vty, "  Home Agent lifetime tracks ra-lifetime%s",
800                    VTY_NEWLINE);
801         vty_out (vty, "  Home Agent preference is %u%s",
802                  rtadv->HomeAgentPreference, VTY_NEWLINE);
803       }
804       if (rtadv->AdvIntervalOption)
805         vty_out (vty, "  ND router advertisements with Adv. Interval option.%s",
806                  VTY_NEWLINE);
807     }
808 }
809 #endif /* HAVE_RTADV */
810
811 /* Interface's information print out to vty interface. */
812 static void
813 if_dump_vty (struct vty *vty, struct interface *ifp)
814 {
815   struct connected *connected;
816   struct listnode *node;
817   struct route_node *rn;
818   struct zebra_if *zebra_if;
819
820   zebra_if = ifp->info;
821
822   vty_out (vty, "Interface %s is ", ifp->name);
823   if (if_is_up(ifp)) {
824     vty_out (vty, "up, line protocol ");
825     
826     if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
827       if (if_is_running(ifp))
828        vty_out (vty, "is up%s", VTY_NEWLINE);
829       else
830         vty_out (vty, "is down%s", VTY_NEWLINE);
831     } else {
832       vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
833     }
834   } else {
835     vty_out (vty, "down%s", VTY_NEWLINE);
836   }
837
838   vty_out (vty, "  Link ups:   %s%s",
839            event_counter_format(&zebra_if->up_events), VTY_NEWLINE);
840   vty_out (vty, "  Link downs: %s%s",
841            event_counter_format(&zebra_if->down_events), VTY_NEWLINE);
842
843   vty_out (vty, "  vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
844
845   if (ifp->desc)
846     vty_out (vty, "  Description: %s%s", ifp->desc,
847              VTY_NEWLINE);
848   if (ifp->ifindex == IFINDEX_INTERNAL)
849     {
850       vty_out(vty, "  pseudo interface%s", VTY_NEWLINE);
851       return;
852     }
853   else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
854     {
855       vty_out(vty, "  index %d inactive interface%s", 
856               ifp->ifindex, 
857               VTY_NEWLINE);
858       return;
859     }
860
861   vty_out (vty, "  index %d metric %d mtu %d ",
862            ifp->ifindex, ifp->metric, ifp->mtu);
863 #ifdef HAVE_IPV6
864   if (ifp->mtu6 != ifp->mtu)
865     vty_out (vty, "mtu6 %d ", ifp->mtu6);
866 #endif 
867   vty_out (vty, "%s  flags: %s%s", VTY_NEWLINE,
868            if_flag_dump (ifp->flags), VTY_NEWLINE);
869   
870   /* Hardware address. */
871   vty_out (vty, "  Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
872   if (ifp->hw_addr_len != 0)
873     {
874       int i;
875
876       vty_out (vty, "  HWaddr: ");
877       for (i = 0; i < ifp->hw_addr_len; i++)
878         vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
879       vty_out (vty, "%s", VTY_NEWLINE);
880     }
881   
882   /* Bandwidth in kbps */
883   if (ifp->bandwidth != 0)
884     {
885       vty_out(vty, "  bandwidth %u kbps", ifp->bandwidth);
886       vty_out(vty, "%s", VTY_NEWLINE);
887     }
888
889   for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
890     {
891       if (! rn->info)
892         continue;
893
894       for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
895         connected_dump_vty (vty, connected);
896     }
897
898   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
899     {
900       if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
901           (connected->address->family == AF_INET6))
902         connected_dump_vty (vty, connected);
903     }
904
905   if (HAS_LINK_PARAMS(ifp))
906     {
907       int i;
908       struct if_link_params *iflp = ifp->link_params;
909       vty_out(vty, "  Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
910       if (IS_PARAM_SET(iflp, LP_TE))
911         vty_out(vty, "    TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
912       if (IS_PARAM_SET(iflp, LP_MAX_BW))
913         vty_out(vty, "    Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
914       if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
915         vty_out(vty, "    Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
916       if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
917         vty_out(vty, "    Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
918         for (i = 0; i < MAX_CLASS_TYPE; i+=2)
919           vty_out(vty, "      [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
920                   i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
921       }
922
923       if (IS_PARAM_SET(iflp, LP_ADM_GRP))
924         vty_out(vty, "    Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
925       if (IS_PARAM_SET(iflp, LP_DELAY))
926         {
927           vty_out(vty, "    Link Delay Average: %u (micro-sec.)", iflp->av_delay);
928           if (IS_PARAM_SET(iflp, LP_MM_DELAY))
929             {
930               vty_out(vty, " Min:  %u (micro-sec.)", iflp->min_delay);
931               vty_out(vty, " Max:  %u (micro-sec.)", iflp->max_delay);
932             }
933           vty_out(vty, "%s", VTY_NEWLINE);
934         }
935       if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
936         vty_out(vty, "    Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
937       if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
938         vty_out(vty, "    Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
939       if (IS_PARAM_SET(iflp, LP_AVA_BW))
940         vty_out(vty, "    Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
941       if (IS_PARAM_SET(iflp, LP_RES_BW))
942         vty_out(vty, "    Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
943       if (IS_PARAM_SET(iflp, LP_USE_BW))
944         vty_out(vty, "    Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
945       if (IS_PARAM_SET(iflp, LP_RMT_AS))
946         vty_out(vty, "    Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
947     }
948
949  #ifdef RTADV
950    nd_dump_vty (vty, ifp);
951  #endif /* RTADV */
952 #if defined (HAVE_RTADV)
953   nd_dump_vty (vty, ifp);
954 #endif /* HAVE_RTADV */
955
956 #ifdef HAVE_PROC_NET_DEV
957   /* Statistics print out using proc file system. */
958   vty_out (vty, "    %lu input packets (%lu multicast), %lu bytes, "
959            "%lu dropped%s",
960            ifp->stats.rx_packets, ifp->stats.rx_multicast,
961            ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
962
963   vty_out (vty, "    %lu input errors, %lu length, %lu overrun,"
964            " %lu CRC, %lu frame%s",
965            ifp->stats.rx_errors, ifp->stats.rx_length_errors,
966            ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
967            ifp->stats.rx_frame_errors, VTY_NEWLINE);
968
969   vty_out (vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
970            ifp->stats.rx_missed_errors, VTY_NEWLINE);
971
972   vty_out (vty, "    %lu output packets, %lu bytes, %lu dropped%s",
973            ifp->stats.tx_packets, ifp->stats.tx_bytes,
974            ifp->stats.tx_dropped, VTY_NEWLINE);
975
976   vty_out (vty, "    %lu output errors, %lu aborted, %lu carrier,"
977            " %lu fifo, %lu heartbeat%s",
978            ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
979            ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
980            ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
981
982   vty_out (vty, "    %lu window, %lu collisions%s",
983            ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
984 #endif /* HAVE_PROC_NET_DEV */
985
986 #ifdef HAVE_NET_RT_IFLIST
987 #if defined (__bsdi__) || defined (__NetBSD__)
988   /* Statistics print out using sysctl (). */
989   vty_out (vty, "    input packets %llu, bytes %llu, dropped %llu,"
990            " multicast packets %llu%s",
991            (unsigned long long)ifp->stats.ifi_ipackets,
992            (unsigned long long)ifp->stats.ifi_ibytes,
993            (unsigned long long)ifp->stats.ifi_iqdrops,
994            (unsigned long long)ifp->stats.ifi_imcasts,
995            VTY_NEWLINE);
996
997   vty_out (vty, "    input errors %llu%s",
998            (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
999
1000   vty_out (vty, "    output packets %llu, bytes %llu,"
1001            " multicast packets %llu%s",
1002            (unsigned long long)ifp->stats.ifi_opackets,
1003            (unsigned long long)ifp->stats.ifi_obytes,
1004            (unsigned long long)ifp->stats.ifi_omcasts,
1005            VTY_NEWLINE);
1006
1007   vty_out (vty, "    output errors %llu%s",
1008            (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
1009
1010   vty_out (vty, "    collisions %llu%s",
1011            (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
1012 #else
1013   /* Statistics print out using sysctl (). */
1014   vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu,"
1015            " multicast packets %lu%s",
1016            ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1017            ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1018            VTY_NEWLINE);
1019
1020   vty_out (vty, "    input errors %lu%s",
1021            ifp->stats.ifi_ierrors, VTY_NEWLINE);
1022
1023   vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s",
1024            ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1025            ifp->stats.ifi_omcasts, VTY_NEWLINE);
1026
1027   vty_out (vty, "    output errors %lu%s",
1028            ifp->stats.ifi_oerrors, VTY_NEWLINE);
1029
1030   vty_out (vty, "    collisions %lu%s",
1031            ifp->stats.ifi_collisions, VTY_NEWLINE);
1032 #endif /* __bsdi__ || __NetBSD__ */
1033 #endif /* HAVE_NET_RT_IFLIST */
1034 }
1035
1036 /* Wrapper hook point for zebra daemon so that ifindex can be set 
1037  * DEFUN macro not used as extract.pl HAS to ignore this
1038  * See also interface_cmd in lib/if.c
1039  */ 
1040 DEFUN_NOSH (zebra_interface,
1041             zebra_interface_cmd,
1042             "interface IFNAME",
1043             "Select an interface to configure\n"
1044             "Interface's name\n")
1045 {
1046   int ret;
1047   struct interface *ifp;
1048   
1049   /* Call lib interface() */
1050   if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
1051     return ret;
1052
1053   ifp = vty->index;
1054
1055   if (ifp->ifindex == IFINDEX_INTERNAL)
1056     /* Is this really necessary?  Shouldn't status be initialized to 0
1057        in that case? */
1058     UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
1059
1060   return ret;
1061 }
1062
1063 ALIAS (zebra_interface,
1064        zebra_interface_vrf_cmd,
1065        "interface IFNAME " VRF_CMD_STR,
1066        "Select an interface to configure\n"
1067        "Interface's name\n"
1068        VRF_CMD_HELP_STR)
1069
1070 struct cmd_node interface_node =
1071 {
1072   INTERFACE_NODE,
1073   "%s(config-if)# ",
1074   1
1075 };
1076
1077 /* Show all interfaces to vty. */
1078 DEFUN (show_interface, show_interface_cmd,
1079        "show interface",
1080        SHOW_STR
1081        "Interface status and configuration\n")
1082 {
1083   struct listnode *node;
1084   struct interface *ifp;
1085   vrf_id_t vrf_id = VRF_DEFAULT;
1086
1087 #ifdef HAVE_PROC_NET_DEV
1088   /* If system has interface statistics via proc file system, update
1089      statistics. */
1090   ifstat_update_proc ();
1091 #endif /* HAVE_PROC_NET_DEV */
1092 #ifdef HAVE_NET_RT_IFLIST
1093   ifstat_update_sysctl ();
1094 #endif /* HAVE_NET_RT_IFLIST */
1095
1096   if (argc > 0)
1097     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1098
1099   /* All interface print. */
1100   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1101     if_dump_vty (vty, ifp);
1102
1103   return CMD_SUCCESS;
1104 }
1105
1106 ALIAS (show_interface,
1107        show_interface_vrf_cmd,
1108        "show interface " VRF_CMD_STR,
1109        SHOW_STR
1110        "Interface status and configuration\n"
1111        VRF_CMD_HELP_STR)
1112
1113 /* Show all interfaces to vty. */
1114 DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
1115        "show interface " VRF_ALL_CMD_STR,
1116        SHOW_STR
1117        "Interface status and configuration\n"
1118        VRF_ALL_CMD_HELP_STR)
1119 {
1120   struct listnode *node;
1121   struct interface *ifp;
1122   vrf_iter_t iter;
1123
1124 #ifdef HAVE_PROC_NET_DEV
1125   /* If system has interface statistics via proc file system, update
1126      statistics. */
1127   ifstat_update_proc ();
1128 #endif /* HAVE_PROC_NET_DEV */
1129 #ifdef HAVE_NET_RT_IFLIST
1130   ifstat_update_sysctl ();
1131 #endif /* HAVE_NET_RT_IFLIST */
1132
1133   /* All interface print. */
1134   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1135     for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1136       if_dump_vty (vty, ifp);
1137
1138   return CMD_SUCCESS;
1139 }
1140
1141 /* Show specified interface to vty. */
1142 DEFUN (show_interface_name, show_interface_name_cmd,
1143        "show interface IFNAME",
1144        SHOW_STR
1145        "Interface status and configuration\n"
1146        "Interface name\n")
1147 {
1148   struct interface *ifp;
1149   vrf_id_t vrf_id = VRF_DEFAULT;
1150
1151 #ifdef HAVE_PROC_NET_DEV
1152   /* If system has interface statistics via proc file system, update
1153      statistics. */
1154   ifstat_update_proc ();
1155 #endif /* HAVE_PROC_NET_DEV */
1156 #ifdef HAVE_NET_RT_IFLIST
1157   ifstat_update_sysctl ();
1158 #endif /* HAVE_NET_RT_IFLIST */
1159
1160   if (argc > 1)
1161     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1162
1163   /* Specified interface print. */
1164   ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1165   if (ifp == NULL)
1166     {
1167       vty_out (vty, "%% Can't find interface %s%s", argv[0],
1168                VTY_NEWLINE);
1169       return CMD_WARNING;
1170     }
1171   if_dump_vty (vty, ifp);
1172
1173   return CMD_SUCCESS;
1174 }
1175
1176 ALIAS (show_interface_name,
1177        show_interface_name_vrf_cmd,
1178        "show interface IFNAME " VRF_CMD_STR,
1179        SHOW_STR
1180        "Interface status and configuration\n"
1181        "Interface name\n"
1182        VRF_CMD_HELP_STR)
1183
1184 /* Show specified interface to vty. */
1185 DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1186        "show interface IFNAME " VRF_ALL_CMD_STR,
1187        SHOW_STR
1188        "Interface status and configuration\n"
1189        "Interface name\n"
1190        VRF_ALL_CMD_HELP_STR)
1191 {
1192   struct interface *ifp;
1193   vrf_iter_t iter;
1194   int found = 0;
1195
1196 #ifdef HAVE_PROC_NET_DEV
1197   /* If system has interface statistics via proc file system, update
1198      statistics. */
1199   ifstat_update_proc ();
1200 #endif /* HAVE_PROC_NET_DEV */
1201 #ifdef HAVE_NET_RT_IFLIST
1202   ifstat_update_sysctl ();
1203 #endif /* HAVE_NET_RT_IFLIST */
1204
1205   /* All interface print. */
1206   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1207     {
1208       /* Specified interface print. */
1209       ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1210       if (ifp)
1211         {
1212           if_dump_vty (vty, ifp);
1213           found++;
1214         }
1215     }
1216
1217   if (!found)
1218     {
1219       vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1220       return CMD_WARNING;
1221     }
1222
1223   return CMD_SUCCESS;
1224 }
1225
1226 static void
1227 if_show_description (struct vty *vty, vrf_id_t vrf_id)
1228 {
1229   struct listnode *node;
1230   struct interface *ifp;
1231
1232   vty_out (vty, "Interface       Status  Protocol  Description%s", VTY_NEWLINE);
1233   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1234     {
1235       int len;
1236
1237       len = vty_out (vty, "%s", ifp->name);
1238       vty_out (vty, "%*s", (16 - len), " ");
1239       
1240       if (if_is_up(ifp))
1241         {
1242           vty_out (vty, "up      ");
1243           if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1244             {
1245               if (if_is_running(ifp))
1246                 vty_out (vty, "up        ");
1247               else
1248                 vty_out (vty, "down      ");
1249             }
1250           else
1251             {
1252               vty_out (vty, "unknown   ");
1253             }
1254         }
1255       else
1256         {
1257           vty_out (vty, "down    down      ");
1258         }
1259
1260       if (ifp->desc)
1261         vty_out (vty, "%s", ifp->desc);
1262       vty_out (vty, "%s", VTY_NEWLINE);
1263     }
1264 }
1265
1266 DEFUN (show_interface_desc,
1267        show_interface_desc_cmd,
1268        "show interface description",
1269        SHOW_STR
1270        "Interface status and configuration\n"
1271        "Interface description\n")
1272 {
1273   vrf_id_t vrf_id = VRF_DEFAULT;
1274
1275   if (argc > 0)
1276     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1277
1278   if_show_description (vty, vrf_id);
1279
1280   return CMD_SUCCESS;
1281 }
1282
1283 ALIAS (show_interface_desc,
1284        show_interface_desc_vrf_cmd,
1285        "show interface description " VRF_CMD_STR,
1286        SHOW_STR
1287        "Interface status and configuration\n"
1288        "Interface description\n"
1289        VRF_CMD_HELP_STR)
1290
1291 DEFUN (show_interface_desc_vrf_all,
1292        show_interface_desc_vrf_all_cmd,
1293        "show interface description " VRF_ALL_CMD_STR,
1294        SHOW_STR
1295        "Interface status and configuration\n"
1296        "Interface description\n"
1297        VRF_ALL_CMD_HELP_STR)
1298 {
1299   vrf_iter_t iter;
1300
1301   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1302     if (!list_isempty (vrf_iter2iflist (iter)))
1303       {
1304         vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1305                  vrf_iter2id (iter),
1306                  VTY_NEWLINE, VTY_NEWLINE);
1307         if_show_description (vty, vrf_iter2id (iter));
1308       }
1309
1310   return CMD_SUCCESS;
1311 }
1312
1313 DEFUN (multicast,
1314        multicast_cmd,
1315        "multicast",
1316        "Set multicast flag to interface\n")
1317 {
1318   int ret;
1319   struct interface *ifp;
1320   struct zebra_if *if_data;
1321
1322   ifp = (struct interface *) vty->index;
1323   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1324     {
1325       ret = if_set_flags (ifp, IFF_MULTICAST);
1326       if (ret < 0)
1327         {
1328           vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1329           return CMD_WARNING;
1330         }
1331       if_refresh (ifp);
1332     }
1333   if_data = ifp->info;
1334   if_data->multicast = IF_ZEBRA_MULTICAST_ON;
1335
1336   return CMD_SUCCESS;
1337 }
1338
1339 DEFUN (no_multicast,
1340        no_multicast_cmd,
1341        "no multicast",
1342        NO_STR
1343        "Unset multicast flag to interface\n")
1344 {
1345   int ret;
1346   struct interface *ifp;
1347   struct zebra_if *if_data;
1348
1349   ifp = (struct interface *) vty->index;
1350   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1351     {
1352       ret = if_unset_flags (ifp, IFF_MULTICAST);
1353       if (ret < 0)
1354         {
1355           vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1356           return CMD_WARNING;
1357         }
1358       if_refresh (ifp);
1359     }
1360   if_data = ifp->info;
1361   if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1362
1363   return CMD_SUCCESS;
1364 }
1365
1366 /* Hacky: create a dummy node just to hang a config-writer callback off it */
1367 static struct cmd_node zebra_if_defaults_node = {
1368   ZEBRA_IF_DEFAULTS_NODE,
1369   "",
1370   1,
1371 };
1372
1373 static int
1374 config_write_zebra_if_defaults (struct vty *vty)
1375 {
1376   if (zif_defaults.linkdetect != IF_LINKDETECT_UNSPEC)
1377     vty_out (vty, "default link-detect %s%s",
1378              zif_defaults.linkdetect == IF_LINKDETECT_ON ? "on" : "off",
1379              VTY_NEWLINE);
1380   return 0;
1381 }
1382
1383 DEFUN(default_linkdetect,
1384       default_linkdetect_cmd,
1385       "default link-detect (on|off)",
1386       "Configure defaults of settings\n"
1387       "Interface link detection\n"
1388       "Interface link-detect defaults to enabled\n"
1389       "Interface link-detect defaults to disabled\n")
1390 {
1391   zebra_if_linkdetect prev = zif_defaults.linkdetect;
1392   struct listnode *node;
1393   struct interface *ifp;
1394   vrf_iter_t iter;
1395   
1396   if (strcmp (argv[1], "on") == 0)
1397     zif_defaults.linkdetect = IF_LINKDETECT_ON;
1398   else
1399     zif_defaults.linkdetect = IF_LINKDETECT_OFF;
1400     
1401   if (zif_defaults.linkdetect != prev)
1402     for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1403       for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1404         if_zebra_linkdetect_set (ifp);
1405   
1406   return CMD_SUCCESS;
1407 }
1408
1409 DEFUN (linkdetect,
1410        linkdetect_cmd,
1411        "link-detect [default]",
1412        "Enable link detection on interface\n"
1413        "Leave link-detect to the default\n")
1414 {
1415   struct interface *ifp;
1416   struct zebra_if *zif;
1417   
1418   ifp = (struct interface *) vty->index;
1419   zif = ifp->info;
1420   assert (zif != NULL);
1421   
1422   zif->linkdetect = IF_LINKDETECT_ON;
1423   if_zebra_linkdetect_set (ifp);
1424   
1425   /* FIXME: Will defer status change forwarding if interface
1426      does not come down! */
1427
1428   return CMD_SUCCESS;
1429 }
1430
1431
1432 DEFUN (no_linkdetect,
1433        no_linkdetect_cmd,
1434        "no link-detect",
1435        NO_STR
1436        "Disable link detection on interface\n")
1437 {
1438   struct interface *ifp;
1439   struct zebra_if *zif;
1440   
1441   ifp = (struct interface *) vty->index;
1442   zif = ifp->info;
1443   assert (zif != NULL);
1444   
1445   zif->linkdetect = IF_LINKDETECT_OFF;
1446   if_zebra_linkdetect_set (ifp);
1447   
1448   /* FIXME: see linkdetect_cmd */
1449
1450   return CMD_SUCCESS;
1451 }
1452
1453 DEFUN (shutdown_if,
1454        shutdown_if_cmd,
1455        "shutdown",
1456        "Shutdown the selected interface\n")
1457 {
1458   int ret;
1459   struct interface *ifp;
1460   struct zebra_if *if_data;
1461
1462   ifp = (struct interface *) vty->index;
1463   if (ifp->ifindex != IFINDEX_INTERNAL)
1464     {
1465         ret = if_unset_flags (ifp, IFF_UP);
1466         if (ret < 0)
1467           {
1468             vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1469             return CMD_WARNING;
1470           }
1471         if_refresh (ifp);
1472     }
1473   if_data = ifp->info;
1474   if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1475
1476   return CMD_SUCCESS;
1477 }
1478
1479 DEFUN (no_shutdown_if,
1480        no_shutdown_if_cmd,
1481        "no shutdown",
1482        NO_STR
1483        "Shutdown the selected interface\n")
1484 {
1485   int ret;
1486   struct interface *ifp;
1487   struct zebra_if *if_data;
1488
1489   ifp = (struct interface *) vty->index;
1490
1491   if (ifp->ifindex != IFINDEX_INTERNAL)
1492     {
1493       ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1494       if (ret < 0)
1495         {
1496           vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1497           return CMD_WARNING;
1498         }
1499       if_refresh (ifp);
1500
1501       /* Some addresses (in particular, IPv6 addresses on Linux) get
1502        * removed when the interface goes down. They need to be readded.
1503        */
1504       if_addr_wakeup(ifp);
1505     }
1506
1507   if_data = ifp->info;
1508   if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1509
1510   return CMD_SUCCESS;
1511 }
1512
1513 DEFUN (bandwidth_if,
1514        bandwidth_if_cmd,
1515        "bandwidth <1-10000000>",
1516        "Set bandwidth informational parameter\n"
1517        "Bandwidth in kilobits\n")
1518 {
1519   struct interface *ifp;   
1520   unsigned int bandwidth;
1521   
1522   ifp = (struct interface *) vty->index;
1523   bandwidth = strtol(argv[0], NULL, 10);
1524
1525   /* bandwidth range is <1-10000000> */
1526   if (bandwidth < 1 || bandwidth > 10000000)
1527     {
1528       vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1529       return CMD_WARNING;
1530     }
1531   
1532   ifp->bandwidth = bandwidth;
1533
1534   /* force protocols to recalculate routes due to cost change */
1535   if (if_is_operative (ifp))
1536     zebra_interface_up_update (ifp);
1537   
1538   return CMD_SUCCESS;
1539 }
1540
1541 DEFUN (no_bandwidth_if,
1542        no_bandwidth_if_cmd,
1543        "no bandwidth",
1544        NO_STR
1545        "Set bandwidth informational parameter\n")
1546 {
1547   struct interface *ifp;   
1548   
1549   ifp = (struct interface *) vty->index;
1550
1551   ifp->bandwidth = 0;
1552   
1553   /* force protocols to recalculate routes due to cost change */
1554   if (if_is_operative (ifp))
1555     zebra_interface_up_update (ifp);
1556
1557   return CMD_SUCCESS;
1558 }
1559
1560 ALIAS (no_bandwidth_if,
1561        no_bandwidth_if_val_cmd,
1562        "no bandwidth <1-10000000>",
1563        NO_STR
1564        "Set bandwidth informational parameter\n"
1565        "Bandwidth in kilobits\n")
1566
1567 struct cmd_node link_params_node =
1568 {
1569   LINK_PARAMS_NODE,
1570   "%s(config-link-params)# ",
1571   1,
1572 };
1573
1574 static void
1575 link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field, 
1576                            uint32_t type, uint32_t value)
1577 {
1578   /* Update field as needed */
1579   if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1580     {
1581       *field = value;
1582       SET_PARAM(ifp->link_params, type);
1583
1584       /* force protocols to update LINK STATE due to parameters change */
1585       if (if_is_operative (ifp))
1586         zebra_interface_parameters_update (ifp);
1587     }
1588 }
1589 static void
1590 link_param_cmd_set_float (struct interface *ifp, float *field,
1591                           uint32_t type, float value)
1592 {
1593
1594   /* Update field as needed */
1595   if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1596     {
1597       *field = value;
1598       SET_PARAM(ifp->link_params, type);
1599
1600       /* force protocols to update LINK STATE due to parameters change */
1601       if (if_is_operative (ifp))
1602         zebra_interface_parameters_update (ifp);
1603     }
1604 }
1605
1606 static void
1607 link_param_cmd_unset (struct interface *ifp, uint32_t type)
1608 {
1609
1610   /* Unset field */
1611   UNSET_PARAM(ifp->link_params, type);
1612
1613   /* force protocols to update LINK STATE due to parameters change */
1614   if (if_is_operative (ifp))
1615     zebra_interface_parameters_update (ifp);
1616 }
1617
1618 DEFUN (link_params,
1619        link_params_cmd,
1620        "link-params",
1621        LINK_PARAMS_STR)
1622 {
1623   vty->node = LINK_PARAMS_NODE;
1624   
1625   return CMD_SUCCESS;
1626 }
1627
1628 DEFUN (exit_link_params,
1629        exit_link_params_cmd,
1630        "exit-link-params",
1631        "Exit from Link Params configuration mode\n")
1632 {
1633   if (vty->node == LINK_PARAMS_NODE)
1634     vty->node = INTERFACE_NODE;
1635   return CMD_SUCCESS;
1636 }
1637
1638 /* Specific Traffic Engineering parameters commands */
1639 DEFUN (link_params_enable,
1640        link_params_enable_cmd,
1641        "enable",
1642        "Activate link parameters on this interface\n")
1643 {
1644   struct interface *ifp = (struct interface *) vty->index;
1645     
1646   /* This command could be issue at startup, when activate MPLS TE */
1647   /* on a new interface or after a ON / OFF / ON toggle */
1648   /* In all case, TE parameters are reset to their default factory */
1649   if (IS_ZEBRA_DEBUG_EVENT)
1650     zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
1651   
1652   if (!if_link_params_get (ifp)) 
1653     {
1654       if (IS_ZEBRA_DEBUG_EVENT)
1655         zlog_debug ("Link-params: failed to init TE link parameters  %s", ifp->name);
1656       
1657       return CMD_WARNING;
1658     }
1659   
1660   /* force protocols to update LINK STATE due to parameters change */
1661   if (if_is_operative (ifp))
1662     zebra_interface_parameters_update (ifp);
1663
1664   return CMD_SUCCESS;
1665 }
1666
1667 DEFUN (no_link_params_enable,
1668        no_link_params_enable_cmd,
1669        "no enable",
1670        NO_STR
1671        "Disable link parameters on this interface\n")
1672 {
1673   struct interface *ifp = (struct interface *) vty->index;
1674
1675   zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
1676   
1677   if_link_params_free (ifp);
1678   
1679   /* force protocols to update LINK STATE due to parameters change */
1680   if (if_is_operative (ifp))
1681     zebra_interface_parameters_update (ifp);
1682
1683   return CMD_SUCCESS;
1684 }
1685
1686 /* STANDARD TE metrics */
1687 DEFUN (link_params_metric,
1688        link_params_metric_cmd,
1689        "metric <0-4294967295>",
1690        "Link metric for MPLS-TE purpose\n"
1691        "Metric value in decimal\n")
1692 {
1693   struct interface *ifp = (struct interface *) vty->index;
1694   struct if_link_params *iflp = if_link_params_get (ifp);
1695   u_int32_t metric;
1696
1697   VTY_GET_ULONG("metric", metric, argv[0]);
1698
1699   /* Update TE metric if needed */
1700   link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric);
1701   
1702   return CMD_SUCCESS;
1703 }
1704
1705 DEFUN (no_link_params_metric,
1706        no_link_params_metric_cmd,
1707        "no metric",
1708        NO_STR
1709        "Disable Link Metric on this interface\n")
1710 {
1711   struct interface *ifp = (struct interface *) vty->index;
1712   
1713   /* Unset TE Metric */
1714   link_param_cmd_unset(ifp, LP_TE);
1715   
1716   return CMD_SUCCESS;
1717 }
1718
1719 DEFUN (link_params_maxbw,
1720        link_params_maxbw_cmd,
1721        "max-bw BANDWIDTH",
1722        "Maximum bandwidth that can be used\n"
1723        "Bytes/second (IEEE floating point format)\n")
1724 {
1725   struct interface *ifp = (struct interface *) vty->index;
1726   struct if_link_params *iflp = if_link_params_get (ifp);
1727   
1728   float bw;
1729
1730   if (sscanf (argv[0], "%g", &bw) != 1)
1731     {
1732       vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
1733                VTY_NEWLINE);
1734       return CMD_WARNING;
1735     }
1736
1737   /* Check that Maximum bandwidth is not lower than other bandwidth parameters */
1738   if ((bw <= iflp->max_rsv_bw)
1739       || (bw <= iflp->unrsv_bw[0])
1740       || (bw <= iflp->unrsv_bw[1])
1741       || (bw <= iflp->unrsv_bw[2])
1742       || (bw <= iflp->unrsv_bw[3])
1743       || (bw <= iflp->unrsv_bw[4])
1744       || (bw <= iflp->unrsv_bw[5])
1745       || (bw <= iflp->unrsv_bw[6])
1746       || (bw <= iflp->unrsv_bw[7])
1747       || (bw <= iflp->ava_bw)
1748       || (bw <= iflp->res_bw)
1749       || (bw <= iflp->use_bw))
1750     {
1751       vty_out (vty,
1752                "Maximum Bandwidth could not be lower than others bandwidth%s",
1753                VTY_NEWLINE);
1754       return CMD_WARNING;
1755     }
1756
1757   /* Update Maximum Bandwidth if needed */
1758   link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
1759     
1760   return CMD_SUCCESS;
1761 }
1762
1763 DEFUN (link_params_max_rsv_bw,
1764        link_params_max_rsv_bw_cmd,
1765        "max-rsv-bw BANDWIDTH",
1766        "Maximum bandwidth that may be reserved\n"
1767        "Bytes/second (IEEE floating point format)\n")
1768 {
1769   struct interface *ifp = (struct interface *) vty->index;
1770   struct if_link_params *iflp = if_link_params_get (ifp);
1771   float bw;
1772
1773   if (sscanf (argv[0], "%g", &bw) != 1)
1774     {
1775       vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
1776                VTY_NEWLINE);
1777       return CMD_WARNING;
1778     }
1779
1780   /* Check that bandwidth is not greater than maximum bandwidth parameter */
1781   if (bw > iflp->max_bw)
1782     {
1783       vty_out (vty,
1784                "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1785                iflp->max_bw, VTY_NEWLINE);
1786       return CMD_WARNING;
1787     }
1788
1789   /* Update Maximum Reservable Bandwidth if needed */
1790   link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
1791   
1792   return CMD_SUCCESS;
1793 }
1794
1795 DEFUN (link_params_unrsv_bw,
1796        link_params_unrsv_bw_cmd,
1797        "unrsv-bw <0-7> BANDWIDTH",
1798        "Unreserved bandwidth at each priority level\n"
1799        "Priority\n"
1800        "Bytes/second (IEEE floating point format)\n")
1801 {
1802   struct interface *ifp = (struct interface *) vty->index;
1803   struct if_link_params *iflp = if_link_params_get (ifp);
1804   int priority;
1805   float bw;
1806
1807   /* We don't have to consider about range check here. */
1808   if (sscanf (argv[0], "%d", &priority) != 1)
1809     {
1810       vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1811                VTY_NEWLINE);
1812       return CMD_WARNING;
1813     }
1814
1815   if (sscanf (argv[1], "%g", &bw) != 1)
1816     {
1817       vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1818                VTY_NEWLINE);
1819       return CMD_WARNING;
1820     }
1821
1822   /* Check that bandwidth is not greater than maximum bandwidth parameter */
1823   if (bw > iflp->max_bw)
1824     {
1825       vty_out (vty,
1826                "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1827                iflp->max_bw, VTY_NEWLINE);
1828       return CMD_WARNING;
1829     }
1830
1831   /* Update Unreserved Bandwidth if needed */
1832   link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
1833   
1834   return CMD_SUCCESS;
1835 }
1836
1837 DEFUN (link_params_admin_grp,
1838        link_params_admin_grp_cmd,
1839        "admin-grp BITPATTERN",
1840        "Administrative group membership\n"
1841        "32-bit Hexadecimal value (e.g. 0xa1)\n")
1842 {
1843   struct interface *ifp = (struct interface *) vty->index;
1844   struct if_link_params *iflp = if_link_params_get (ifp);
1845   unsigned long value;
1846
1847   if (sscanf (argv[0], "0x%lx", &value) != 1)
1848     {
1849       vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
1850                safe_strerror (errno), VTY_NEWLINE);
1851       return CMD_WARNING;
1852     }
1853
1854   /* Update Administrative Group if needed */
1855   link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
1856   
1857   return CMD_SUCCESS;
1858 }
1859
1860 DEFUN (no_link_params_admin_grp,
1861        no_link_params_admin_grp_cmd,
1862        "no admin-grp",
1863        NO_STR
1864        "Disable Administrative group membership on this interface\n")
1865 {
1866   struct interface *ifp = (struct interface *) vty->index;
1867   
1868   /* Unset Admin Group */
1869   link_param_cmd_unset(ifp, LP_ADM_GRP);
1870   
1871   return CMD_SUCCESS;
1872 }
1873
1874 /* RFC5392 & RFC5316: INTER-AS */
1875 DEFUN (link_params_inter_as,
1876        link_params_inter_as_cmd,
1877        "neighbor A.B.C.D as <1-4294967295>",
1878        "Configure remote ASBR information (Neighbor IP address and AS number)\n"
1879        "Remote IP address in dot decimal A.B.C.D\n"
1880        "Remote AS number\n"
1881        "AS number in the range <1-4294967295>\n")
1882 {
1883
1884   struct interface *ifp = (struct interface *) vty->index;
1885   struct if_link_params *iflp = if_link_params_get (ifp);
1886   struct in_addr addr;
1887   u_int32_t as;
1888
1889   if (!inet_aton (argv[0], &addr))
1890     {
1891       vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
1892       return CMD_WARNING;
1893     }
1894     
1895   VTY_GET_ULONG("AS number", as, argv[1]);
1896   
1897   /* Update Remote IP and Remote AS fields if needed */
1898   if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
1899       || iflp->rmt_as != as
1900       || iflp->rmt_ip.s_addr != addr.s_addr)
1901     {
1902
1903       iflp->rmt_as = as;
1904       iflp->rmt_ip.s_addr = addr.s_addr;
1905       SET_PARAM(iflp, LP_RMT_AS);
1906
1907       /* force protocols to update LINK STATE due to parameters change */
1908       if (if_is_operative (ifp))
1909         zebra_interface_parameters_update (ifp);
1910     }
1911   return CMD_SUCCESS;
1912 }
1913
1914 DEFUN (no_link_params_inter_as,
1915        no_link_params_inter_as_cmd,
1916        "no neighbor",
1917        NO_STR
1918        "Remove Neighbor IP address and AS number for Inter-AS TE\n")
1919 {
1920
1921   struct interface *ifp = (struct interface *) vty->index;
1922   struct if_link_params *iflp = if_link_params_get (ifp);
1923
1924   /* Reset Remote IP and AS neighbor */
1925   iflp->rmt_as = 0;
1926   iflp->rmt_ip.s_addr = 0;
1927   UNSET_PARAM(iflp, LP_RMT_AS);
1928
1929   /* force protocols to update LINK STATE due to parameters change */
1930   if (if_is_operative (ifp))
1931     zebra_interface_parameters_update (ifp);
1932
1933   return CMD_SUCCESS;
1934 }
1935
1936 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
1937 DEFUN (link_params_delay,
1938        link_params_delay_cmd,
1939        "delay <0-16777215>",
1940        "Unidirectional Average Link Delay\n"
1941        "Average delay in micro-second as decimal (0...16777215)\n")
1942 {
1943
1944   struct interface *ifp = (struct interface *) vty->index;
1945   struct if_link_params *iflp = if_link_params_get (ifp);
1946   u_int32_t delay = 0, low = 0, high = 0;
1947   u_int8_t update = 0;
1948
1949   /* Get and Check new delay values */
1950   VTY_GET_ULONG("delay", delay, argv[0]);
1951   switch (argc)
1952     {
1953     case 1:
1954       /* Check new delay value against old Min and Max delays if set */
1955       if (IS_PARAM_SET(iflp, LP_MM_DELAY)
1956           && (delay <= iflp->min_delay || delay >= iflp->max_delay))
1957         {
1958           vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1959                    iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
1960           return CMD_WARNING;
1961         }
1962       /* Update delay if value is not set or change */
1963       if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
1964         {
1965           iflp->av_delay = delay;
1966           SET_PARAM(iflp, LP_DELAY);
1967           update = 1;
1968         }
1969       /* Unset Min and Max delays if already set */
1970       if (IS_PARAM_SET(iflp, LP_MM_DELAY))
1971         {
1972           iflp->min_delay = 0;
1973           iflp->max_delay = 0;
1974           UNSET_PARAM(iflp, LP_MM_DELAY);
1975           update = 1;
1976         }
1977       break;
1978     case 2:
1979       vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
1980                VTY_NEWLINE);
1981       return CMD_WARNING;
1982     break;
1983     case 3:
1984       VTY_GET_ULONG("minimum delay", low, argv[1]);
1985       VTY_GET_ULONG("maximum delay", high, argv[2]);
1986       /* Check new delays value coherency */
1987       if (delay <= low || delay >= high)
1988         {
1989           vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1990                    low, high, VTY_NEWLINE);
1991           return CMD_WARNING;
1992         }
1993       /* Update Delays if needed */
1994       if (IS_PARAM_UNSET(iflp, LP_DELAY)
1995           || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
1996           || iflp->av_delay != delay
1997           || iflp->min_delay != low
1998           || iflp->max_delay != high)
1999         {
2000           iflp->av_delay = delay;
2001           SET_PARAM(iflp, LP_DELAY);
2002           iflp->min_delay = low;
2003           iflp->max_delay = high;
2004           SET_PARAM(iflp, LP_MM_DELAY);
2005           update = 1;
2006         }
2007       break;
2008     default:
2009       return CMD_WARNING;
2010       break;
2011     }
2012
2013   /* force protocols to update LINK STATE due to parameters change */
2014   if (update == 1 && if_is_operative (ifp))
2015     zebra_interface_parameters_update (ifp);
2016
2017   return CMD_SUCCESS;
2018 }
2019
2020 ALIAS (link_params_delay,
2021        link_params_delay_mm_cmd,
2022        "delay <0-16777215> min <0-16777215> max <0-16777215>",
2023        "Unidirectional Average Link Delay (optionally Minimum and Maximum delays)\n"
2024        "Average delay in micro-second as decimal (0...16777215)\n"
2025        "Minimum delay\n"
2026        "Minimum delay in micro-second as decimal (0...16777215)\n"
2027        "Maximum delay\n"
2028        "Maximum delay in micro-second as decimal (0...16777215)\n")
2029
2030 DEFUN (no_link_params_delay,
2031        no_link_params_delay_cmd,
2032        "no delay",
2033        NO_STR
2034        "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2035 {
2036   struct interface *ifp = (struct interface *) vty->index;
2037   struct if_link_params *iflp = if_link_params_get (ifp);
2038   
2039   /* Unset Delays */
2040   iflp->av_delay = 0;
2041   UNSET_PARAM(iflp, LP_DELAY);
2042   iflp->min_delay = 0;
2043   iflp->max_delay = 0;
2044   UNSET_PARAM(iflp, LP_MM_DELAY);
2045   
2046   /* force protocols to update LINK STATE due to parameters change */
2047   if (if_is_operative (ifp))
2048     zebra_interface_parameters_update (ifp);
2049   
2050   return CMD_SUCCESS;
2051 }
2052
2053 DEFUN (link_params_delay_var,
2054        link_params_delay_var_cmd,
2055        "delay-variation <0-16777215>",
2056        "Unidirectional Link Delay Variation\n"
2057        "delay variation in micro-second as decimal (0...16777215)\n")
2058 {
2059   struct interface *ifp = (struct interface *) vty->index;
2060   struct if_link_params *iflp = if_link_params_get (ifp);
2061   u_int32_t value;
2062   
2063   VTY_GET_ULONG("delay variation", value, argv[0]);
2064   
2065   /* Update Delay Variation if needed */
2066   link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2067   
2068   return CMD_SUCCESS;
2069 }
2070
2071 DEFUN (no_link_params_delay_var,
2072        no_link_params_delay_var_cmd,
2073        "no delay-variation",
2074        NO_STR
2075        "Disable Unidirectional Delay Variation on this interface\n")
2076 {
2077   struct interface *ifp = (struct interface *) vty->index;
2078   
2079   /* Unset Delay Variation */
2080   link_param_cmd_unset(ifp, LP_DELAY_VAR);
2081   
2082   return CMD_SUCCESS;
2083 }
2084
2085 DEFUN (link_params_pkt_loss,
2086        link_params_pkt_loss_cmd,
2087        "packet-loss PERCENTAGE",
2088        "Unidirectional Link Packet Loss\n"
2089        "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2090 {
2091   struct interface *ifp = (struct interface *) vty->index;
2092   struct if_link_params *iflp = if_link_params_get (ifp);
2093   float fval;
2094
2095   if (sscanf (argv[0], "%g", &fval) != 1)
2096     {
2097       vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
2098                VTY_NEWLINE);
2099       return CMD_WARNING;
2100     }
2101
2102   if (fval > MAX_PKT_LOSS)
2103     fval = MAX_PKT_LOSS;
2104
2105   /* Update Packet Loss if needed */
2106   link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2107   
2108   return CMD_SUCCESS;
2109 }
2110
2111 DEFUN (no_link_params_pkt_loss,
2112        no_link_params_pkt_loss_cmd,
2113        "no packet-loss",
2114        NO_STR
2115        "Disable Unidirectional Link Packet Loss on this interface\n")
2116 {
2117   struct interface *ifp = (struct interface *) vty->index;
2118   
2119   /* Unset Packet Loss */
2120   link_param_cmd_unset(ifp, LP_PKT_LOSS);
2121   
2122   return CMD_SUCCESS;
2123 }
2124
2125 DEFUN (link_params_res_bw,
2126        link_params_res_bw_cmd,
2127        "res-bw BANDWIDTH",
2128        "Unidirectional Residual Bandwidth\n"
2129        "Bytes/second (IEEE floating point format)\n")
2130 {
2131   struct interface *ifp = (struct interface *) vty->index;
2132   struct if_link_params *iflp = if_link_params_get (ifp);
2133   float bw;
2134
2135   if (sscanf (argv[0], "%g", &bw) != 1)
2136     {
2137       vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
2138                VTY_NEWLINE);
2139       return CMD_WARNING;
2140     }
2141
2142   /* Check that bandwidth is not greater than maximum bandwidth parameter */
2143   if (bw > iflp->max_bw)
2144     {
2145       vty_out (vty,
2146                "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2147                iflp->max_bw, VTY_NEWLINE);
2148       return CMD_WARNING;
2149     }
2150
2151   /* Update Residual Bandwidth if needed */
2152   link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
2153   
2154   return CMD_SUCCESS;
2155 }
2156
2157 DEFUN (no_link_params_res_bw,
2158        no_link_params_res_bw_cmd,
2159        "no res-bw",
2160        NO_STR
2161        "Disable Unidirectional Residual Bandwidth on this interface\n")
2162 {
2163   struct interface *ifp = (struct interface *) vty->index;
2164   
2165   /* Unset Residual Bandwidth */
2166   link_param_cmd_unset(ifp, LP_RES_BW);
2167   
2168   return CMD_SUCCESS;
2169 }
2170
2171 DEFUN (link_params_ava_bw,
2172        link_params_ava_bw_cmd,
2173        "ava-bw BANDWIDTH",
2174        "Unidirectional Available Bandwidth\n"
2175        "Bytes/second (IEEE floating point format)\n")
2176 {
2177   struct interface *ifp = (struct interface *) vty->index;
2178   struct if_link_params *iflp = if_link_params_get (ifp);
2179   float bw;
2180
2181   if (sscanf (argv[0], "%g", &bw) != 1)
2182     {
2183       vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
2184                VTY_NEWLINE);
2185       return CMD_WARNING;
2186     }
2187
2188   /* Check that bandwidth is not greater than maximum bandwidth parameter */
2189   if (bw > iflp->max_bw)
2190     {
2191       vty_out (vty,
2192                "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2193                iflp->max_bw, VTY_NEWLINE);
2194       return CMD_WARNING;
2195     }
2196
2197   /* Update Residual Bandwidth if needed */
2198   link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2199   
2200   return CMD_SUCCESS;
2201 }
2202
2203 DEFUN (no_link_params_ava_bw,
2204        no_link_params_ava_bw_cmd,
2205        "no ava-bw",
2206        NO_STR
2207        "Disable Unidirectional Available Bandwidth on this interface\n")
2208 {
2209   struct interface *ifp = (struct interface *) vty->index;
2210   
2211   /* Unset Available Bandwidth */
2212   link_param_cmd_unset(ifp, LP_AVA_BW);
2213   
2214   return CMD_SUCCESS;
2215 }
2216
2217 DEFUN (link_params_use_bw,
2218        link_params_use_bw_cmd,
2219        "use-bw BANDWIDTH",
2220        "Unidirectional Utilised Bandwidth\n"
2221        "Bytes/second (IEEE floating point format)\n")
2222 {
2223   struct interface *ifp = (struct interface *) vty->index;
2224   struct if_link_params *iflp = if_link_params_get (ifp);
2225   float bw;
2226
2227   if (sscanf (argv[0], "%g", &bw) != 1)
2228     {
2229       vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
2230                VTY_NEWLINE);
2231       return CMD_WARNING;
2232     }
2233
2234   /* Check that bandwidth is not greater than maximum bandwidth parameter */
2235   if (bw > iflp->max_bw)
2236     {
2237       vty_out (vty,
2238                "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2239                iflp->max_bw, VTY_NEWLINE);
2240       return CMD_WARNING;
2241     }
2242
2243   /* Update Utilized Bandwidth if needed */
2244   link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
2245   
2246   return CMD_SUCCESS;
2247 }
2248
2249 DEFUN (no_link_params_use_bw,
2250        no_link_params_use_bw_cmd,
2251        "no use-bw",
2252        NO_STR
2253        "Disable Unidirectional Utilised Bandwidth on this interface\n")
2254 {
2255   struct interface *ifp = (struct interface *) vty->index;
2256   
2257   /* Unset Utilised Bandwidth */
2258   link_param_cmd_unset(ifp, LP_USE_BW);
2259   
2260   return CMD_SUCCESS;
2261 }
2262
2263 static int
2264 ip_address_install (struct vty *vty, struct interface *ifp,
2265                     const char *addr_str, const char *peer_str,
2266                     const char *label)
2267 {
2268   struct zebra_if *if_data;
2269   struct prefix_ipv4 cp;
2270   struct connected *ifc;
2271   struct prefix_ipv4 *p;
2272   int ret;
2273
2274   if_data = ifp->info;
2275
2276   ret = str2prefix_ipv4 (addr_str, &cp);
2277   if (ret <= 0)
2278     {
2279       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2280       return CMD_WARNING;
2281     }
2282
2283   ifc = connected_check (ifp, (struct prefix *) &cp);
2284   if (! ifc)
2285     {
2286       ifc = connected_new ();
2287       ifc->ifp = ifp;
2288
2289       /* Address. */
2290       p = prefix_ipv4_new ();
2291       *p = cp;
2292       ifc->address = (struct prefix *) p;
2293
2294       /* Broadcast. */
2295       if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
2296         {
2297           p = prefix_ipv4_new ();
2298           *p = cp;
2299           p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
2300           ifc->destination = (struct prefix *) p;
2301         }
2302
2303       /* Label. */
2304       if (label)
2305         ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
2306
2307       /* Add to linked list. */
2308       listnode_add (ifp->connected, ifc);
2309     }
2310
2311   /* This address is configured from zebra. */
2312   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2313     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2314
2315   /* In case of this route need to install kernel. */
2316   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2317       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2318       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
2319     {
2320       /* Some system need to up the interface to set IP address. */
2321       if (! if_is_up (ifp))
2322         {
2323           if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2324           if_refresh (ifp);
2325         }
2326
2327       ret = if_set_prefix (ifp, ifc);
2328       if (ret < 0)
2329         {
2330           vty_out (vty, "%% Can't set interface IP address: %s.%s", 
2331                    safe_strerror(errno), VTY_NEWLINE);
2332           return CMD_WARNING;
2333         }
2334
2335       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2336       /* The address will be advertised to zebra clients when the notification
2337        * from the kernel has been received.
2338        * It will also be added to the subnet chain list, then. */
2339     }
2340
2341   return CMD_SUCCESS;
2342 }
2343
2344 static int
2345 ip_address_uninstall (struct vty *vty, struct interface *ifp,
2346                       const char *addr_str, const char *peer_str,
2347                       const char *label)
2348 {
2349   struct prefix_ipv4 cp;
2350   struct connected *ifc;
2351   int ret;
2352
2353   /* Convert to prefix structure. */
2354   ret = str2prefix_ipv4 (addr_str, &cp);
2355   if (ret <= 0)
2356     {
2357       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2358       return CMD_WARNING;
2359     }
2360
2361   /* Check current interface address. */
2362   ifc = connected_check (ifp, (struct prefix *) &cp);
2363   if (! ifc)
2364     {
2365       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2366       return CMD_WARNING;
2367     }
2368
2369   /* This is not configured address. */
2370   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2371     return CMD_WARNING;
2372
2373   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2374   
2375   /* This is not real address or interface is not active. */
2376   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2377       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2378     {
2379       listnode_delete (ifp->connected, ifc);
2380       connected_free (ifc);
2381       return CMD_WARNING;
2382     }
2383
2384   /* This is real route. */
2385   ret = if_unset_prefix (ifp, ifc);
2386   if (ret < 0)
2387     {
2388       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
2389                safe_strerror(errno), VTY_NEWLINE);
2390       return CMD_WARNING;
2391     }
2392   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2393   /* we will receive a kernel notification about this route being removed.
2394    * this will trigger its removal from the connected list. */
2395   return CMD_SUCCESS;
2396 }
2397
2398 DEFUN (ip_address,
2399        ip_address_cmd,
2400        "ip address A.B.C.D/M",
2401        "Interface Internet Protocol config commands\n"
2402        "Set the IP address of an interface\n"
2403        "IP address (e.g. 10.0.0.1/8)\n")
2404 {
2405   return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
2406 }
2407
2408 DEFUN (no_ip_address,
2409        no_ip_address_cmd,
2410        "no ip address A.B.C.D/M",
2411        NO_STR
2412        "Interface Internet Protocol config commands\n"
2413        "Set the IP address of an interface\n"
2414        "IP Address (e.g. 10.0.0.1/8)")
2415 {
2416   return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
2417 }
2418
2419 #ifdef HAVE_NETLINK
2420 DEFUN (ip_address_label,
2421        ip_address_label_cmd,
2422        "ip address A.B.C.D/M label LINE",
2423        "Interface Internet Protocol config commands\n"
2424        "Set the IP address of an interface\n"
2425        "IP address (e.g. 10.0.0.1/8)\n"
2426        "Label of this address\n"
2427        "Label\n")
2428 {
2429   return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
2430 }
2431
2432 DEFUN (no_ip_address_label,
2433        no_ip_address_label_cmd,
2434        "no ip address A.B.C.D/M label LINE",
2435        NO_STR
2436        "Interface Internet Protocol config commands\n"
2437        "Set the IP address of an interface\n"
2438        "IP address (e.g. 10.0.0.1/8)\n"
2439        "Label of this address\n"
2440        "Label\n")
2441 {
2442   return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
2443 }
2444 #endif /* HAVE_NETLINK */
2445
2446 #ifdef HAVE_IPV6
2447 static int
2448 ipv6_address_install (struct vty *vty, struct interface *ifp,
2449                       const char *addr_str, const char *peer_str,
2450                       const char *label, int secondary)
2451 {
2452   struct zebra_if *if_data;
2453   struct prefix_ipv6 cp;
2454   struct connected *ifc;
2455   struct prefix_ipv6 *p;
2456   int ret;
2457
2458   if_data = ifp->info;
2459
2460   ret = str2prefix_ipv6 (addr_str, &cp);
2461   if (ret <= 0)
2462     {
2463       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2464       return CMD_WARNING;
2465     }
2466
2467   ifc = connected_check (ifp, (struct prefix *) &cp);
2468   if (! ifc)
2469     {
2470       ifc = connected_new ();
2471       ifc->ifp = ifp;
2472
2473       /* Address. */
2474       p = prefix_ipv6_new ();
2475       *p = cp;
2476       ifc->address = (struct prefix *) p;
2477
2478       /* Secondary. */
2479       if (secondary)
2480         SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
2481
2482       /* Label. */
2483       if (label)
2484         ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
2485
2486       /* Add to linked list. */
2487       listnode_add (ifp->connected, ifc);
2488     }
2489
2490   /* This address is configured from zebra. */
2491   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2492     SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2493
2494   /* In case of this route need to install kernel. */
2495   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2496       && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2497       && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
2498     {
2499       /* Some system need to up the interface to set IP address. */
2500       if (! if_is_up (ifp))
2501         {
2502           if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2503           if_refresh (ifp);
2504         }
2505
2506       ret = if_prefix_add_ipv6 (ifp, ifc);
2507
2508       if (ret < 0)
2509         {
2510           vty_out (vty, "%% Can't set interface IP address: %s.%s", 
2511                    safe_strerror(errno), VTY_NEWLINE);
2512           return CMD_WARNING;
2513         }
2514
2515       SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2516       /* The address will be advertised to zebra clients when the notification
2517        * from the kernel has been received. */
2518     }
2519
2520   return CMD_SUCCESS;
2521 }
2522
2523 static int
2524 ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
2525                         const char *addr_str, const char *peer_str,
2526                         const char *label, int secondry)
2527 {
2528   struct prefix_ipv6 cp;
2529   struct connected *ifc;
2530   int ret;
2531
2532   /* Convert to prefix structure. */
2533   ret = str2prefix_ipv6 (addr_str, &cp);
2534   if (ret <= 0)
2535     {
2536       vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2537       return CMD_WARNING;
2538     }
2539
2540   /* Check current interface address. */
2541   ifc = connected_check (ifp, (struct prefix *) &cp);
2542   if (! ifc)
2543     {
2544       vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2545       return CMD_WARNING;
2546     }
2547
2548   /* This is not configured address. */
2549   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2550     return CMD_WARNING;
2551
2552   UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2553
2554   /* This is not real address or interface is not active. */
2555   if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2556       || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2557     {
2558       listnode_delete (ifp->connected, ifc);
2559       connected_free (ifc);
2560       return CMD_WARNING;
2561     }
2562
2563   /* This is real route. */
2564   ret = if_prefix_delete_ipv6 (ifp, ifc);
2565   if (ret < 0)
2566     {
2567       vty_out (vty, "%% Can't unset interface IP address: %s.%s", 
2568                safe_strerror(errno), VTY_NEWLINE);
2569       return CMD_WARNING;
2570     }
2571
2572   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2573   /* This information will be propagated to the zclients when the
2574    * kernel notification is received. */
2575   return CMD_SUCCESS;
2576 }
2577
2578 DEFUN (ipv6_address,
2579        ipv6_address_cmd,
2580        "ipv6 address X:X::X:X/M",
2581        "Interface IPv6 config commands\n"
2582        "Set the IP address of an interface\n"
2583        "IPv6 address (e.g. 3ffe:506::1/48)\n")
2584 {
2585   return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
2586 }
2587
2588 DEFUN (no_ipv6_address,
2589        no_ipv6_address_cmd,
2590        "no ipv6 address X:X::X:X/M",
2591        NO_STR
2592        "Interface IPv6 config commands\n"
2593        "Set the IP address of an interface\n"
2594        "IPv6 address (e.g. 3ffe:506::1/48)\n")
2595 {
2596   return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
2597 }
2598 #endif /* HAVE_IPV6 */
2599
2600 static int
2601 link_params_config_write (struct vty *vty, struct interface *ifp)
2602 {
2603   int i;
2604   
2605   if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2606     return -1;
2607   
2608   struct if_link_params *iflp = ifp->link_params;
2609
2610   vty_out (vty, " link-params%s", VTY_NEWLINE);
2611   vty_out(vty, "  enable%s", VTY_NEWLINE);
2612   if (IS_PARAM_SET(iflp, LP_TE))
2613     vty_out(vty, "  metric %u%s",iflp->te_metric, VTY_NEWLINE);
2614   if (IS_PARAM_SET(iflp, LP_MAX_BW))
2615     vty_out(vty, "  max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
2616   if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2617     vty_out(vty, "  max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
2618   if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
2619     {
2620       for (i = 0; i < 8; i++)
2621         vty_out(vty, "  unrsv-bw %d %g%s",
2622             i, iflp->unrsv_bw[i], VTY_NEWLINE);
2623     }
2624   if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2625     vty_out(vty, "  admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE);
2626   if (IS_PARAM_SET(iflp, LP_DELAY))
2627     {
2628       vty_out(vty, "  delay %u", iflp->av_delay);
2629       if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2630         {
2631           vty_out(vty, " min %u", iflp->min_delay);
2632           vty_out(vty, " max %u", iflp->max_delay);
2633         }
2634       vty_out(vty, "%s", VTY_NEWLINE);
2635     }
2636   if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2637     vty_out(vty, "  delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
2638   if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2639     vty_out(vty, "  packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
2640   if (IS_PARAM_SET(iflp, LP_AVA_BW))
2641     vty_out(vty, "  ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
2642   if (IS_PARAM_SET(iflp, LP_RES_BW))
2643     vty_out(vty, "  res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
2644   if (IS_PARAM_SET(iflp, LP_USE_BW))
2645     vty_out(vty, "  use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
2646   if (IS_PARAM_SET(iflp, LP_RMT_AS))
2647     vty_out(vty, "  neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
2648         iflp->rmt_as, VTY_NEWLINE);
2649   vty_out(vty, "  exit-link-params%s", VTY_NEWLINE);
2650   return 0;
2651 }
2652
2653 static int
2654 if_config_write (struct vty *vty)
2655 {
2656   struct listnode *node;
2657   struct interface *ifp;
2658   vrf_iter_t iter;
2659
2660   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2661   for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
2662     {
2663       struct zebra_if *if_data;
2664       struct listnode *addrnode;
2665       struct connected *ifc;
2666       struct prefix *p;
2667
2668       if_data = ifp->info;
2669
2670       if (ifp->vrf_id == VRF_DEFAULT)
2671         vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2672       else
2673         vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
2674                  VTY_NEWLINE);
2675
2676       if (if_data)
2677         {
2678           if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2679             vty_out (vty, " shutdown%s", VTY_NEWLINE);
2680         }
2681
2682       if (ifp->desc)
2683         vty_out (vty, " description %s%s", ifp->desc,
2684                  VTY_NEWLINE);
2685
2686       /* Assign bandwidth here to avoid unnecessary interface flap
2687          while processing config script */
2688       if (ifp->bandwidth != 0)
2689         vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
2690       
2691       switch (if_data->linkdetect)
2692         {
2693           case IF_LINKDETECT_ON:
2694             vty_out(vty, " link-detect%s", VTY_NEWLINE);
2695             break;
2696           case IF_LINKDETECT_OFF:
2697             vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2698             break;
2699           default: break;
2700         }
2701       
2702       for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
2703           {
2704             if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2705               {
2706                 char buf[INET6_ADDRSTRLEN];
2707                 p = ifc->address;
2708                 vty_out (vty, " ip%s address %s",
2709                          p->family == AF_INET ? "" : "v6",
2710                          prefix2str (p, buf, sizeof(buf)));
2711
2712                 if (ifc->label)
2713                   vty_out (vty, " label %s", ifc->label);
2714
2715                 vty_out (vty, "%s", VTY_NEWLINE);
2716               }
2717           }
2718
2719       if (if_data)
2720         {
2721           if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2722             vty_out (vty, " %smulticast%s",
2723                      if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2724                      VTY_NEWLINE);
2725         }
2726
2727 #if defined (HAVE_RTADV)
2728       rtadv_config_write (vty, ifp);
2729 #endif /* HAVE_RTADV */
2730
2731 #ifdef HAVE_IRDP
2732       irdp_config_write (vty, ifp);
2733 #endif /* IRDP */
2734
2735       link_params_config_write (vty, ifp);
2736
2737       vty_out (vty, "!%s", VTY_NEWLINE);
2738     }
2739   return 0;
2740 }
2741
2742
2743 /* Allocate and initialize interface vector. */
2744 void
2745 zebra_if_init (void)
2746 {
2747   /* Initialize interface and new hook. */
2748   if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2749   if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2750   
2751   /* Install configuration write function. */
2752   install_node (&interface_node, if_config_write);
2753   
2754   install_node (&zebra_if_defaults_node, config_write_zebra_if_defaults);
2755
2756   install_node (&link_params_node, NULL);
2757   
2758   install_element (VIEW_NODE, &show_interface_cmd);
2759   install_element (VIEW_NODE, &show_interface_vrf_cmd);
2760   install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
2761   install_element (VIEW_NODE, &show_interface_name_cmd);
2762   install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2763   install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
2764   install_element (CONFIG_NODE, &zebra_interface_cmd);
2765   install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
2766   install_element (CONFIG_NODE, &no_interface_cmd);
2767   install_element (CONFIG_NODE, &no_interface_vrf_cmd);
2768   install_element (CONFIG_NODE, &default_linkdetect_cmd);
2769   install_default (INTERFACE_NODE);
2770   install_element (INTERFACE_NODE, &interface_desc_cmd);
2771   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2772   install_element (INTERFACE_NODE, &multicast_cmd);
2773   install_element (INTERFACE_NODE, &no_multicast_cmd);
2774   install_element (INTERFACE_NODE, &linkdetect_cmd);
2775   install_element (INTERFACE_NODE, &no_linkdetect_cmd);
2776   install_element (INTERFACE_NODE, &shutdown_if_cmd);
2777   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2778   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2779   install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
2780   install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
2781   install_element (INTERFACE_NODE, &ip_address_cmd);
2782   install_element (INTERFACE_NODE, &no_ip_address_cmd);
2783 #ifdef HAVE_IPV6
2784   install_element (INTERFACE_NODE, &ipv6_address_cmd);
2785   install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
2786 #endif /* HAVE_IPV6 */
2787 #ifdef HAVE_NETLINK
2788   install_element (INTERFACE_NODE, &ip_address_label_cmd);
2789   install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
2790 #endif /* HAVE_NETLINK */
2791   install_element(INTERFACE_NODE, &link_params_cmd);
2792   install_default(LINK_PARAMS_NODE);
2793   install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2794   install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2795   install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
2796   install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2797   install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2798   install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2799   install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
2800   install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
2801   install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2802   install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2803   install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
2804   install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
2805   install_element(LINK_PARAMS_NODE, &link_params_delay_mm_cmd);
2806   install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
2807   install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
2808   install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
2809   install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
2810   install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
2811   install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
2812   install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
2813   install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
2814   install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
2815   install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
2816   install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
2817 }