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