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