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