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
if_cmp_func(struct interface * ifp1,struct interface * ifp2)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 *
if_create_vrf(const char * name,int namelen,vrf_id_t vrf_id)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 *
if_create(const char * name,int namelen)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
if_delete_retain(struct interface * ifp)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
if_delete(struct interface * ifp)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
if_add_hook(int type,int (* func)(struct interface * ifp))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 *
if_lookup_by_index_vrf(ifindex_t ifindex,vrf_id_t vrf_id)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 *
if_lookup_by_index(ifindex_t ifindex)208 if_lookup_by_index (ifindex_t ifindex)
209 {
210   return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
211 }
212 
213 const char *
ifindex2ifname_vrf(ifindex_t ifindex,vrf_id_t vrf_id)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 *
ifindex2ifname(ifindex_t ifindex)223 ifindex2ifname (ifindex_t ifindex)
224 {
225   return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
226 }
227 
228 ifindex_t
ifname2ifindex_vrf(const char * name,vrf_id_t vrf_id)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
ifname2ifindex(const char * name)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 *
if_lookup_by_name_vrf(const char * name,vrf_id_t vrf_id)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 *
if_lookup_by_name(const char * name)260 if_lookup_by_name (const char *name)
261 {
262   return if_lookup_by_name_vrf (name, VRF_DEFAULT);
263 }
264 
265 struct interface *
if_lookup_by_name_len_vrf(const char * name,size_t namelen,vrf_id_t vrf_id)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 *
if_lookup_by_name_len(const char * name,size_t namelen)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 *
if_lookup_exact_address_vrf(struct in_addr src,vrf_id_t vrf_id)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 *
if_lookup_exact_address(struct in_addr src)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 *
if_lookup_address_vrf(struct in_addr src,vrf_id_t vrf_id)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 *
if_lookup_address(struct in_addr src)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 *
if_lookup_prefix_vrf(struct prefix * prefix,vrf_id_t vrf_id)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 *
if_lookup_prefix(struct prefix * prefix)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 *
if_get_by_name_vrf(const char * name,vrf_id_t vrf_id)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 *
if_get_by_name(const char * name)400 if_get_by_name (const char *name)
401 {
402   return if_get_by_name_vrf (name, VRF_DEFAULT);
403 }
404 
405 struct interface *
if_get_by_name_len_vrf(const char * name,size_t namelen,vrf_id_t vrf_id)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 *
if_get_by_name_len(const char * name,size_t namelen)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
if_is_up(struct interface * ifp)422 if_is_up (struct interface *ifp)
423 {
424   return ifp->flags & IFF_UP;
425 }
426 
427 /* Is interface running? */
428 int
if_is_running(struct interface * ifp)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
if_is_operative(struct interface * ifp)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
if_is_loopback(struct interface * ifp)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
if_is_broadcast(struct interface * ifp)455 if_is_broadcast (struct interface *ifp)
456 {
457   return ifp->flags & IFF_BROADCAST;
458 }
459 
460 /* Does this interface support broadcast ? */
461 int
if_is_pointopoint(struct interface * ifp)462 if_is_pointopoint (struct interface *ifp)
463 {
464   return ifp->flags & IFF_POINTOPOINT;
465 }
466 
467 /* Does this interface support multicast ? */
468 int
if_is_multicast(struct interface * ifp)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 *
if_flag_dump(unsigned long flag)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
if_dump(const struct interface * ifp)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
if_dump_all(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 *
if_sunwzebra_get(const char * name,size_t nlen,vrf_id_t vrf_id)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 *
connected_new(void)793 connected_new (void)
794 {
795   return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
796 }
797 
798 /* Free connected structure. */
799 void
connected_free(struct connected * connected)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))
connected_log(struct connected * connected,char * str)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
connected_same_prefix(struct prefix * p1,struct prefix * p2)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 *
connected_delete_by_prefix(struct interface * ifp,struct prefix * p)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 *
connected_lookup_address(struct interface * ifp,struct in_addr dst)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 *
connected_add_by_prefix(struct interface * ifp,struct prefix * p,struct prefix * destination)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
if_nametoindex(const char * name)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 *
if_indextoname(ifindex_t ifindex,char * name)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
if_init(vrf_id_t vrf_id,struct list ** intf_list)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
if_terminate(vrf_id_t vrf_id,struct list ** intf_list)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 *
if_link_type_str(enum zebra_link_type llt)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 *
if_link_params_get(struct interface * ifp)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
if_link_params_free(struct interface * ifp)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 }
1172