]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - lib/if.c
New upstream release and new maintainer
[quagga-debian.git] / lib / if.c
1
2 /* 
3  * Interface functions.
4  * Copyright (C) 1997, 98 Kunihiro Ishiguro
5  *
6  * This file is part of GNU Zebra.
7  * 
8  * GNU Zebra is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2, or (at your
11  * option) any later version.
12  *
13  * GNU Zebra is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with GNU Zebra; see the file COPYING.  If not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <zebra.h>
25
26 #include "linklist.h"
27 #include "vector.h"
28 #include "vty.h"
29 #include "command.h"
30 #include "vrf.h"
31 #include "if.h"
32 #include "sockunion.h"
33 #include "prefix.h"
34 #include "memory.h"
35 #include "table.h"
36 #include "buffer.h"
37 #include "str.h"
38 #include "log.h"
39
40 /* List of interfaces in only the default VRF */
41 struct list *iflist;
42
43 /* One for each program.  This structure is needed to store hooks. */
44 struct if_master
45 {
46   int (*if_new_hook) (struct interface *);
47   int (*if_delete_hook) (struct interface *);
48 } if_master = {0,};
49
50 /* Compare interface names, returning an integer greater than, equal to, or
51  * less than 0, (following the strcmp convention), according to the
52  * relationship between ifp1 and ifp2.  Interface names consist of an
53  * alphabetic prefix and a numeric suffix.  The primary sort key is
54  * lexicographic by name, and then numeric by number.  No number sorts
55  * before all numbers.  Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
56  * devpty0, de0 < del0
57  */         
58 int
59 if_cmp_func (struct interface *ifp1, struct interface *ifp2)
60 {
61   unsigned int l1, l2;
62   long int x1, x2;
63   char *p1, *p2;
64   int res;
65
66   p1 = ifp1->name;
67   p2 = ifp2->name;
68
69   while (*p1 && *p2) {
70     /* look up to any number */
71     l1 = strcspn(p1, "0123456789");
72     l2 = strcspn(p2, "0123456789");
73
74     /* name lengths are different -> compare names */
75     if (l1 != l2)
76       return (strcmp(p1, p2));
77
78     /* Note that this relies on all numbers being less than all letters, so
79      * that de0 < del0.
80      */
81     res = strncmp(p1, p2, l1);
82
83     /* names are different -> compare them */
84     if (res)
85       return res;
86
87     /* with identical name part, go to numeric part */
88     p1 += l1;
89     p2 += l1;
90
91     if (!*p1) 
92       return -1;
93     if (!*p2) 
94       return 1;
95
96     x1 = strtol(p1, &p1, 10);
97     x2 = strtol(p2, &p2, 10);
98
99     /* let's compare numbers now */
100     if (x1 < x2)
101       return -1;
102     if (x1 > x2)
103       return 1;
104
105     /* numbers were equal, lets do it again..
106     (it happens with name like "eth123.456:789") */
107   }
108   if (*p1)
109     return 1;
110   if (*p2)
111     return -1;
112   return 0;
113 }
114
115 /* Create new interface structure. */
116 struct interface *
117 if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
118 {
119   struct interface *ifp;
120   struct list *intf_list = vrf_iflist_get (vrf_id);
121
122   ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
123   ifp->ifindex = IFINDEX_INTERNAL;
124   
125   assert (name);
126   assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
127   strncpy (ifp->name, name, namelen);
128   ifp->name[namelen] = '\0';
129   ifp->vrf_id = vrf_id;
130   if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
131     listnode_add_sort (intf_list, ifp);
132   else
133     zlog_err("if_create(%s): corruption detected -- interface with this "
134              "name exists already in VRF %u!", ifp->name, vrf_id);
135   ifp->connected = list_new ();
136   ifp->connected->del = (void (*) (void *)) connected_free;
137
138   if (if_master.if_new_hook)
139     (*if_master.if_new_hook) (ifp);
140
141   return ifp;
142 }
143
144 struct interface *
145 if_create (const char *name, int namelen)
146 {
147   return if_create_vrf (name, namelen, VRF_DEFAULT);
148 }
149
150 /* Delete interface structure. */
151 void
152 if_delete_retain (struct interface *ifp)
153 {
154   if (if_master.if_delete_hook)
155     (*if_master.if_delete_hook) (ifp);
156
157   /* Free connected address list */
158   list_delete_all_node (ifp->connected);
159 }
160
161 /* Delete and free interface structure. */
162 void
163 if_delete (struct interface *ifp)
164 {
165   listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
166
167   if_delete_retain(ifp);
168
169   list_free (ifp->connected);
170
171   if_link_params_free (ifp);
172   
173   XFREE (MTYPE_IF, ifp);
174 }
175
176 /* Add hook to interface master. */
177 void
178 if_add_hook (int type, int (*func)(struct interface *ifp))
179 {
180   switch (type) {
181   case IF_NEW_HOOK:
182     if_master.if_new_hook = func;
183     break;
184   case IF_DELETE_HOOK:
185     if_master.if_delete_hook = func;
186     break;
187   default:
188     break;
189   }
190 }
191
192 /* Interface existance check by index. */
193 struct interface *
194 if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
195 {
196   struct listnode *node;
197   struct interface *ifp;
198
199   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
200     {
201       if (ifp->ifindex == ifindex)
202         return ifp;
203     }
204   return NULL;
205 }
206
207 struct interface *
208 if_lookup_by_index (ifindex_t ifindex)
209 {
210   return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
211 }
212
213 const char *
214 ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
215 {
216   struct interface *ifp;
217
218   return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
219          ifp->name : "unknown";
220 }
221
222 const char *
223 ifindex2ifname (ifindex_t ifindex)
224 {
225   return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
226 }
227
228 ifindex_t
229 ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
230 {
231   struct interface *ifp;
232
233   return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
234                                                    : IFINDEX_INTERNAL;
235 }
236
237 ifindex_t
238 ifname2ifindex (const char *name)
239 {
240   return ifname2ifindex_vrf (name, VRF_DEFAULT);
241 }
242
243 /* Interface existance check by interface name. */
244 struct interface *
245 if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
246 {
247   struct listnode *node;
248   struct interface *ifp;
249   
250   if (name)
251     for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
252       {
253         if (strcmp(name, ifp->name) == 0)
254           return ifp;
255       }
256   return NULL;
257 }
258
259 struct interface *
260 if_lookup_by_name (const char *name)
261 {
262   return if_lookup_by_name_vrf (name, VRF_DEFAULT);
263 }
264
265 struct interface *
266 if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
267 {
268   struct listnode *node;
269   struct interface *ifp;
270
271   if (namelen > INTERFACE_NAMSIZ)
272     return NULL;
273
274   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
275     {
276       if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
277         return ifp;
278     }
279   return NULL;
280 }
281
282 struct interface *
283 if_lookup_by_name_len(const char *name, size_t namelen)
284 {
285   return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
286 }
287
288 /* Lookup interface by IPv4 address. */
289 struct interface *
290 if_lookup_exact_address_vrf (struct in_addr src, vrf_id_t vrf_id)
291 {
292   struct listnode *node;
293   struct listnode *cnode;
294   struct interface *ifp;
295   struct prefix *p;
296   struct connected *c;
297
298   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
299     {
300       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
301         {
302           p = c->address;
303
304           if (p && p->family == AF_INET)
305             {
306               if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
307                 return ifp;
308             }         
309         }
310     }
311   return NULL;
312 }
313
314 struct interface *
315 if_lookup_exact_address (struct in_addr src)
316 {
317   return if_lookup_exact_address_vrf (src, VRF_DEFAULT);
318 }
319
320 /* Lookup interface by IPv4 address. */
321 struct interface *
322 if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
323 {
324   struct listnode *node;
325   struct prefix addr;
326   int bestlen = 0;
327   struct listnode *cnode;
328   struct interface *ifp;
329   struct connected *c;
330   struct interface *match;
331
332   addr.family = AF_INET;
333   addr.u.prefix4 = src;
334   addr.prefixlen = IPV4_MAX_BITLEN;
335
336   match = NULL;
337
338   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
339     {
340       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
341         {
342           if (c->address && (c->address->family == AF_INET) &&
343               prefix_match(CONNECTED_PREFIX(c), &addr) &&
344               (c->address->prefixlen > bestlen))
345             {
346               bestlen = c->address->prefixlen;
347               match = ifp;
348             }
349         }
350     }
351   return match;
352 }
353
354 struct interface *
355 if_lookup_address (struct in_addr src)
356 {
357   return if_lookup_address_vrf (src, VRF_DEFAULT);
358 }
359
360 /* Lookup interface by prefix */
361 struct interface *
362 if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
363 {
364   struct listnode *node;
365   struct listnode *cnode;
366   struct interface *ifp;
367   struct connected *c;
368
369   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
370     {
371       for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
372         {
373           if (prefix_cmp(c->address, prefix) == 0)
374             {
375               return ifp;
376             }
377         }
378     }
379   return NULL;
380 }
381
382 struct interface *
383 if_lookup_prefix (struct prefix *prefix)
384 {
385   return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
386 }
387
388 /* Get interface by name if given name interface doesn't exist create
389    one. */
390 struct interface *
391 if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
392 {
393   struct interface *ifp;
394
395   return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
396          if_create_vrf (name, strlen(name), vrf_id);
397 }
398
399 struct interface *
400 if_get_by_name (const char *name)
401 {
402   return if_get_by_name_vrf (name, VRF_DEFAULT);
403 }
404
405 struct interface *
406 if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
407 {
408   struct interface *ifp;
409
410   return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \
411          ifp : if_create_vrf (name, namelen, vrf_id);
412 }
413
414 struct interface *
415 if_get_by_name_len (const char *name, size_t namelen)
416 {
417   return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT);
418 }
419
420 /* Does interface up ? */
421 int
422 if_is_up (struct interface *ifp)
423 {
424   return ifp->flags & IFF_UP;
425 }
426
427 /* Is interface running? */
428 int
429 if_is_running (struct interface *ifp)
430 {
431   return ifp->flags & IFF_RUNNING;
432 }
433
434 /* Is the interface operative, eg. either UP & RUNNING
435    or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
436 int
437 if_is_operative (struct interface *ifp)
438 {
439   return ((ifp->flags & IFF_UP) &&
440           (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
441 }
442
443 /* Is this loopback interface ? */
444 int
445 if_is_loopback (struct interface *ifp)
446 {
447   /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
448    * but Y on platform N?
449    */
450   return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
451 }
452
453 /* Does this interface support broadcast ? */
454 int
455 if_is_broadcast (struct interface *ifp)
456 {
457   return ifp->flags & IFF_BROADCAST;
458 }
459
460 /* Does this interface support broadcast ? */
461 int
462 if_is_pointopoint (struct interface *ifp)
463 {
464   return ifp->flags & IFF_POINTOPOINT;
465 }
466
467 /* Does this interface support multicast ? */
468 int
469 if_is_multicast (struct interface *ifp)
470 {
471   return ifp->flags & IFF_MULTICAST;
472 }
473
474 /* Printout flag information into log */
475 const char *
476 if_flag_dump (unsigned long flag)
477 {
478   int separator = 0;
479   static char logbuf[BUFSIZ];
480
481 #define IFF_OUT_LOG(X,STR) \
482   if (flag & (X)) \
483     { \
484       if (separator) \
485         strlcat (logbuf, ",", BUFSIZ); \
486       else \
487         separator = 1; \
488       strlcat (logbuf, STR, BUFSIZ); \
489     }
490
491   strlcpy (logbuf, "<", BUFSIZ);
492   IFF_OUT_LOG (IFF_UP, "UP");
493   IFF_OUT_LOG (IFF_BROADCAST, "BROADCAST");
494   IFF_OUT_LOG (IFF_DEBUG, "DEBUG");
495   IFF_OUT_LOG (IFF_LOOPBACK, "LOOPBACK");
496   IFF_OUT_LOG (IFF_POINTOPOINT, "POINTOPOINT");
497   IFF_OUT_LOG (IFF_NOTRAILERS, "NOTRAILERS");
498   IFF_OUT_LOG (IFF_RUNNING, "RUNNING");
499   IFF_OUT_LOG (IFF_NOARP, "NOARP");
500   IFF_OUT_LOG (IFF_PROMISC, "PROMISC");
501   IFF_OUT_LOG (IFF_ALLMULTI, "ALLMULTI");
502   IFF_OUT_LOG (IFF_OACTIVE, "OACTIVE");
503   IFF_OUT_LOG (IFF_SIMPLEX, "SIMPLEX");
504   IFF_OUT_LOG (IFF_LINK0, "LINK0");
505   IFF_OUT_LOG (IFF_LINK1, "LINK1");
506   IFF_OUT_LOG (IFF_LINK2, "LINK2");
507   IFF_OUT_LOG (IFF_MULTICAST, "MULTICAST");
508   IFF_OUT_LOG (IFF_NOXMIT, "NOXMIT");
509   IFF_OUT_LOG (IFF_NORTEXCH, "NORTEXCH");
510   IFF_OUT_LOG (IFF_VIRTUAL, "VIRTUAL");
511   IFF_OUT_LOG (IFF_IPV4, "IPv4");
512   IFF_OUT_LOG (IFF_IPV6, "IPv6");
513
514   strlcat (logbuf, ">", BUFSIZ);
515
516   return logbuf;
517 #undef IFF_OUT_LOG
518 }
519
520 /* For debugging */
521 static void
522 if_dump (const struct interface *ifp)
523 {
524   struct listnode *node;
525   struct connected *c __attribute__((unused));
526
527   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
528     zlog_info ("Interface %s vrf %u index %d metric %d mtu %d "
529 #ifdef HAVE_IPV6
530                "mtu6 %d "
531 #endif /* HAVE_IPV6 */
532                "%s",
533                ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, ifp->mtu,
534 #ifdef HAVE_IPV6
535                ifp->mtu6,
536 #endif /* HAVE_IPV6 */
537                if_flag_dump (ifp->flags));
538 }
539
540 /* Interface printing for all interface. */
541 void
542 if_dump_all (void)
543 {
544   struct list *intf_list;
545   struct listnode *node;
546   void *p;
547   vrf_iter_t iter;
548
549   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
550     if ((intf_list = vrf_iter2iflist (iter)) != NULL)
551       for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
552         if_dump (p);
553 }
554
555 DEFUN (interface_desc, 
556        interface_desc_cmd,
557        "description .LINE",
558        "Interface specific description\n"
559        "Characters describing this interface\n")
560 {
561   struct interface *ifp;
562
563   if (argc == 0)
564     return CMD_SUCCESS;
565
566   ifp = vty->index;
567   if (ifp->desc)
568     XFREE (MTYPE_TMP, ifp->desc);
569   ifp->desc = argv_concat(argv, argc, 0);
570
571   return CMD_SUCCESS;
572 }
573
574 DEFUN (no_interface_desc, 
575        no_interface_desc_cmd,
576        "no description",
577        NO_STR
578        "Interface specific description\n")
579 {
580   struct interface *ifp;
581
582   ifp = vty->index;
583   if (ifp->desc)
584     XFREE (MTYPE_TMP, ifp->desc);
585   ifp->desc = NULL;
586
587   return CMD_SUCCESS;
588 }
589
590 #ifdef SUNOS_5
591 /* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created
592  * a seperate struct interface for each logical interface, so config
593  * file may be full of 'interface fooX:Y'. Solaris however does not
594  * expose logical interfaces via PF_ROUTE, so trying to track logical
595  * interfaces can be fruitless, for that reason Quagga only tracks
596  * the primary IP interface.
597  *
598  * We try accomodate SUNWzebra by:
599  * - looking up the interface name, to see whether it exists, if so
600  *   its useable
601  *   - for protocol daemons, this could only because zebra told us of
602  *     the interface
603  *   - for zebra, only because it learnt from kernel
604  * - if not:
605  *   - search the name to see if it contains a sub-ipif / logical interface
606  *     seperator, the ':' char. If it does:
607  *     - text up to that char must be the primary name - get that name.
608  *     if not:
609  *     - no idea, just get the name in its entirety.
610  */
611 static struct interface *
612 if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
613 {
614   struct interface *ifp;
615   size_t seppos = 0;
616
617   if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
618     return ifp;
619   
620   /* hunt the primary interface name... */
621   while (seppos < nlen && name[seppos] != ':')
622     seppos++;
623   
624   /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
625   if (seppos < nlen)
626     return if_get_by_name_len_vrf (name, seppos, vrf_id);
627   else
628     return if_get_by_name_len_vrf (name, nlen, vrf_id);
629 }
630 #endif /* SUNOS_5 */
631
632 DEFUN (interface,
633        interface_cmd,
634        "interface IFNAME",
635        "Select an interface to configure\n"
636        "Interface's name\n")
637 {
638   struct interface *ifp;
639   size_t sl;
640   vrf_id_t vrf_id = VRF_DEFAULT;
641
642   if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
643     {
644       vty_out (vty, "%% Interface name %s is invalid: length exceeds "
645                     "%d characters%s",
646                argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
647       return CMD_WARNING;
648     }
649
650   if (argc > 1)
651     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
652
653 #ifdef SUNOS_5
654   ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
655 #else
656   ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id);
657 #endif /* SUNOS_5 */
658
659   vty->index = ifp;
660   vty->node = INTERFACE_NODE;
661
662   return CMD_SUCCESS;
663 }
664
665 ALIAS (interface,
666        interface_vrf_cmd,
667        "interface IFNAME " VRF_CMD_STR,
668        "Select an interface to configure\n"
669        "Interface's name\n"
670        VRF_CMD_HELP_STR)
671
672 DEFUN_NOSH (no_interface,
673            no_interface_cmd,
674            "no interface IFNAME",
675            NO_STR
676            "Delete a pseudo interface's configuration\n"
677            "Interface's name\n")
678 {
679   // deleting interface
680   struct interface *ifp;
681   vrf_id_t vrf_id = VRF_DEFAULT;
682
683   if (argc > 1)
684     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
685
686   ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
687
688   if (ifp == NULL)
689     {
690       vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
691       return CMD_WARNING;
692     }
693
694   if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) 
695     {
696       vty_out (vty, "%% Only inactive interfaces can be deleted%s",
697               VTY_NEWLINE);
698       return CMD_WARNING;
699     }
700
701   if_delete(ifp);
702
703   return CMD_SUCCESS;
704 }
705
706 ALIAS (no_interface,
707        no_interface_vrf_cmd,
708        "no interface IFNAME " VRF_CMD_STR,
709        NO_STR
710        "Delete a pseudo interface's configuration\n"
711        "Interface's name\n"
712        VRF_CMD_HELP_STR)
713
714 /* For debug purpose. */
715 DEFUN (show_address,
716        show_address_cmd,
717        "show address",
718        SHOW_STR
719        "address\n")
720 {
721   struct listnode *node;
722   struct listnode *node2;
723   struct interface *ifp;
724   struct connected *ifc;
725   struct prefix *p;
726   vrf_id_t vrf_id = VRF_DEFAULT;
727
728   if (argc > 0)
729     VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
730
731   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
732     {
733       for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
734         {
735           p = ifc->address;
736
737           if (p->family == AF_INET)
738             vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
739                      VTY_NEWLINE);
740         }
741     }
742   return CMD_SUCCESS;
743 }
744
745 ALIAS (show_address,
746        show_address_vrf_cmd,
747        "show address " VRF_CMD_STR,
748        SHOW_STR
749        "address\n"
750        VRF_CMD_HELP_STR)
751
752 DEFUN (show_address_vrf_all,
753        show_address_vrf_all_cmd,
754        "show address " VRF_ALL_CMD_STR,
755        SHOW_STR
756        "address\n"
757        VRF_ALL_CMD_HELP_STR)
758 {
759   struct list *intf_list;
760   struct listnode *node;
761   struct listnode *node2;
762   struct interface *ifp;
763   struct connected *ifc;
764   struct prefix *p;
765   vrf_iter_t iter;
766
767   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
768     {
769       intf_list = vrf_iter2iflist (iter);
770       if (!intf_list || !listcount (intf_list))
771         continue;
772
773       vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
774                VTY_NEWLINE, VTY_NEWLINE);
775
776       for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
777         {
778           for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
779             {
780               p = ifc->address;
781
782               if (p->family == AF_INET)
783                 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
784                          VTY_NEWLINE);
785             }
786         }
787     }
788   return CMD_SUCCESS;
789 }
790
791 /* Allocate connected structure. */
792 struct connected *
793 connected_new (void)
794 {
795   return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
796 }
797
798 /* Free connected structure. */
799 void
800 connected_free (struct connected *connected)
801 {
802   if (connected->address)
803     prefix_free (connected->address);
804
805   if (connected->destination)
806     prefix_free (connected->destination);
807
808   if (connected->label)
809     XFREE (MTYPE_CONNECTED_LABEL, connected->label);
810
811   XFREE (MTYPE_CONNECTED, connected);
812 }
813
814 /* Print if_addr structure. */
815 static void __attribute__ ((unused))
816 connected_log (struct connected *connected, char *str)
817 {
818   struct prefix *p;
819   struct interface *ifp;
820   char logbuf[BUFSIZ];
821   char buf[BUFSIZ];
822   
823   ifp = connected->ifp;
824   p = connected->address;
825
826   snprintf (logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ",
827             str, ifp->name, ifp->vrf_id, prefix_family_str (p),
828             inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
829             p->prefixlen);
830
831   p = connected->destination;
832   if (p)
833     {
834       strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
835                BUFSIZ - strlen(logbuf));
836     }
837   zlog (NULL, LOG_INFO, "%s", logbuf);
838 }
839
840 /* If two connected address has same prefix return 1. */
841 static int
842 connected_same_prefix (struct prefix *p1, struct prefix *p2)
843 {
844   if (p1->family == p2->family)
845     {
846       if (p1->family == AF_INET &&
847           IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
848         return 1;
849 #ifdef HAVE_IPV6
850       if (p1->family == AF_INET6 &&
851           IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
852         return 1;
853 #endif /* HAVE_IPV6 */
854     }
855   return 0;
856 }
857
858 struct connected *
859 connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
860 {
861   struct listnode *node;
862   struct listnode *next;
863   struct connected *ifc;
864
865   /* In case of same prefix come, replace it with new one. */
866   for (node = listhead (ifp->connected); node; node = next)
867     {
868       ifc = listgetdata (node);
869       next = node->next;
870
871       if (connected_same_prefix (ifc->address, p))
872         {
873           listnode_delete (ifp->connected, ifc);
874           return ifc;
875         }
876     }
877   return NULL;
878 }
879
880 /* Find the IPv4 address on our side that will be used when packets
881    are sent to dst. */
882 struct connected *
883 connected_lookup_address (struct interface *ifp, struct in_addr dst)
884 {
885   struct prefix addr;
886   struct listnode *cnode;
887   struct connected *c;
888   struct connected *match;
889
890   addr.family = AF_INET;
891   addr.u.prefix4 = dst;
892   addr.prefixlen = IPV4_MAX_BITLEN;
893
894   match = NULL;
895
896   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
897     {
898       if (c->address && (c->address->family == AF_INET) &&
899           prefix_match(CONNECTED_PREFIX(c), &addr) &&
900           (!match || (c->address->prefixlen > match->address->prefixlen)))
901         match = c;
902     }
903   return match;
904 }
905
906 struct connected *
907 connected_add_by_prefix (struct interface *ifp, struct prefix *p, 
908                          struct prefix *destination)
909 {
910   struct connected *ifc;
911
912   /* Allocate new connected address. */
913   ifc = connected_new ();
914   ifc->ifp = ifp;
915
916   /* Fetch interface address */
917   ifc->address = prefix_new();
918   memcpy (ifc->address, p, sizeof(struct prefix));
919
920   /* Fetch dest address */
921   if (destination)
922     {
923       ifc->destination = prefix_new();
924       memcpy (ifc->destination, destination, sizeof(struct prefix));
925     }
926
927   /* Add connected address to the interface. */
928   listnode_add (ifp->connected, ifc);
929   return ifc;
930 }
931
932 #ifndef HAVE_IF_NAMETOINDEX
933 ifindex_t
934 if_nametoindex (const char *name)
935 {
936   struct interface *ifp;
937
938   return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
939          ? ifp->ifindex : 0;
940 }
941 #endif
942
943 #ifndef HAVE_IF_INDEXTONAME
944 char *
945 if_indextoname (ifindex_t ifindex, char *name)
946 {
947   struct interface *ifp;
948
949   if (!(ifp = if_lookup_by_index(ifindex)))
950     return NULL;
951   strncpy (name, ifp->name, IFNAMSIZ);
952   return ifp->name;
953 }
954 #endif
955
956 #if 0 /* this route_table of struct connected's is unused
957        * however, it would be good to use a route_table rather than
958        * a list..
959        */
960 /* Interface looking up by interface's address. */
961 /* Interface's IPv4 address reverse lookup table. */
962 struct route_table *ifaddr_ipv4_table;
963 /* struct route_table *ifaddr_ipv6_table; */
964
965 static void
966 ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
967 {
968   struct route_node *rn;
969   struct prefix_ipv4 p;
970
971   p.family = AF_INET;
972   p.prefixlen = IPV4_MAX_PREFIXLEN;
973   p.prefix = *ifaddr;
974
975   rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
976   if (rn)
977     {
978       route_unlock_node (rn);
979       zlog_info ("ifaddr_ipv4_add(): address %s is already added",
980                  inet_ntoa (*ifaddr));
981       return;
982     }
983   rn->info = ifp;
984 }
985
986 static void
987 ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
988 {
989   struct route_node *rn;
990   struct prefix_ipv4 p;
991
992   p.family = AF_INET;
993   p.prefixlen = IPV4_MAX_PREFIXLEN;
994   p.prefix = *ifaddr;
995
996   rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
997   if (! rn)
998     {
999       zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
1000                  inet_ntoa (*ifaddr));
1001       return;
1002     }
1003   rn->info = NULL;
1004   route_unlock_node (rn);
1005   route_unlock_node (rn);
1006 }
1007
1008 /* Lookup interface by interface's IP address or interface index. */
1009 static struct interface *
1010 ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
1011 {
1012   struct prefix_ipv4 p;
1013   struct route_node *rn;
1014   struct interface *ifp;
1015
1016   if (addr)
1017     {
1018       p.family = AF_INET;
1019       p.prefixlen = IPV4_MAX_PREFIXLEN;
1020       p.prefix = *addr;
1021
1022       rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1023       if (! rn)
1024         return NULL;
1025       
1026       ifp = rn->info;
1027       route_unlock_node (rn);
1028       return ifp;
1029     }
1030   else
1031     return if_lookup_by_index(ifindex);
1032 }
1033 #endif /* ifaddr_ipv4_table */
1034
1035 /* Initialize interface list. */
1036 void
1037 if_init (vrf_id_t vrf_id, struct list **intf_list)
1038 {
1039   *intf_list = list_new ();
1040 #if 0
1041   ifaddr_ipv4_table = route_table_init ();
1042 #endif /* ifaddr_ipv4_table */
1043
1044   (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
1045
1046   if (vrf_id == VRF_DEFAULT)
1047     iflist = *intf_list;
1048 }
1049
1050 void
1051 if_terminate (vrf_id_t vrf_id, struct list **intf_list)
1052 {
1053   for (;;)
1054     {
1055       struct interface *ifp;
1056
1057       ifp = listnode_head (*intf_list);
1058       if (ifp == NULL)
1059         break;
1060
1061       if_delete (ifp);
1062     }
1063
1064   list_delete (*intf_list);
1065   *intf_list = NULL;
1066
1067   if (vrf_id == VRF_DEFAULT)
1068     iflist = NULL;
1069 }
1070
1071 const char *
1072 if_link_type_str (enum zebra_link_type llt)
1073 {
1074   switch (llt)
1075     {
1076 #define llts(T,S) case (T): return (S)
1077       llts(ZEBRA_LLT_UNKNOWN,               "Unknown");
1078       llts(ZEBRA_LLT_ETHER,                 "Ethernet");
1079       llts(ZEBRA_LLT_EETHER,                "Experimental Ethernet");
1080       llts(ZEBRA_LLT_AX25,                  "AX.25 Level 2");
1081       llts(ZEBRA_LLT_PRONET,                "PROnet token ring");
1082       llts(ZEBRA_LLT_IEEE802,               "IEEE 802.2 Ethernet/TR/TB");
1083       llts(ZEBRA_LLT_ARCNET,                "ARCnet");
1084       llts(ZEBRA_LLT_APPLETLK,              "AppleTalk");
1085       llts(ZEBRA_LLT_DLCI,                  "Frame Relay DLCI");
1086       llts(ZEBRA_LLT_ATM,                   "ATM");
1087       llts(ZEBRA_LLT_METRICOM,              "Metricom STRIP");
1088       llts(ZEBRA_LLT_IEEE1394,              "IEEE 1394 IPv4");
1089       llts(ZEBRA_LLT_EUI64,                 "EUI-64");
1090       llts(ZEBRA_LLT_INFINIBAND,            "InfiniBand");
1091       llts(ZEBRA_LLT_SLIP,                  "SLIP");
1092       llts(ZEBRA_LLT_CSLIP,                 "Compressed SLIP");
1093       llts(ZEBRA_LLT_SLIP6,                 "SLIPv6");
1094       llts(ZEBRA_LLT_CSLIP6,                "Compressed SLIPv6");
1095       llts(ZEBRA_LLT_ROSE,                  "ROSE packet radio");
1096       llts(ZEBRA_LLT_X25,                   "CCITT X.25");
1097       llts(ZEBRA_LLT_PPP,                   "PPP");
1098       llts(ZEBRA_LLT_CHDLC,                 "Cisco HDLC");
1099       llts(ZEBRA_LLT_RAWHDLC,               "Raw HDLC");
1100       llts(ZEBRA_LLT_LAPB,                  "LAPB");
1101       llts(ZEBRA_LLT_IPIP,                  "IPIP Tunnel");
1102       llts(ZEBRA_LLT_IPIP6,                 "IPIP6 Tunnel");
1103       llts(ZEBRA_LLT_FRAD,                  "FRAD");
1104       llts(ZEBRA_LLT_SKIP,                  "SKIP vif");
1105       llts(ZEBRA_LLT_LOOPBACK,              "Loopback");
1106       llts(ZEBRA_LLT_LOCALTLK,              "Localtalk");
1107       llts(ZEBRA_LLT_FDDI,                  "FDDI");
1108       llts(ZEBRA_LLT_SIT,                   "IPv6-in-IPv4 SIT");
1109       llts(ZEBRA_LLT_IPDDP,                 "IP-in-DDP tunnel");
1110       llts(ZEBRA_LLT_IPGRE,                 "GRE over IP");
1111       llts(ZEBRA_LLT_PIMREG,                "PIMSM registration");
1112       llts(ZEBRA_LLT_HIPPI,                 "HiPPI");
1113       llts(ZEBRA_LLT_IRDA,                  "IrDA");
1114       llts(ZEBRA_LLT_FCPP,                  "Fibre-Channel PtP");
1115       llts(ZEBRA_LLT_FCAL,                  "Fibre-Channel Arbitrated Loop");
1116       llts(ZEBRA_LLT_FCPL,                  "Fibre-Channel Public Loop");
1117       llts(ZEBRA_LLT_FCFABRIC,              "Fibre-Channel Fabric");
1118       llts(ZEBRA_LLT_IEEE802_TR,            "IEEE 802.2 Token Ring");
1119       llts(ZEBRA_LLT_IEEE80211,             "IEEE 802.11");
1120       llts(ZEBRA_LLT_IEEE80211_RADIOTAP,    "IEEE 802.11 Radiotap");
1121       llts(ZEBRA_LLT_IEEE802154,            "IEEE 802.15.4");
1122       llts(ZEBRA_LLT_IEEE802154_PHY,        "IEEE 802.15.4 Phy");
1123       default:
1124         zlog_warn ("Unknown value %d", llt);
1125         return "Unknown type!";
1126 #undef llts
1127     }
1128   return NULL;
1129 }
1130
1131 struct if_link_params *
1132 if_link_params_get (struct interface *ifp)
1133 {
1134   int i;
1135   
1136   if (ifp->link_params != NULL)
1137     return ifp->link_params;
1138   
1139   struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
1140                                       sizeof (struct if_link_params));
1141   if (iflp == NULL) return NULL;
1142   
1143   /* Set TE metric == standard metric */
1144   iflp->te_metric = ifp->metric;
1145
1146   /* Compute default bandwidth based on interface */
1147   int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH) 
1148                    * TE_KILO_BIT / TE_BYTE);
1149   
1150   /* Set Max, Reservable and Unreserved Bandwidth */
1151   iflp->max_bw = bw;
1152   iflp->max_rsv_bw = bw;
1153   for (i = 0; i < MAX_CLASS_TYPE; i++)
1154     iflp->unrsv_bw[i] = bw;
1155   
1156   /* Update Link parameters status */
1157   iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
1158
1159   /* Finally attach newly created Link Parameters */
1160   ifp->link_params = iflp;
1161
1162   return iflp;
1163 }
1164
1165 void
1166 if_link_params_free (struct interface *ifp)
1167 {
1168   if (ifp->link_params == NULL) return;
1169   XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
1170   ifp->link_params = NULL;
1171 }