4 * Copyright (C) 1997, 98 Kunihiro Ishiguro
6 * This file is part of GNU Zebra.
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.
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.
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.
32 #include "sockunion.h"
40 /* List of interfaces in only the default VRF */
43 /* One for each program. This structure is needed to store hooks. */
46 int (*if_new_hook) (struct interface *);
47 int (*if_delete_hook) (struct interface *);
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 <
59 if_cmp_func (struct interface *ifp1, struct interface *ifp2)
70 /* look up to any number */
71 l1 = strcspn(p1, "0123456789");
72 l2 = strcspn(p2, "0123456789");
74 /* name lengths are different -> compare names */
76 return (strcmp(p1, p2));
78 /* Note that this relies on all numbers being less than all letters, so
81 res = strncmp(p1, p2, l1);
83 /* names are different -> compare them */
87 /* with identical name part, go to numeric part */
96 x1 = strtol(p1, &p1, 10);
97 x2 = strtol(p2, &p2, 10);
99 /* let's compare numbers now */
105 /* numbers were equal, lets do it again..
106 (it happens with name like "eth123.456:789") */
115 /* Create new interface structure. */
117 if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
119 struct interface *ifp;
120 struct list *intf_list = vrf_iflist_get (vrf_id);
122 ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
123 ifp->ifindex = IFINDEX_INTERNAL;
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);
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;
138 if (if_master.if_new_hook)
139 (*if_master.if_new_hook) (ifp);
145 if_create (const char *name, int namelen)
147 return if_create_vrf (name, namelen, VRF_DEFAULT);
150 /* Delete interface structure. */
152 if_delete_retain (struct interface *ifp)
154 if (if_master.if_delete_hook)
155 (*if_master.if_delete_hook) (ifp);
157 /* Free connected address list */
158 list_delete_all_node (ifp->connected);
161 /* Delete and free interface structure. */
163 if_delete (struct interface *ifp)
165 listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
167 if_delete_retain(ifp);
169 list_free (ifp->connected);
171 if_link_params_free (ifp);
173 XFREE (MTYPE_IF, ifp);
176 /* Add hook to interface master. */
178 if_add_hook (int type, int (*func)(struct interface *ifp))
182 if_master.if_new_hook = func;
185 if_master.if_delete_hook = func;
192 /* Interface existance check by index. */
194 if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
196 struct listnode *node;
197 struct interface *ifp;
199 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
201 if (ifp->ifindex == ifindex)
208 if_lookup_by_index (ifindex_t ifindex)
210 return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
214 ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
216 struct interface *ifp;
218 return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
219 ifp->name : "unknown";
223 ifindex2ifname (ifindex_t ifindex)
225 return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
229 ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
231 struct interface *ifp;
233 return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
238 ifname2ifindex (const char *name)
240 return ifname2ifindex_vrf (name, VRF_DEFAULT);
243 /* Interface existance check by interface name. */
245 if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
247 struct listnode *node;
248 struct interface *ifp;
251 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
253 if (strcmp(name, ifp->name) == 0)
260 if_lookup_by_name (const char *name)
262 return if_lookup_by_name_vrf (name, VRF_DEFAULT);
266 if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
268 struct listnode *node;
269 struct interface *ifp;
271 if (namelen > INTERFACE_NAMSIZ)
274 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
276 if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
283 if_lookup_by_name_len(const char *name, size_t namelen)
285 return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
288 /* Lookup interface by IPv4 address. */
290 if_lookup_exact_address_vrf (struct in_addr src, vrf_id_t vrf_id)
292 struct listnode *node;
293 struct listnode *cnode;
294 struct interface *ifp;
298 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
300 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
304 if (p && p->family == AF_INET)
306 if (IPV4_ADDR_SAME (&p->u.prefix4, &src))
315 if_lookup_exact_address (struct in_addr src)
317 return if_lookup_exact_address_vrf (src, VRF_DEFAULT);
320 /* Lookup interface by IPv4 address. */
322 if_lookup_address_vrf (struct in_addr src, vrf_id_t vrf_id)
324 struct listnode *node;
327 struct listnode *cnode;
328 struct interface *ifp;
330 struct interface *match;
332 addr.family = AF_INET;
333 addr.u.prefix4 = src;
334 addr.prefixlen = IPV4_MAX_BITLEN;
338 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
340 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
342 if (c->address && (c->address->family == AF_INET) &&
343 prefix_match(CONNECTED_PREFIX(c), &addr) &&
344 (c->address->prefixlen > bestlen))
346 bestlen = c->address->prefixlen;
355 if_lookup_address (struct in_addr src)
357 return if_lookup_address_vrf (src, VRF_DEFAULT);
360 /* Lookup interface by prefix */
362 if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
364 struct listnode *node;
365 struct listnode *cnode;
366 struct interface *ifp;
369 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
371 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
373 if (prefix_cmp(c->address, prefix) == 0)
383 if_lookup_prefix (struct prefix *prefix)
385 return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
388 /* Get interface by name if given name interface doesn't exist create
391 if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
393 struct interface *ifp;
395 return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
396 if_create_vrf (name, strlen(name), vrf_id);
400 if_get_by_name (const char *name)
402 return if_get_by_name_vrf (name, VRF_DEFAULT);
406 if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
408 struct interface *ifp;
410 return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \
411 ifp : if_create_vrf (name, namelen, vrf_id);
415 if_get_by_name_len (const char *name, size_t namelen)
417 return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT);
420 /* Does interface up ? */
422 if_is_up (struct interface *ifp)
424 return ifp->flags & IFF_UP;
427 /* Is interface running? */
429 if_is_running (struct interface *ifp)
431 return ifp->flags & IFF_RUNNING;
434 /* Is the interface operative, eg. either UP & RUNNING
435 or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
437 if_is_operative (struct interface *ifp)
439 return ((ifp->flags & IFF_UP) &&
440 (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
443 /* Is this loopback interface ? */
445 if_is_loopback (struct interface *ifp)
447 /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
448 * but Y on platform N?
450 return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
453 /* Does this interface support broadcast ? */
455 if_is_broadcast (struct interface *ifp)
457 return ifp->flags & IFF_BROADCAST;
460 /* Does this interface support broadcast ? */
462 if_is_pointopoint (struct interface *ifp)
464 return ifp->flags & IFF_POINTOPOINT;
467 /* Does this interface support multicast ? */
469 if_is_multicast (struct interface *ifp)
471 return ifp->flags & IFF_MULTICAST;
474 /* Printout flag information into log */
476 if_flag_dump (unsigned long flag)
479 static char logbuf[BUFSIZ];
481 #define IFF_OUT_LOG(X,STR) \
485 strlcat (logbuf, ",", BUFSIZ); \
488 strlcat (logbuf, STR, BUFSIZ); \
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");
514 strlcat (logbuf, ">", BUFSIZ);
522 if_dump (const struct interface *ifp)
524 struct listnode *node;
525 struct connected *c __attribute__((unused));
527 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
528 zlog_info ("Interface %s vrf %u index %d metric %d mtu %d "
531 #endif /* HAVE_IPV6 */
533 ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, ifp->mtu,
536 #endif /* HAVE_IPV6 */
537 if_flag_dump (ifp->flags));
540 /* Interface printing for all interface. */
544 struct list *intf_list;
545 struct listnode *node;
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))
555 DEFUN (interface_desc,
558 "Interface specific description\n"
559 "Characters describing this interface\n")
561 struct interface *ifp;
568 XFREE (MTYPE_TMP, ifp->desc);
569 ifp->desc = argv_concat(argv, argc, 0);
574 DEFUN (no_interface_desc,
575 no_interface_desc_cmd,
578 "Interface specific description\n")
580 struct interface *ifp;
584 XFREE (MTYPE_TMP, ifp->desc);
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.
598 * We try accomodate SUNWzebra by:
599 * - looking up the interface name, to see whether it exists, if so
601 * - for protocol daemons, this could only because zebra told us of
603 * - for zebra, only because it learnt from kernel
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.
609 * - no idea, just get the name in its entirety.
611 static struct interface *
612 if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
614 struct interface *ifp;
617 if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
620 /* hunt the primary interface name... */
621 while (seppos < nlen && name[seppos] != ':')
624 /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
626 return if_get_by_name_len_vrf (name, seppos, vrf_id);
628 return if_get_by_name_len_vrf (name, nlen, vrf_id);
635 "Select an interface to configure\n"
636 "Interface's name\n")
638 struct interface *ifp;
640 vrf_id_t vrf_id = VRF_DEFAULT;
642 if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
644 vty_out (vty, "%% Interface name %s is invalid: length exceeds "
646 argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
651 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
654 ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
656 ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id);
660 vty->node = INTERFACE_NODE;
667 "interface IFNAME " VRF_CMD_STR,
668 "Select an interface to configure\n"
672 DEFUN_NOSH (no_interface,
674 "no interface IFNAME",
676 "Delete a pseudo interface's configuration\n"
677 "Interface's name\n")
679 // deleting interface
680 struct interface *ifp;
681 vrf_id_t vrf_id = VRF_DEFAULT;
684 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
686 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
690 vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
694 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
696 vty_out (vty, "%% Only inactive interfaces can be deleted%s",
707 no_interface_vrf_cmd,
708 "no interface IFNAME " VRF_CMD_STR,
710 "Delete a pseudo interface's configuration\n"
714 /* For debug purpose. */
721 struct listnode *node;
722 struct listnode *node2;
723 struct interface *ifp;
724 struct connected *ifc;
726 vrf_id_t vrf_id = VRF_DEFAULT;
729 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
731 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
733 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
737 if (p->family == AF_INET)
738 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
746 show_address_vrf_cmd,
747 "show address " VRF_CMD_STR,
752 DEFUN (show_address_vrf_all,
753 show_address_vrf_all_cmd,
754 "show address " VRF_ALL_CMD_STR,
757 VRF_ALL_CMD_HELP_STR)
759 struct list *intf_list;
760 struct listnode *node;
761 struct listnode *node2;
762 struct interface *ifp;
763 struct connected *ifc;
767 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
769 intf_list = vrf_iter2iflist (iter);
770 if (!intf_list || !listcount (intf_list))
773 vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
774 VTY_NEWLINE, VTY_NEWLINE);
776 for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
778 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
782 if (p->family == AF_INET)
783 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
791 /* Allocate connected structure. */
795 return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
798 /* Free connected structure. */
800 connected_free (struct connected *connected)
802 if (connected->address)
803 prefix_free (connected->address);
805 if (connected->destination)
806 prefix_free (connected->destination);
808 if (connected->label)
809 XFREE (MTYPE_CONNECTED_LABEL, connected->label);
811 XFREE (MTYPE_CONNECTED, connected);
814 /* Print if_addr structure. */
815 static void __attribute__ ((unused))
816 connected_log (struct connected *connected, char *str)
819 struct interface *ifp;
823 ifp = connected->ifp;
824 p = connected->address;
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),
831 p = connected->destination;
834 strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
835 BUFSIZ - strlen(logbuf));
837 zlog (NULL, LOG_INFO, "%s", logbuf);
840 /* If two connected address has same prefix return 1. */
842 connected_same_prefix (struct prefix *p1, struct prefix *p2)
844 if (p1->family == p2->family)
846 if (p1->family == AF_INET &&
847 IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
850 if (p1->family == AF_INET6 &&
851 IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
853 #endif /* HAVE_IPV6 */
859 connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
861 struct listnode *node;
862 struct listnode *next;
863 struct connected *ifc;
865 /* In case of same prefix come, replace it with new one. */
866 for (node = listhead (ifp->connected); node; node = next)
868 ifc = listgetdata (node);
871 if (connected_same_prefix (ifc->address, p))
873 listnode_delete (ifp->connected, ifc);
880 /* Find the IPv4 address on our side that will be used when packets
883 connected_lookup_address (struct interface *ifp, struct in_addr dst)
886 struct listnode *cnode;
888 struct connected *match;
890 addr.family = AF_INET;
891 addr.u.prefix4 = dst;
892 addr.prefixlen = IPV4_MAX_BITLEN;
896 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
898 if (c->address && (c->address->family == AF_INET) &&
899 prefix_match(CONNECTED_PREFIX(c), &addr) &&
900 (!match || (c->address->prefixlen > match->address->prefixlen)))
907 connected_add_by_prefix (struct interface *ifp, struct prefix *p,
908 struct prefix *destination)
910 struct connected *ifc;
912 /* Allocate new connected address. */
913 ifc = connected_new ();
916 /* Fetch interface address */
917 ifc->address = prefix_new();
918 memcpy (ifc->address, p, sizeof(struct prefix));
920 /* Fetch dest address */
923 ifc->destination = prefix_new();
924 memcpy (ifc->destination, destination, sizeof(struct prefix));
927 /* Add connected address to the interface. */
928 listnode_add (ifp->connected, ifc);
932 #ifndef HAVE_IF_NAMETOINDEX
934 if_nametoindex (const char *name)
936 struct interface *ifp;
938 return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
943 #ifndef HAVE_IF_INDEXTONAME
945 if_indextoname (ifindex_t ifindex, char *name)
947 struct interface *ifp;
949 if (!(ifp = if_lookup_by_index(ifindex)))
951 strncpy (name, ifp->name, IFNAMSIZ);
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
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; */
966 ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
968 struct route_node *rn;
969 struct prefix_ipv4 p;
972 p.prefixlen = IPV4_MAX_PREFIXLEN;
975 rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
978 route_unlock_node (rn);
979 zlog_info ("ifaddr_ipv4_add(): address %s is already added",
980 inet_ntoa (*ifaddr));
987 ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
989 struct route_node *rn;
990 struct prefix_ipv4 p;
993 p.prefixlen = IPV4_MAX_PREFIXLEN;
996 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
999 zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
1000 inet_ntoa (*ifaddr));
1004 route_unlock_node (rn);
1005 route_unlock_node (rn);
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)
1012 struct prefix_ipv4 p;
1013 struct route_node *rn;
1014 struct interface *ifp;
1019 p.prefixlen = IPV4_MAX_PREFIXLEN;
1022 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1027 route_unlock_node (rn);
1031 return if_lookup_by_index(ifindex);
1033 #endif /* ifaddr_ipv4_table */
1035 /* Initialize interface list. */
1037 if_init (vrf_id_t vrf_id, struct list **intf_list)
1039 *intf_list = list_new ();
1041 ifaddr_ipv4_table = route_table_init ();
1042 #endif /* ifaddr_ipv4_table */
1044 (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
1046 if (vrf_id == VRF_DEFAULT)
1047 iflist = *intf_list;
1051 if_terminate (vrf_id_t vrf_id, struct list **intf_list)
1055 struct interface *ifp;
1057 ifp = listnode_head (*intf_list);
1064 list_delete (*intf_list);
1067 if (vrf_id == VRF_DEFAULT)
1072 if_link_type_str (enum zebra_link_type llt)
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");
1124 zlog_warn ("Unknown value %d", llt);
1125 return "Unknown type!";
1131 struct if_link_params *
1132 if_link_params_get (struct interface *ifp)
1136 if (ifp->link_params != NULL)
1137 return ifp->link_params;
1139 struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
1140 sizeof (struct if_link_params));
1141 if (iflp == NULL) return NULL;
1143 /* Set TE metric == standard metric */
1144 iflp->te_metric = ifp->metric;
1146 /* Compute default bandwidth based on interface */
1147 int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
1148 * TE_KILO_BIT / TE_BYTE);
1150 /* Set Max, Reservable and Unreserved Bandwidth */
1152 iflp->max_rsv_bw = bw;
1153 for (i = 0; i < MAX_CLASS_TYPE; i++)
1154 iflp->unrsv_bw[i] = bw;
1156 /* Update Link parameters status */
1157 iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
1159 /* Finally attach newly created Link Parameters */
1160 ifp->link_params = iflp;
1166 if_link_params_free (struct interface *ifp)
1168 if (ifp->link_params == NULL) return;
1169 XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
1170 ifp->link_params = NULL;