]> git.proxmox.com Git - mirror_frr.git/blame - lib/if.c
isisd: scrub argc CHECK ME's, refactor general
[mirror_frr.git] / lib / if.c
CommitLineData
106d2fd5 1
718e3744 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"
8736158a 30#include "vrf.h"
718e3744 31#include "if.h"
32#include "sockunion.h"
33#include "prefix.h"
718e3744 34#include "memory.h"
35#include "table.h"
36#include "buffer.h"
37#include "str.h"
38#include "log.h"
6b0655a2 39
4a1ab8e4
DL
40DEFINE_MTYPE( LIB, IF, "Interface")
41DEFINE_MTYPE_STATIC(LIB, CONNECTED, "Connected")
42DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED, "Neighbor Connected")
43DEFINE_MTYPE( LIB, CONNECTED_LABEL, "Connected interface label")
44DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters")
45
8736158a 46/* List of interfaces in only the default VRF */
244c1cdc 47int ptm_enable = 0;
718e3744 48
49/* One for each program. This structure is needed to store hooks. */
50struct if_master
51{
52 int (*if_new_hook) (struct interface *);
53 int (*if_delete_hook) (struct interface *);
8736158a 54} if_master = {0,};
6b0655a2 55
3a0391a9 56/* Compare interface names, returning an integer greater than, equal to, or
57 * less than 0, (following the strcmp convention), according to the
58 * relationship between ifp1 and ifp2. Interface names consist of an
59 * alphabetic prefix and a numeric suffix. The primary sort key is
60 * lexicographic by name, and then numeric by number. No number sorts
61 * before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
62 * devpty0, de0 < del0
63 */
106d2fd5 64int
974fc9d2 65if_cmp_name_func (char *p1, char *p2)
106d2fd5 66{
67 unsigned int l1, l2;
68 long int x1, x2;
106d2fd5 69 int res;
70
90578521 71 while (*p1 && *p2) {
106d2fd5 72 /* look up to any number */
73 l1 = strcspn(p1, "0123456789");
74 l2 = strcspn(p2, "0123456789");
75
76 /* name lengths are different -> compare names */
77 if (l1 != l2)
78 return (strcmp(p1, p2));
79
3a0391a9 80 /* Note that this relies on all numbers being less than all letters, so
81 * that de0 < del0.
82 */
106d2fd5 83 res = strncmp(p1, p2, l1);
84
85 /* names are different -> compare them */
86 if (res)
87 return res;
88
89 /* with identical name part, go to numeric part */
106d2fd5 90 p1 += l1;
91 p2 += l1;
92
b06c14f2 93 if (!*p1)
94 return -1;
95 if (!*p2)
96 return 1;
97
106d2fd5 98 x1 = strtol(p1, &p1, 10);
99 x2 = strtol(p2, &p2, 10);
100
101 /* let's compare numbers now */
102 if (x1 < x2)
103 return -1;
104 if (x1 > x2)
105 return 1;
106
107 /* numbers were equal, lets do it again..
108 (it happens with name like "eth123.456:789") */
109 }
90578521 110 if (*p1)
111 return 1;
112 if (*p2)
113 return -1;
114 return 0;
106d2fd5 115}
116
974fc9d2
DS
117static int
118if_cmp_func (struct interface *ifp1, struct interface *ifp2)
119{
120 return if_cmp_name_func (ifp1->name, ifp2->name);
121}
122
718e3744 123/* Create new interface structure. */
718e3744 124struct interface *
8736158a 125if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
718e3744 126{
127 struct interface *ifp;
8736158a 128 struct list *intf_list = vrf_iflist_get (vrf_id);
718e3744 129
d2fc8896 130 ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
131 ifp->ifindex = IFINDEX_INTERNAL;
718e3744 132
106d2fd5 133 assert (name);
d2fc8896 134 assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
106d2fd5 135 strncpy (ifp->name, name, namelen);
d2fc8896 136 ifp->name[namelen] = '\0';
8736158a
FL
137 ifp->vrf_id = vrf_id;
138 if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
139 listnode_add_sort (intf_list, ifp);
d2fc8896 140 else
141 zlog_err("if_create(%s): corruption detected -- interface with this "
8736158a 142 "name exists already in VRF %u!", ifp->name, vrf_id);
718e3744 143 ifp->connected = list_new ();
144 ifp->connected->del = (void (*) (void *)) connected_free;
145
a80beece
DS
146 ifp->nbr_connected = list_new ();
147 ifp->nbr_connected->del = (void (*) (void *)) nbr_connected_free;
148
c9506a0a
DS
149 /* Enable Link-detection by default */
150 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
151
718e3744 152 if (if_master.if_new_hook)
153 (*if_master.if_new_hook) (ifp);
154
155 return ifp;
156}
157
8736158a
FL
158struct interface *
159if_create (const char *name, int namelen)
160{
161 return if_create_vrf (name, namelen, VRF_DEFAULT);
162}
163
f93e3f69
DS
164/* Create new interface structure. */
165void
166if_update_vrf (struct interface *ifp, const char *name, int namelen, vrf_id_t vrf_id)
167{
168 struct list *intf_list = vrf_iflist_get (vrf_id);
169
170 /* remove interface from old master vrf list */
171 if (vrf_iflist (ifp->vrf_id))
172 listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
173
174 assert (name);
175 assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
176 strncpy (ifp->name, name, namelen);
177 ifp->name[namelen] = '\0';
178 ifp->vrf_id = vrf_id;
179 if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
180 listnode_add_sort (intf_list, ifp);
181 else
182 zlog_err("if_create(%s): corruption detected -- interface with this "
183 "name exists already in VRF %u!", ifp->name, vrf_id);
184
185 return;
186}
187
188
d2fc8896 189/* Delete interface structure. */
718e3744 190void
d2fc8896 191if_delete_retain (struct interface *ifp)
718e3744 192{
718e3744 193 if (if_master.if_delete_hook)
194 (*if_master.if_delete_hook) (ifp);
195
196 /* Free connected address list */
2dd04c5d 197 list_delete_all_node (ifp->connected);
a80beece
DS
198
199 /* Free connected nbr address list */
200 list_delete_all_node (ifp->nbr_connected);
d2fc8896 201}
202
203/* Delete and free interface structure. */
204void
205if_delete (struct interface *ifp)
206{
8736158a 207 listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
d2fc8896 208
209 if_delete_retain(ifp);
718e3744 210
2dd04c5d 211 list_free (ifp->connected);
a80beece 212 list_free (ifp->nbr_connected);
2dd04c5d 213
16f1b9ee
OD
214 if_link_params_free (ifp);
215
718e3744 216 XFREE (MTYPE_IF, ifp);
217}
218
219/* Add hook to interface master. */
220void
221if_add_hook (int type, int (*func)(struct interface *ifp))
222{
223 switch (type) {
224 case IF_NEW_HOOK:
225 if_master.if_new_hook = func;
226 break;
227 case IF_DELETE_HOOK:
228 if_master.if_delete_hook = func;
229 break;
230 default:
231 break;
232 }
233}
234
235/* Interface existance check by index. */
236struct interface *
b892f1dd 237if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
718e3744 238{
52dc7ee6 239 struct listnode *node;
718e3744 240 struct interface *ifp;
241
8736158a 242 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
718e3744 243 {
b892f1dd 244 if (ifp->ifindex == ifindex)
718e3744 245 return ifp;
246 }
247 return NULL;
248}
249
8736158a 250struct interface *
b892f1dd 251if_lookup_by_index (ifindex_t ifindex)
8736158a 252{
b892f1dd 253 return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
8736158a
FL
254}
255
8cc4198f 256const char *
b892f1dd 257ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
718e3744 258{
718e3744 259 struct interface *ifp;
260
b892f1dd 261 return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
8cc4198f 262 ifp->name : "unknown";
d2fc8896 263}
264
8736158a 265const char *
b892f1dd 266ifindex2ifname (ifindex_t ifindex)
8736158a 267{
b892f1dd 268 return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
8736158a
FL
269}
270
b892f1dd 271ifindex_t
8736158a 272ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
d2fc8896 273{
274 struct interface *ifp;
275
8736158a 276 return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
3e4ee959 277 : IFINDEX_INTERNAL;
718e3744 278}
279
b892f1dd 280ifindex_t
8736158a
FL
281ifname2ifindex (const char *name)
282{
283 return ifname2ifindex_vrf (name, VRF_DEFAULT);
284}
285
718e3744 286/* Interface existance check by interface name. */
287struct interface *
8736158a 288if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
718e3744 289{
52dc7ee6 290 struct listnode *node;
718e3744 291 struct interface *ifp;
3e4ee959
PJ
292
293 if (name)
8736158a 294 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
3e4ee959
PJ
295 {
296 if (strcmp(name, ifp->name) == 0)
297 return ifp;
298 }
718e3744 299 return NULL;
300}
301
f8962871
DS
302struct interface *
303if_lookup_by_name_all_vrf (const char *name)
304{
305 struct interface *ifp;
306 struct vrf *vrf = NULL;
307 vrf_iter_t iter;
308
309 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
310 {
311 vrf = vrf_iter2vrf (iter);
312 ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
313 if (ifp)
314 return ifp;
315 }
316
317 return NULL;
318}
319
a349198f 320struct interface *
8736158a
FL
321if_lookup_by_name (const char *name)
322{
323 return if_lookup_by_name_vrf (name, VRF_DEFAULT);
324}
325
326struct interface *
327if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
a349198f 328{
329 struct listnode *node;
1eb8ef25 330 struct interface *ifp;
a349198f 331
332 if (namelen > INTERFACE_NAMSIZ)
333 return NULL;
334
8736158a 335 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
a349198f 336 {
a349198f 337 if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
338 return ifp;
339 }
340 return NULL;
341}
342
8736158a
FL
343struct interface *
344if_lookup_by_name_len(const char *name, size_t namelen)
345{
346 return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
347}
348
718e3744 349/* Lookup interface by IPv4 address. */
350struct interface *
8736158a 351if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
718e3744 352{
52dc7ee6 353 struct listnode *node;
354 struct listnode *cnode;
718e3744 355 struct interface *ifp;
356 struct prefix *p;
357 struct connected *c;
358
8736158a 359 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
718e3744 360 {
1eb8ef25 361 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
718e3744 362 {
718e3744 363 p = c->address;
364
0aabccc0 365 if (p && (p->family == family))
718e3744 366 {
0aabccc0
DD
367 if (family == AF_INET)
368 {
369 if (IPV4_ADDR_SAME (&p->u.prefix4, (struct in_addr *)src))
370 return ifp;
371 }
372 else if (family == AF_INET6)
373 {
374 if (IPV6_ADDR_SAME (&p->u.prefix4, (struct in6_addr *)src))
375 return ifp;
376 }
377 }
718e3744 378 }
379 }
380 return NULL;
381}
382
8736158a
FL
383struct interface *
384if_lookup_exact_address (void *src, int family)
385{
386 return if_lookup_exact_address_vrf (src, family, VRF_DEFAULT);
387}
388
718e3744 389/* Lookup interface by IPv4 address. */
390struct interface *
8736158a 391if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
718e3744 392{
52dc7ee6 393 struct listnode *node;
718e3744 394 struct prefix addr;
3fb9cd6e 395 int bestlen = 0;
52dc7ee6 396 struct listnode *cnode;
718e3744 397 struct interface *ifp;
718e3744 398 struct connected *c;
399 struct interface *match;
400
0aabccc0
DD
401 if (family == AF_INET)
402 {
403 addr.family = AF_INET;
404 addr.u.prefix4 = *((struct in_addr *)matchaddr);
405 addr.prefixlen = IPV4_MAX_BITLEN;
406 }
407 else if (family == AF_INET6)
408 {
409 addr.family = AF_INET6;
410 addr.u.prefix6 = *((struct in6_addr *)matchaddr);
411 addr.prefixlen = IPV6_MAX_BITLEN;
412 }
718e3744 413
414 match = NULL;
415
8736158a 416 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
718e3744 417 {
1eb8ef25 418 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
718e3744 419 {
e4529636
AS
420 if (c->address && (c->address->family == AF_INET) &&
421 prefix_match(CONNECTED_PREFIX(c), &addr) &&
422 (c->address->prefixlen > bestlen))
718e3744 423 {
e4529636
AS
424 bestlen = c->address->prefixlen;
425 match = ifp;
718e3744 426 }
427 }
428 }
429 return match;
430}
431
8736158a
FL
432struct interface *
433if_lookup_address (void *matchaddr, int family)
434{
435 return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
436}
437
b81e97a8
DD
438/* Lookup interface by prefix */
439struct interface *
8736158a 440if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
b81e97a8
DD
441{
442 struct listnode *node;
b81e97a8
DD
443 struct listnode *cnode;
444 struct interface *ifp;
445 struct connected *c;
446
8736158a 447 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
b81e97a8
DD
448 {
449 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
450 {
451 if (prefix_cmp(c->address, prefix) == 0)
452 {
453 return ifp;
454 }
455 }
456 }
457 return NULL;
458}
459
8736158a
FL
460struct interface *
461if_lookup_prefix (struct prefix *prefix)
462{
463 return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
464}
465
718e3744 466/* Get interface by name if given name interface doesn't exist create
467 one. */
468struct interface *
8736158a 469if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
718e3744 470{
471 struct interface *ifp;
472
8736158a
FL
473 return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
474 if_create_vrf (name, strlen(name), vrf_id);
a349198f 475}
476
477struct interface *
8736158a
FL
478if_get_by_name (const char *name)
479{
480 return if_get_by_name_vrf (name, VRF_DEFAULT);
481}
482
483struct interface *
85f9da7f 484if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
a349198f 485{
486 struct interface *ifp;
85f9da7f
DS
487 struct listnode *node;
488 struct vrf *vrf = NULL;
489 vrf_iter_t iter;
490
491 ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
492 if (ifp)
493 return ifp;
a349198f 494
85f9da7f
DS
495 /* Didn't find the interface on that vrf. Defined on a different one? */
496 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
497 {
498 vrf = vrf_iter2vrf(iter);
499 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp))
500 {
501 if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
502 {
503 /* Found a match. If the interface command was entered in vty without a
504 * VRF (passed as VRF_DEFAULT), accept the ifp we found. If a vrf was
505 * entered and there is a mismatch, reject it if from vty. If it came
506 * from the kernel by way of zclient, believe it and update
507 * the ifp accordingly.
508 */
53eadacf 509 if (vty)
510 {
511 if (vrf_id == VRF_DEFAULT)
512 return ifp;
513 return NULL;
514 }
85f9da7f
DS
515 else
516 {
517 if_update_vrf (ifp, name, namelen, vrf_id);
518 return ifp;
519 }
520 }
521 }
522 }
523 return (if_create_vrf (name, namelen, vrf_id));
8736158a
FL
524}
525
526struct interface *
527if_get_by_name_len (const char *name, size_t namelen)
528{
85f9da7f 529 return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT, 0);
718e3744 530}
531
532/* Does interface up ? */
533int
534if_is_up (struct interface *ifp)
535{
536 return ifp->flags & IFF_UP;
537}
538
2e3b2e47 539/* Is interface running? */
540int
541if_is_running (struct interface *ifp)
542{
543 return ifp->flags & IFF_RUNNING;
544}
545
546/* Is the interface operative, eg. either UP & RUNNING
244c1cdc
DS
547 or UP & !ZEBRA_INTERFACE_LINK_DETECTION and
548 if ptm checking is enabled, then ptm check has passed */
2e3b2e47 549int
550if_is_operative (struct interface *ifp)
551{
552 return ((ifp->flags & IFF_UP) &&
244c1cdc
DS
553 (((ifp->flags & IFF_RUNNING) &&
554 (ifp->ptm_status || !ifp->ptm_enable)) ||
555 !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
556}
557
558/* Is the interface operative, eg. either UP & RUNNING
559 or UP & !ZEBRA_INTERFACE_LINK_DETECTION, without PTM check */
560int
561if_is_no_ptm_operative (struct interface *ifp)
562{
563 return ((ifp->flags & IFF_UP) &&
564 ((ifp->flags & IFF_RUNNING) ||
565 !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
2e3b2e47 566}
567
718e3744 568/* Is this loopback interface ? */
569int
570if_is_loopback (struct interface *ifp)
571{
4ba9b924 572 /* XXX: Do this better, eg what if IFF_WHATEVER means X on platform M
573 * but Y on platform N?
574 */
575 return (ifp->flags & (IFF_LOOPBACK|IFF_NOXMIT|IFF_VIRTUAL));
718e3744 576}
577
578/* Does this interface support broadcast ? */
579int
580if_is_broadcast (struct interface *ifp)
581{
582 return ifp->flags & IFF_BROADCAST;
583}
584
585/* Does this interface support broadcast ? */
586int
587if_is_pointopoint (struct interface *ifp)
588{
589 return ifp->flags & IFF_POINTOPOINT;
590}
591
592/* Does this interface support multicast ? */
593int
594if_is_multicast (struct interface *ifp)
595{
596 return ifp->flags & IFF_MULTICAST;
597}
598
599/* Printout flag information into log */
600const char *
601if_flag_dump (unsigned long flag)
602{
603 int separator = 0;
604 static char logbuf[BUFSIZ];
605
606#define IFF_OUT_LOG(X,STR) \
4ba9b924 607 if (flag & (X)) \
718e3744 608 { \
609 if (separator) \
610 strlcat (logbuf, ",", BUFSIZ); \
611 else \
612 separator = 1; \
613 strlcat (logbuf, STR, BUFSIZ); \
614 }
615
630c97ce 616 strlcpy (logbuf, "<", BUFSIZ);
718e3744 617 IFF_OUT_LOG (IFF_UP, "UP");
618 IFF_OUT_LOG (IFF_BROADCAST, "BROADCAST");
619 IFF_OUT_LOG (IFF_DEBUG, "DEBUG");
620 IFF_OUT_LOG (IFF_LOOPBACK, "LOOPBACK");
621 IFF_OUT_LOG (IFF_POINTOPOINT, "POINTOPOINT");
622 IFF_OUT_LOG (IFF_NOTRAILERS, "NOTRAILERS");
623 IFF_OUT_LOG (IFF_RUNNING, "RUNNING");
624 IFF_OUT_LOG (IFF_NOARP, "NOARP");
625 IFF_OUT_LOG (IFF_PROMISC, "PROMISC");
626 IFF_OUT_LOG (IFF_ALLMULTI, "ALLMULTI");
627 IFF_OUT_LOG (IFF_OACTIVE, "OACTIVE");
628 IFF_OUT_LOG (IFF_SIMPLEX, "SIMPLEX");
629 IFF_OUT_LOG (IFF_LINK0, "LINK0");
630 IFF_OUT_LOG (IFF_LINK1, "LINK1");
631 IFF_OUT_LOG (IFF_LINK2, "LINK2");
632 IFF_OUT_LOG (IFF_MULTICAST, "MULTICAST");
4ba9b924 633 IFF_OUT_LOG (IFF_NOXMIT, "NOXMIT");
634 IFF_OUT_LOG (IFF_NORTEXCH, "NORTEXCH");
635 IFF_OUT_LOG (IFF_VIRTUAL, "VIRTUAL");
636 IFF_OUT_LOG (IFF_IPV4, "IPv4");
637 IFF_OUT_LOG (IFF_IPV6, "IPv6");
718e3744 638
639 strlcat (logbuf, ">", BUFSIZ);
640
641 return logbuf;
630c97ce 642#undef IFF_OUT_LOG
718e3744 643}
644
645/* For debugging */
8cc4198f 646static void
cedd7f2f 647if_dump (const struct interface *ifp)
718e3744 648{
1f9a9fff
PJ
649 struct listnode *node;
650 struct connected *c __attribute__((unused));
651
652 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
3968dbf8 653 zlog_info ("Interface %s vrf %u index %d metric %d mtu %d "
1f9a9fff 654 "mtu6 %d %s",
3968dbf8 655 ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, ifp->mtu,
1f9a9fff 656 ifp->mtu6, if_flag_dump (ifp->flags));
718e3744 657}
658
659/* Interface printing for all interface. */
660void
66e5cd87 661if_dump_all (void)
718e3744 662{
8736158a 663 struct list *intf_list;
52dc7ee6 664 struct listnode *node;
1eb8ef25 665 void *p;
8736158a 666 vrf_iter_t iter;
718e3744 667
8736158a
FL
668 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
669 if ((intf_list = vrf_iter2iflist (iter)) != NULL)
670 for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
671 if_dump (p);
718e3744 672}
673
6147e2c6 674DEFUN (interface_desc,
718e3744 675 interface_desc_cmd,
fcbee690 676 "description LINE...",
718e3744 677 "Interface specific description\n"
678 "Characters describing this interface\n")
679{
67656e9b 680 /* CHECK ME argc referenced below */
718e3744 681 struct interface *ifp;
718e3744 682
fcbee690 683 if (argc == 1)
718e3744 684 return CMD_SUCCESS;
685
686 ifp = vty->index;
687 if (ifp->desc)
3b8b1855 688 XFREE (MTYPE_TMP, ifp->desc);
fcbee690 689 ifp->desc = argv_concat(argv, argc, 1);
718e3744 690
691 return CMD_SUCCESS;
692}
693
6147e2c6 694DEFUN (no_interface_desc,
718e3744 695 no_interface_desc_cmd,
696 "no description",
697 NO_STR
698 "Interface specific description\n")
699{
700 struct interface *ifp;
701
702 ifp = vty->index;
703 if (ifp->desc)
0241684e 704 XFREE (MTYPE_TMP, ifp->desc);
718e3744 705 ifp->desc = NULL;
706
707 return CMD_SUCCESS;
708}
6b0655a2 709
98954844
PJ
710#ifdef SUNOS_5
711/* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created
712 * a seperate struct interface for each logical interface, so config
713 * file may be full of 'interface fooX:Y'. Solaris however does not
714 * expose logical interfaces via PF_ROUTE, so trying to track logical
715 * interfaces can be fruitless, for that reason Quagga only tracks
716 * the primary IP interface.
717 *
718 * We try accomodate SUNWzebra by:
719 * - looking up the interface name, to see whether it exists, if so
720 * its useable
721 * - for protocol daemons, this could only because zebra told us of
722 * the interface
723 * - for zebra, only because it learnt from kernel
724 * - if not:
725 * - search the name to see if it contains a sub-ipif / logical interface
726 * seperator, the ':' char. If it does:
727 * - text up to that char must be the primary name - get that name.
728 * if not:
729 * - no idea, just get the name in its entirety.
730 */
731static struct interface *
8736158a 732if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
98954844
PJ
733{
734 struct interface *ifp;
735 size_t seppos = 0;
718e3744 736
8736158a 737 if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
98954844
PJ
738 return ifp;
739
740 /* hunt the primary interface name... */
741 while (seppos < nlen && name[seppos] != ':')
742 seppos++;
743
744 /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
745 if (seppos < nlen)
85f9da7f 746 return if_get_by_name_len_vrf (name, seppos, vrf_id, 1);
98954844 747 else
85f9da7f 748 return if_get_by_name_len_vrf (name, nlen, vrf_id, 1);
98954844
PJ
749}
750#endif /* SUNOS_5 */
6b0655a2 751
718e3744 752DEFUN (interface,
753 interface_cmd,
199d90a1 754 "interface IFNAME [vrf NAME]",
718e3744 755 "Select an interface to configure\n"
fcbee690
QY
756 "Interface's name\n"
757 VRF_CMD_HELP_STR)
718e3744 758{
c349116d 759 int idx_ifname = 1;
abddf075 760 int idx_vrf = 3;
c349116d 761 const char *ifname = argv[idx_ifname]->arg;
abddf075 762 const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL;
fcbee690 763
718e3744 764 struct interface *ifp;
d2fc8896 765 size_t sl;
8736158a 766 vrf_id_t vrf_id = VRF_DEFAULT;
d2fc8896 767
fcbee690 768 if ((sl = strlen(ifname)) > INTERFACE_NAMSIZ)
d2fc8896 769 {
770 vty_out (vty, "%% Interface name %s is invalid: length exceeds "
771 "%d characters%s",
fcbee690 772 ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
d2fc8896 773 return CMD_WARNING;
774 }
718e3744 775
f93e3f69
DS
776/*Pending: need proper vrf name based lookup/(possible creation of VRF)
777 Imagine forward reference of a vrf by name in this interface config */
fcbee690
QY
778 if (vrfname)
779 VRF_GET_ID (vrf_id, vrfname);
cd2a8a42 780
98954844 781#ifdef SUNOS_5
fcbee690 782 ifp = if_sunwzebra_get (ifname, sl, vrf_id);
98954844 783#else
fcbee690 784 ifp = if_get_by_name_len_vrf (ifname, sl, vrf_id, 1);
98954844 785#endif /* SUNOS_5 */
718e3744 786
85f9da7f
DS
787 if (!ifp)
788 {
fcbee690 789 vty_out (vty, "%% interface %s not in %s%s", ifname, vrfname, VTY_NEWLINE);
85f9da7f
DS
790 return CMD_WARNING;
791 }
718e3744 792 vty->index = ifp;
793 vty->node = INTERFACE_NODE;
794
795 return CMD_SUCCESS;
796}
797
32d2463c 798DEFUN_NOSH (no_interface,
799 no_interface_cmd,
199d90a1 800 "no interface IFNAME [vrf NAME]",
32d2463c 801 NO_STR
802 "Delete a pseudo interface's configuration\n"
fcbee690
QY
803 "Interface's name\n"
804 VRF_CMD_HELP_STR)
32d2463c 805{
fcbee690
QY
806 const char *ifname = argv[2]->arg;
807 const char *vrfname = (argc > 3) ? argv[3]->arg : NULL;
808
32d2463c 809 // deleting interface
810 struct interface *ifp;
8736158a 811 vrf_id_t vrf_id = VRF_DEFAULT;
32d2463c 812
fcbee690
QY
813 if (argc > 3)
814 VRF_GET_ID (vrf_id, vrfname);
cd2a8a42 815
fcbee690 816 ifp = if_lookup_by_name_vrf (ifname, vrf_id);
32d2463c 817
818 if (ifp == NULL)
d2fc8896 819 {
fcbee690 820 vty_out (vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
d2fc8896 821 return CMD_WARNING;
822 }
32d2463c 823
bfc13532 824 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
d2fc8896 825 {
826 vty_out (vty, "%% Only inactive interfaces can be deleted%s",
827 VTY_NEWLINE);
828 return CMD_WARNING;
829 }
32d2463c 830
831 if_delete(ifp);
832
833 return CMD_SUCCESS;
834}
835
f93e3f69
DS
836DEFUN (vrf,
837 vrf_cmd,
bcff2289
DW
838 "vrf NAME",
839 "Select a VRF to configure\n"
840 "VRF's name\n")
f93e3f69 841{
c349116d
DW
842 int idx_name = 1;
843 const char *vrfname = argv[idx_name]->arg;
fcbee690 844
f93e3f69
DS
845 struct vrf *vrfp;
846 size_t sl;
847
fcbee690 848 if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
f93e3f69
DS
849 {
850 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
851 "%d characters%s",
fcbee690 852 vrfname, VRF_NAMSIZ, VTY_NEWLINE);
f93e3f69
DS
853 return CMD_WARNING;
854 }
855
fcbee690 856 vrfp = vrf_get (VRF_UNKNOWN, vrfname);
f93e3f69
DS
857
858 vty->index = vrfp;
859 vty->node = VRF_NODE;
860
861 return CMD_SUCCESS;
862}
863
864DEFUN_NOSH (no_vrf,
865 no_vrf_cmd,
bcff2289 866 "no vrf NAME",
f93e3f69 867 NO_STR
bcff2289
DW
868 "Delete a pseudo VRF's configuration\n"
869 "VRF's name\n")
f93e3f69 870{
fcbee690
QY
871 const char *vrfname = argv[2]->arg;
872
f93e3f69
DS
873 struct vrf *vrfp;
874
fcbee690 875 vrfp = vrf_list_lookup_by_name (vrfname);;
f93e3f69
DS
876
877 if (vrfp == NULL)
878 {
fcbee690 879 vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
f93e3f69
DS
880 return CMD_WARNING;
881 }
882
79694123 883 if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
f93e3f69
DS
884 {
885 vty_out (vty, "%% Only inactive VRFs can be deleted%s",
886 VTY_NEWLINE);
887 return CMD_WARNING;
888 }
889
890 vrf_delete(vrfp);
891
892 return CMD_SUCCESS;
893}
894
895
718e3744 896/* For debug purpose. */
897DEFUN (show_address,
898 show_address_cmd,
199d90a1 899 "show address [vrf NAME]",
718e3744 900 SHOW_STR
fcbee690
QY
901 "address\n"
902 VRF_CMD_HELP_STR)
718e3744 903{
abddf075 904 int idx_vrf = 3;
52dc7ee6 905 struct listnode *node;
906 struct listnode *node2;
718e3744 907 struct interface *ifp;
908 struct connected *ifc;
909 struct prefix *p;
8736158a 910 vrf_id_t vrf_id = VRF_DEFAULT;
718e3744 911
fcbee690 912 if (argc > 2)
c349116d 913 VRF_GET_ID (vrf_id, argv[idx_vrf_cmd_str]->arg);
8736158a
FL
914
915 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
718e3744 916 {
1eb8ef25 917 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
718e3744 918 {
718e3744 919 p = ifc->address;
920
921 if (p->family == AF_INET)
922 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
923 VTY_NEWLINE);
924 }
925 }
926 return CMD_SUCCESS;
927}
928
8736158a
FL
929DEFUN (show_address_vrf_all,
930 show_address_vrf_all_cmd,
9ccf14f7 931 "show address vrf all",
8736158a
FL
932 SHOW_STR
933 "address\n"
934 VRF_ALL_CMD_HELP_STR)
935{
936 struct list *intf_list;
937 struct listnode *node;
938 struct listnode *node2;
939 struct interface *ifp;
940 struct connected *ifc;
941 struct prefix *p;
942 vrf_iter_t iter;
943
944 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
945 {
946 intf_list = vrf_iter2iflist (iter);
947 if (!intf_list || !listcount (intf_list))
948 continue;
949
950 vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
951 VTY_NEWLINE, VTY_NEWLINE);
952
953 for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
954 {
955 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
956 {
957 p = ifc->address;
958
959 if (p->family == AF_INET)
960 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
961 VTY_NEWLINE);
962 }
963 }
964 }
965 return CMD_SUCCESS;
966}
967
718e3744 968/* Allocate connected structure. */
969struct connected *
8cc4198f 970connected_new (void)
718e3744 971{
393deb9b 972 return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
718e3744 973}
974
a80beece
DS
975/* Allocate nbr connected structure. */
976struct nbr_connected *
977nbr_connected_new (void)
978{
979 return XCALLOC (MTYPE_NBR_CONNECTED, sizeof (struct nbr_connected));
980}
981
718e3744 982/* Free connected structure. */
983void
984connected_free (struct connected *connected)
985{
986 if (connected->address)
987 prefix_free (connected->address);
988
989 if (connected->destination)
990 prefix_free (connected->destination);
991
992 if (connected->label)
9c4f1c6f 993 XFREE (MTYPE_CONNECTED_LABEL, connected->label);
718e3744 994
995 XFREE (MTYPE_CONNECTED, connected);
996}
997
a80beece
DS
998/* Free nbr connected structure. */
999void
1000nbr_connected_free (struct nbr_connected *connected)
1001{
1002 if (connected->address)
1003 prefix_free (connected->address);
1004
1005 XFREE (MTYPE_NBR_CONNECTED, connected);
1006}
1007
1008/* If same interface nbr address already exists... */
1009struct nbr_connected *
1010nbr_connected_check (struct interface *ifp, struct prefix *p)
1011{
1012 struct nbr_connected *ifc;
1013 struct listnode *node;
1014
1015 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, ifc))
1016 if (prefix_same (ifc->address, p))
1017 return ifc;
1018
1019 return NULL;
1020}
1021
718e3744 1022/* Print if_addr structure. */
8cc4198f 1023static void __attribute__ ((unused))
718e3744 1024connected_log (struct connected *connected, char *str)
1025{
1026 struct prefix *p;
1027 struct interface *ifp;
1028 char logbuf[BUFSIZ];
1029 char buf[BUFSIZ];
1030
1031 ifp = connected->ifp;
1032 p = connected->address;
1033
3968dbf8
FL
1034 snprintf (logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ",
1035 str, ifp->name, ifp->vrf_id, prefix_family_str (p),
718e3744 1036 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1037 p->prefixlen);
1038
1039 p = connected->destination;
1040 if (p)
1041 {
1042 strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1043 BUFSIZ - strlen(logbuf));
1044 }
fc95186c 1045 zlog (NULL, LOG_INFO, "%s", logbuf);
718e3744 1046}
1047
a80beece
DS
1048/* Print if_addr structure. */
1049static void __attribute__ ((unused))
1050nbr_connected_log (struct nbr_connected *connected, char *str)
1051{
1052 struct prefix *p;
1053 struct interface *ifp;
1054 char logbuf[BUFSIZ];
1055 char buf[BUFSIZ];
1056
1057 ifp = connected->ifp;
1058 p = connected->address;
1059
1060 snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ",
1061 str, ifp->name, prefix_family_str (p),
1062 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1063 p->prefixlen);
1064
1065 zlog (NULL, LOG_INFO, "%s", logbuf);
1066}
1067
718e3744 1068/* If two connected address has same prefix return 1. */
8cc4198f 1069static int
718e3744 1070connected_same_prefix (struct prefix *p1, struct prefix *p2)
1071{
1072 if (p1->family == p2->family)
1073 {
1074 if (p1->family == AF_INET &&
1075 IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
1076 return 1;
1077#ifdef HAVE_IPV6
1078 if (p1->family == AF_INET6 &&
1079 IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
1080 return 1;
1081#endif /* HAVE_IPV6 */
1082 }
1083 return 0;
1084}
1085
38485402
DS
1086struct connected *
1087connected_lookup_prefix_exact (struct interface *ifp, struct prefix *p)
1088{
1089 struct listnode *node;
1090 struct listnode *next;
1091 struct connected *ifc;
1092
1093 for (node = listhead (ifp->connected); node; node = next)
1094 {
1095 ifc = listgetdata (node);
1096 next = node->next;
1097
1098 if (connected_same_prefix (ifc->address, p))
1099 return ifc;
1100 }
1101 return NULL;
1102}
1103
718e3744 1104struct connected *
1105connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
1106{
1107 struct listnode *node;
1108 struct listnode *next;
1109 struct connected *ifc;
1110
1111 /* In case of same prefix come, replace it with new one. */
1112 for (node = listhead (ifp->connected); node; node = next)
1113 {
1eb8ef25 1114 ifc = listgetdata (node);
718e3744 1115 next = node->next;
1116
1117 if (connected_same_prefix (ifc->address, p))
1118 {
1119 listnode_delete (ifp->connected, ifc);
1120 return ifc;
1121 }
1122 }
1123 return NULL;
1124}
1125
bd40c341 1126/* Find the address on our side that will be used when packets
727d104b 1127 are sent to dst. */
1128struct connected *
bd40c341 1129connected_lookup_prefix (struct interface *ifp, struct prefix *addr)
727d104b 1130{
52dc7ee6 1131 struct listnode *cnode;
727d104b 1132 struct connected *c;
1133 struct connected *match;
1134
727d104b 1135 match = NULL;
1136
1eb8ef25 1137 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
727d104b 1138 {
bd40c341
DS
1139 if (c->address && (c->address->family == addr->family) &&
1140 prefix_match(CONNECTED_PREFIX(c), addr) &&
e4529636
AS
1141 (!match || (c->address->prefixlen > match->address->prefixlen)))
1142 match = c;
727d104b 1143 }
1144 return match;
1145}
1146
4a7aac1b 1147struct connected *
1148connected_add_by_prefix (struct interface *ifp, struct prefix *p,
1149 struct prefix *destination)
1150{
1151 struct connected *ifc;
1152
1153 /* Allocate new connected address. */
1154 ifc = connected_new ();
1155 ifc->ifp = ifp;
1156
1157 /* Fetch interface address */
1158 ifc->address = prefix_new();
1159 memcpy (ifc->address, p, sizeof(struct prefix));
1160
1161 /* Fetch dest address */
3fb9cd6e 1162 if (destination)
1163 {
1164 ifc->destination = prefix_new();
1165 memcpy (ifc->destination, destination, sizeof(struct prefix));
1166 }
4a7aac1b 1167
1168 /* Add connected address to the interface. */
1169 listnode_add (ifp->connected, ifc);
1170 return ifc;
1171}
1172
718e3744 1173#ifndef HAVE_IF_NAMETOINDEX
b892f1dd 1174ifindex_t
718e3744 1175if_nametoindex (const char *name)
1176{
718e3744 1177 struct interface *ifp;
1178
018546e9 1179 return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
1180 ? ifp->ifindex : 0;
718e3744 1181}
1182#endif
1183
1184#ifndef HAVE_IF_INDEXTONAME
1185char *
b892f1dd 1186if_indextoname (ifindex_t ifindex, char *name)
718e3744 1187{
718e3744 1188 struct interface *ifp;
1189
d2fc8896 1190 if (!(ifp = if_lookup_by_index(ifindex)))
1191 return NULL;
1192 strncpy (name, ifp->name, IFNAMSIZ);
1193 return ifp->name;
718e3744 1194}
1195#endif
6b0655a2 1196
8cc4198f 1197#if 0 /* this route_table of struct connected's is unused
1198 * however, it would be good to use a route_table rather than
1199 * a list..
1200 */
718e3744 1201/* Interface looking up by interface's address. */
718e3744 1202/* Interface's IPv4 address reverse lookup table. */
1203struct route_table *ifaddr_ipv4_table;
1204/* struct route_table *ifaddr_ipv6_table; */
1205
8cc4198f 1206static void
718e3744 1207ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
1208{
1209 struct route_node *rn;
1210 struct prefix_ipv4 p;
1211
1212 p.family = AF_INET;
1213 p.prefixlen = IPV4_MAX_PREFIXLEN;
1214 p.prefix = *ifaddr;
1215
1216 rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
1217 if (rn)
1218 {
1219 route_unlock_node (rn);
1220 zlog_info ("ifaddr_ipv4_add(): address %s is already added",
1221 inet_ntoa (*ifaddr));
1222 return;
1223 }
1224 rn->info = ifp;
1225}
1226
8cc4198f 1227static void
718e3744 1228ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
1229{
1230 struct route_node *rn;
1231 struct prefix_ipv4 p;
1232
1233 p.family = AF_INET;
1234 p.prefixlen = IPV4_MAX_PREFIXLEN;
1235 p.prefix = *ifaddr;
1236
1237 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1238 if (! rn)
1239 {
1240 zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
1241 inet_ntoa (*ifaddr));
1242 return;
1243 }
1244 rn->info = NULL;
1245 route_unlock_node (rn);
1246 route_unlock_node (rn);
1247}
1248
1249/* Lookup interface by interface's IP address or interface index. */
8cc4198f 1250static struct interface *
b892f1dd 1251ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
718e3744 1252{
1253 struct prefix_ipv4 p;
1254 struct route_node *rn;
1255 struct interface *ifp;
718e3744 1256
1257 if (addr)
1258 {
1259 p.family = AF_INET;
1260 p.prefixlen = IPV4_MAX_PREFIXLEN;
1261 p.prefix = *addr;
1262
1263 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1264 if (! rn)
1265 return NULL;
1266
1267 ifp = rn->info;
1268 route_unlock_node (rn);
1269 return ifp;
1270 }
1271 else
d2fc8896 1272 return if_lookup_by_index(ifindex);
718e3744 1273}
8cc4198f 1274#endif /* ifaddr_ipv4_table */
718e3744 1275
1276/* Initialize interface list. */
1277void
b2d7c082 1278if_init (struct list **intf_list)
718e3744 1279{
8736158a 1280 *intf_list = list_new ();
8cc4198f 1281#if 0
718e3744 1282 ifaddr_ipv4_table = route_table_init ();
8cc4198f 1283#endif /* ifaddr_ipv4_table */
718e3744 1284
8736158a 1285 (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
718e3744 1286}
4bd045d5
TG
1287
1288void
b2d7c082 1289if_terminate (struct list **intf_list)
4bd045d5
TG
1290{
1291 for (;;)
1292 {
1293 struct interface *ifp;
1294
8736158a 1295 ifp = listnode_head (*intf_list);
4bd045d5
TG
1296 if (ifp == NULL)
1297 break;
1298
3f6d6a5d
DS
1299 if (ifp->node)
1300 {
1301 ifp->node->info = NULL;
1302 route_unlock_node (ifp->node);
1303 }
1304
4bd045d5
TG
1305 if_delete (ifp);
1306 }
1307
8736158a
FL
1308 list_delete (*intf_list);
1309 *intf_list = NULL;
4bd045d5 1310}
8ccc7e80
TT
1311
1312const char *
1313if_link_type_str (enum zebra_link_type llt)
1314{
1315 switch (llt)
1316 {
1317#define llts(T,S) case (T): return (S)
1318 llts(ZEBRA_LLT_UNKNOWN, "Unknown");
1319 llts(ZEBRA_LLT_ETHER, "Ethernet");
1320 llts(ZEBRA_LLT_EETHER, "Experimental Ethernet");
1321 llts(ZEBRA_LLT_AX25, "AX.25 Level 2");
1322 llts(ZEBRA_LLT_PRONET, "PROnet token ring");
1323 llts(ZEBRA_LLT_IEEE802, "IEEE 802.2 Ethernet/TR/TB");
1324 llts(ZEBRA_LLT_ARCNET, "ARCnet");
1325 llts(ZEBRA_LLT_APPLETLK, "AppleTalk");
1326 llts(ZEBRA_LLT_DLCI, "Frame Relay DLCI");
1327 llts(ZEBRA_LLT_ATM, "ATM");
1328 llts(ZEBRA_LLT_METRICOM, "Metricom STRIP");
1329 llts(ZEBRA_LLT_IEEE1394, "IEEE 1394 IPv4");
1330 llts(ZEBRA_LLT_EUI64, "EUI-64");
1331 llts(ZEBRA_LLT_INFINIBAND, "InfiniBand");
1332 llts(ZEBRA_LLT_SLIP, "SLIP");
1333 llts(ZEBRA_LLT_CSLIP, "Compressed SLIP");
1334 llts(ZEBRA_LLT_SLIP6, "SLIPv6");
1335 llts(ZEBRA_LLT_CSLIP6, "Compressed SLIPv6");
1336 llts(ZEBRA_LLT_ROSE, "ROSE packet radio");
1337 llts(ZEBRA_LLT_X25, "CCITT X.25");
1338 llts(ZEBRA_LLT_PPP, "PPP");
1339 llts(ZEBRA_LLT_CHDLC, "Cisco HDLC");
1340 llts(ZEBRA_LLT_RAWHDLC, "Raw HDLC");
1341 llts(ZEBRA_LLT_LAPB, "LAPB");
1342 llts(ZEBRA_LLT_IPIP, "IPIP Tunnel");
1343 llts(ZEBRA_LLT_IPIP6, "IPIP6 Tunnel");
1344 llts(ZEBRA_LLT_FRAD, "FRAD");
1345 llts(ZEBRA_LLT_SKIP, "SKIP vif");
1346 llts(ZEBRA_LLT_LOOPBACK, "Loopback");
1347 llts(ZEBRA_LLT_LOCALTLK, "Localtalk");
1348 llts(ZEBRA_LLT_FDDI, "FDDI");
1349 llts(ZEBRA_LLT_SIT, "IPv6-in-IPv4 SIT");
1350 llts(ZEBRA_LLT_IPDDP, "IP-in-DDP tunnel");
1351 llts(ZEBRA_LLT_IPGRE, "GRE over IP");
1352 llts(ZEBRA_LLT_PIMREG, "PIMSM registration");
1353 llts(ZEBRA_LLT_HIPPI, "HiPPI");
1354 llts(ZEBRA_LLT_IRDA, "IrDA");
1355 llts(ZEBRA_LLT_FCPP, "Fibre-Channel PtP");
1356 llts(ZEBRA_LLT_FCAL, "Fibre-Channel Arbitrated Loop");
1357 llts(ZEBRA_LLT_FCPL, "Fibre-Channel Public Loop");
1358 llts(ZEBRA_LLT_FCFABRIC, "Fibre-Channel Fabric");
1359 llts(ZEBRA_LLT_IEEE802_TR, "IEEE 802.2 Token Ring");
1360 llts(ZEBRA_LLT_IEEE80211, "IEEE 802.11");
1361 llts(ZEBRA_LLT_IEEE80211_RADIOTAP, "IEEE 802.11 Radiotap");
1362 llts(ZEBRA_LLT_IEEE802154, "IEEE 802.15.4");
1363 llts(ZEBRA_LLT_IEEE802154_PHY, "IEEE 802.15.4 Phy");
1364 default:
1365 zlog_warn ("Unknown value %d", llt);
1366 return "Unknown type!";
1367#undef llts
1368 }
1369 return NULL;
1370}
16f1b9ee
OD
1371
1372struct if_link_params *
1373if_link_params_get (struct interface *ifp)
1374{
1375 int i;
1376
1377 if (ifp->link_params != NULL)
1378 return ifp->link_params;
1379
1380 struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
1381 sizeof (struct if_link_params));
1382 if (iflp == NULL) return NULL;
1383
1384 /* Set TE metric == standard metric */
1385 iflp->te_metric = ifp->metric;
1386
1387 /* Compute default bandwidth based on interface */
1388 int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
1389 * TE_KILO_BIT / TE_BYTE);
1390
1391 /* Set Max, Reservable and Unreserved Bandwidth */
1392 iflp->max_bw = bw;
1393 iflp->max_rsv_bw = bw;
1394 for (i = 0; i < MAX_CLASS_TYPE; i++)
1395 iflp->unrsv_bw[i] = bw;
1396
1397 /* Update Link parameters status */
1398 iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
1399
1400 /* Finally attach newly created Link Parameters */
1401 ifp->link_params = iflp;
1402
1403 return iflp;
1404}
1405
1406void
1407if_link_params_free (struct interface *ifp)
1408{
1409 if (ifp->link_params == NULL) return;
1410 XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
1411 ifp->link_params = NULL;
1412}