]> git.proxmox.com Git - mirror_frr.git/blob - lib/if.c
Merge branch 'cmaster-next-isisd-bpf' into cmaster-next-releng
[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 VTY_DECLVAR_CONTEXT (interface, ifp);
686
687 if (argc == 0)
688 return CMD_SUCCESS;
689
690 if (ifp->desc)
691 XFREE (MTYPE_TMP, ifp->desc);
692 ifp->desc = argv_concat(argv, argc, 0);
693
694 return CMD_SUCCESS;
695 }
696
697 DEFUN (no_interface_desc,
698 no_interface_desc_cmd,
699 "no description",
700 NO_STR
701 "Interface specific description\n")
702 {
703 VTY_DECLVAR_CONTEXT (interface, ifp);
704
705 if (ifp->desc)
706 XFREE (MTYPE_TMP, ifp->desc);
707 ifp->desc = NULL;
708
709 return CMD_SUCCESS;
710 }
711
712 #ifdef SUNOS_5
713 /* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created
714 * a seperate struct interface for each logical interface, so config
715 * file may be full of 'interface fooX:Y'. Solaris however does not
716 * expose logical interfaces via PF_ROUTE, so trying to track logical
717 * interfaces can be fruitless, for that reason Quagga only tracks
718 * the primary IP interface.
719 *
720 * We try accomodate SUNWzebra by:
721 * - looking up the interface name, to see whether it exists, if so
722 * its useable
723 * - for protocol daemons, this could only because zebra told us of
724 * the interface
725 * - for zebra, only because it learnt from kernel
726 * - if not:
727 * - search the name to see if it contains a sub-ipif / logical interface
728 * seperator, the ':' char. If it does:
729 * - text up to that char must be the primary name - get that name.
730 * if not:
731 * - no idea, just get the name in its entirety.
732 */
733 static struct interface *
734 if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
735 {
736 struct interface *ifp;
737 size_t seppos = 0;
738
739 if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
740 return ifp;
741
742 /* hunt the primary interface name... */
743 while (seppos < nlen && name[seppos] != ':')
744 seppos++;
745
746 /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
747 if (seppos < nlen)
748 return if_get_by_name_len_vrf (name, seppos, vrf_id, 1);
749 else
750 return if_get_by_name_len_vrf (name, nlen, vrf_id, 1);
751 }
752 #endif /* SUNOS_5 */
753
754 DEFUN (interface,
755 interface_cmd,
756 "interface IFNAME",
757 "Select an interface to configure\n"
758 "Interface's name\n")
759 {
760 struct interface *ifp;
761 size_t sl;
762 vrf_id_t vrf_id = VRF_DEFAULT;
763
764 if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
765 {
766 vty_out (vty, "%% Interface name %s is invalid: length exceeds "
767 "%d characters%s",
768 argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
769 return CMD_WARNING;
770 }
771
772 /*Pending: need proper vrf name based lookup/(possible creation of VRF)
773 Imagine forward reference of a vrf by name in this interface config */
774 if (argc > 1)
775 VRF_GET_ID (vrf_id, argv[1]);
776
777 #ifdef SUNOS_5
778 ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
779 #else
780 ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id, 1);
781 #endif /* SUNOS_5 */
782
783 if (!ifp)
784 {
785 vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE);
786 return CMD_WARNING;
787 }
788 VTY_PUSH_CONTEXT_COMPAT (INTERFACE_NODE, ifp);
789
790 return CMD_SUCCESS;
791 }
792
793 ALIAS (interface,
794 interface_vrf_cmd,
795 "interface IFNAME " VRF_CMD_STR,
796 "Select an interface to configure\n"
797 "Interface's name\n"
798 VRF_CMD_HELP_STR)
799
800 DEFUN_NOSH (no_interface,
801 no_interface_cmd,
802 "no interface IFNAME",
803 NO_STR
804 "Delete a pseudo interface's configuration\n"
805 "Interface's name\n")
806 {
807 // deleting interface
808 struct interface *ifp;
809 vrf_id_t vrf_id = VRF_DEFAULT;
810
811 if (argc > 1)
812 VRF_GET_ID (vrf_id, argv[1]);
813
814 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
815
816 if (ifp == NULL)
817 {
818 vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
819 return CMD_WARNING;
820 }
821
822 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
823 {
824 vty_out (vty, "%% Only inactive interfaces can be deleted%s",
825 VTY_NEWLINE);
826 return CMD_WARNING;
827 }
828
829 if_delete(ifp);
830
831 return CMD_SUCCESS;
832 }
833
834 ALIAS (no_interface,
835 no_interface_vrf_cmd,
836 "no interface IFNAME " VRF_CMD_STR,
837 NO_STR
838 "Delete a pseudo interface's configuration\n"
839 "Interface's name\n"
840 VRF_CMD_HELP_STR)
841
842 DEFUN (vrf,
843 vrf_cmd,
844 "vrf NAME",
845 "Select a VRF to configure\n"
846 "VRF's name\n")
847 {
848 struct vrf *vrfp;
849 size_t sl;
850
851 if ((sl = strlen(argv[0])) > VRF_NAMSIZ)
852 {
853 vty_out (vty, "%% VRF name %s is invalid: length exceeds "
854 "%d characters%s",
855 argv[0], VRF_NAMSIZ, VTY_NEWLINE);
856 return CMD_WARNING;
857 }
858
859 vrfp = vrf_get (VRF_UNKNOWN, argv[0]);
860
861 VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp);
862
863 return CMD_SUCCESS;
864 }
865
866 DEFUN_NOSH (no_vrf,
867 no_vrf_cmd,
868 "no vrf NAME",
869 NO_STR
870 "Delete a pseudo VRF's configuration\n"
871 "VRF's name\n")
872 {
873 struct vrf *vrfp;
874
875 vrfp = vrf_list_lookup_by_name (argv[0]);
876
877 if (vrfp == NULL)
878 {
879 vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE);
880 return CMD_WARNING;
881 }
882
883 if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
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
896 /* For debug purpose. */
897 DEFUN (show_address,
898 show_address_cmd,
899 "show address",
900 SHOW_STR
901 "address\n")
902 {
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 > 0)
911 VRF_GET_ID (vrf_id, argv[0]);
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 ALIAS (show_address,
928 show_address_vrf_cmd,
929 "show address " VRF_CMD_STR,
930 SHOW_STR
931 "address\n"
932 VRF_CMD_HELP_STR)
933
934 DEFUN (show_address_vrf_all,
935 show_address_vrf_all_cmd,
936 "show address " VRF_ALL_CMD_STR,
937 SHOW_STR
938 "address\n"
939 VRF_ALL_CMD_HELP_STR)
940 {
941 struct list *intf_list;
942 struct listnode *node;
943 struct listnode *node2;
944 struct interface *ifp;
945 struct connected *ifc;
946 struct prefix *p;
947 vrf_iter_t iter;
948
949 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
950 {
951 intf_list = vrf_iter2iflist (iter);
952 if (!intf_list || !listcount (intf_list))
953 continue;
954
955 vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
956 VTY_NEWLINE, VTY_NEWLINE);
957
958 for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
959 {
960 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
961 {
962 p = ifc->address;
963
964 if (p->family == AF_INET)
965 vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
966 VTY_NEWLINE);
967 }
968 }
969 }
970 return CMD_SUCCESS;
971 }
972
973 /* Allocate connected structure. */
974 struct connected *
975 connected_new (void)
976 {
977 return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected));
978 }
979
980 /* Allocate nbr connected structure. */
981 struct nbr_connected *
982 nbr_connected_new (void)
983 {
984 return XCALLOC (MTYPE_NBR_CONNECTED, sizeof (struct nbr_connected));
985 }
986
987 /* Free connected structure. */
988 void
989 connected_free (struct connected *connected)
990 {
991 if (connected->address)
992 prefix_free (connected->address);
993
994 if (connected->destination)
995 prefix_free (connected->destination);
996
997 if (connected->label)
998 XFREE (MTYPE_CONNECTED_LABEL, connected->label);
999
1000 XFREE (MTYPE_CONNECTED, connected);
1001 }
1002
1003 /* Free nbr connected structure. */
1004 void
1005 nbr_connected_free (struct nbr_connected *connected)
1006 {
1007 if (connected->address)
1008 prefix_free (connected->address);
1009
1010 XFREE (MTYPE_NBR_CONNECTED, connected);
1011 }
1012
1013 /* If same interface nbr address already exists... */
1014 struct nbr_connected *
1015 nbr_connected_check (struct interface *ifp, struct prefix *p)
1016 {
1017 struct nbr_connected *ifc;
1018 struct listnode *node;
1019
1020 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, ifc))
1021 if (prefix_same (ifc->address, p))
1022 return ifc;
1023
1024 return NULL;
1025 }
1026
1027 /* Print if_addr structure. */
1028 static void __attribute__ ((unused))
1029 connected_log (struct connected *connected, char *str)
1030 {
1031 struct prefix *p;
1032 struct interface *ifp;
1033 char logbuf[BUFSIZ];
1034 char buf[BUFSIZ];
1035
1036 ifp = connected->ifp;
1037 p = connected->address;
1038
1039 snprintf (logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ",
1040 str, ifp->name, ifp->vrf_id, prefix_family_str (p),
1041 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1042 p->prefixlen);
1043
1044 p = connected->destination;
1045 if (p)
1046 {
1047 strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1048 BUFSIZ - strlen(logbuf));
1049 }
1050 zlog (NULL, LOG_INFO, "%s", logbuf);
1051 }
1052
1053 /* Print if_addr structure. */
1054 static void __attribute__ ((unused))
1055 nbr_connected_log (struct nbr_connected *connected, char *str)
1056 {
1057 struct prefix *p;
1058 struct interface *ifp;
1059 char logbuf[BUFSIZ];
1060 char buf[BUFSIZ];
1061
1062 ifp = connected->ifp;
1063 p = connected->address;
1064
1065 snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ",
1066 str, ifp->name, prefix_family_str (p),
1067 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1068 p->prefixlen);
1069
1070 zlog (NULL, LOG_INFO, "%s", logbuf);
1071 }
1072
1073 /* If two connected address has same prefix return 1. */
1074 static int
1075 connected_same_prefix (struct prefix *p1, struct prefix *p2)
1076 {
1077 if (p1->family == p2->family)
1078 {
1079 if (p1->family == AF_INET &&
1080 IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
1081 return 1;
1082 #ifdef HAVE_IPV6
1083 if (p1->family == AF_INET6 &&
1084 IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
1085 return 1;
1086 #endif /* HAVE_IPV6 */
1087 }
1088 return 0;
1089 }
1090
1091 struct connected *
1092 connected_lookup_prefix_exact (struct interface *ifp, struct prefix *p)
1093 {
1094 struct listnode *node;
1095 struct listnode *next;
1096 struct connected *ifc;
1097
1098 for (node = listhead (ifp->connected); node; node = next)
1099 {
1100 ifc = listgetdata (node);
1101 next = node->next;
1102
1103 if (connected_same_prefix (ifc->address, p))
1104 return ifc;
1105 }
1106 return NULL;
1107 }
1108
1109 struct connected *
1110 connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
1111 {
1112 struct listnode *node;
1113 struct listnode *next;
1114 struct connected *ifc;
1115
1116 /* In case of same prefix come, replace it with new one. */
1117 for (node = listhead (ifp->connected); node; node = next)
1118 {
1119 ifc = listgetdata (node);
1120 next = node->next;
1121
1122 if (connected_same_prefix (ifc->address, p))
1123 {
1124 listnode_delete (ifp->connected, ifc);
1125 return ifc;
1126 }
1127 }
1128 return NULL;
1129 }
1130
1131 /* Find the address on our side that will be used when packets
1132 are sent to dst. */
1133 struct connected *
1134 connected_lookup_prefix (struct interface *ifp, struct prefix *addr)
1135 {
1136 struct listnode *cnode;
1137 struct connected *c;
1138 struct connected *match;
1139
1140 match = NULL;
1141
1142 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
1143 {
1144 if (c->address && (c->address->family == addr->family) &&
1145 prefix_match(CONNECTED_PREFIX(c), addr) &&
1146 (!match || (c->address->prefixlen > match->address->prefixlen)))
1147 match = c;
1148 }
1149 return match;
1150 }
1151
1152 struct connected *
1153 connected_add_by_prefix (struct interface *ifp, struct prefix *p,
1154 struct prefix *destination)
1155 {
1156 struct connected *ifc;
1157
1158 /* Allocate new connected address. */
1159 ifc = connected_new ();
1160 ifc->ifp = ifp;
1161
1162 /* Fetch interface address */
1163 ifc->address = prefix_new();
1164 memcpy (ifc->address, p, sizeof(struct prefix));
1165
1166 /* Fetch dest address */
1167 if (destination)
1168 {
1169 ifc->destination = prefix_new();
1170 memcpy (ifc->destination, destination, sizeof(struct prefix));
1171 }
1172
1173 /* Add connected address to the interface. */
1174 listnode_add (ifp->connected, ifc);
1175 return ifc;
1176 }
1177
1178 #if 0 /* this route_table of struct connected's is unused
1179 * however, it would be good to use a route_table rather than
1180 * a list..
1181 */
1182 /* Interface looking up by interface's address. */
1183 /* Interface's IPv4 address reverse lookup table. */
1184 struct route_table *ifaddr_ipv4_table;
1185 /* struct route_table *ifaddr_ipv6_table; */
1186
1187 static void
1188 ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
1189 {
1190 struct route_node *rn;
1191 struct prefix_ipv4 p;
1192
1193 p.family = AF_INET;
1194 p.prefixlen = IPV4_MAX_PREFIXLEN;
1195 p.prefix = *ifaddr;
1196
1197 rn = route_node_get (ifaddr_ipv4_table, (struct prefix *) &p);
1198 if (rn)
1199 {
1200 route_unlock_node (rn);
1201 zlog_info ("ifaddr_ipv4_add(): address %s is already added",
1202 inet_ntoa (*ifaddr));
1203 return;
1204 }
1205 rn->info = ifp;
1206 }
1207
1208 static void
1209 ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
1210 {
1211 struct route_node *rn;
1212 struct prefix_ipv4 p;
1213
1214 p.family = AF_INET;
1215 p.prefixlen = IPV4_MAX_PREFIXLEN;
1216 p.prefix = *ifaddr;
1217
1218 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1219 if (! rn)
1220 {
1221 zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
1222 inet_ntoa (*ifaddr));
1223 return;
1224 }
1225 rn->info = NULL;
1226 route_unlock_node (rn);
1227 route_unlock_node (rn);
1228 }
1229
1230 /* Lookup interface by interface's IP address or interface index. */
1231 static struct interface *
1232 ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
1233 {
1234 struct prefix_ipv4 p;
1235 struct route_node *rn;
1236 struct interface *ifp;
1237
1238 if (addr)
1239 {
1240 p.family = AF_INET;
1241 p.prefixlen = IPV4_MAX_PREFIXLEN;
1242 p.prefix = *addr;
1243
1244 rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
1245 if (! rn)
1246 return NULL;
1247
1248 ifp = rn->info;
1249 route_unlock_node (rn);
1250 return ifp;
1251 }
1252 else
1253 return if_lookup_by_index(ifindex);
1254 }
1255 #endif /* ifaddr_ipv4_table */
1256
1257 /* Initialize interface list. */
1258 void
1259 if_init (struct list **intf_list)
1260 {
1261 *intf_list = list_new ();
1262 #if 0
1263 ifaddr_ipv4_table = route_table_init ();
1264 #endif /* ifaddr_ipv4_table */
1265
1266 (*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
1267 }
1268
1269 void
1270 if_terminate (struct list **intf_list)
1271 {
1272 for (;;)
1273 {
1274 struct interface *ifp;
1275
1276 ifp = listnode_head (*intf_list);
1277 if (ifp == NULL)
1278 break;
1279
1280 if (ifp->node)
1281 {
1282 ifp->node->info = NULL;
1283 route_unlock_node (ifp->node);
1284 }
1285
1286 if_delete (ifp);
1287 }
1288
1289 list_delete (*intf_list);
1290 *intf_list = NULL;
1291 }
1292
1293 const char *
1294 if_link_type_str (enum zebra_link_type llt)
1295 {
1296 switch (llt)
1297 {
1298 #define llts(T,S) case (T): return (S)
1299 llts(ZEBRA_LLT_UNKNOWN, "Unknown");
1300 llts(ZEBRA_LLT_ETHER, "Ethernet");
1301 llts(ZEBRA_LLT_EETHER, "Experimental Ethernet");
1302 llts(ZEBRA_LLT_AX25, "AX.25 Level 2");
1303 llts(ZEBRA_LLT_PRONET, "PROnet token ring");
1304 llts(ZEBRA_LLT_IEEE802, "IEEE 802.2 Ethernet/TR/TB");
1305 llts(ZEBRA_LLT_ARCNET, "ARCnet");
1306 llts(ZEBRA_LLT_APPLETLK, "AppleTalk");
1307 llts(ZEBRA_LLT_DLCI, "Frame Relay DLCI");
1308 llts(ZEBRA_LLT_ATM, "ATM");
1309 llts(ZEBRA_LLT_METRICOM, "Metricom STRIP");
1310 llts(ZEBRA_LLT_IEEE1394, "IEEE 1394 IPv4");
1311 llts(ZEBRA_LLT_EUI64, "EUI-64");
1312 llts(ZEBRA_LLT_INFINIBAND, "InfiniBand");
1313 llts(ZEBRA_LLT_SLIP, "SLIP");
1314 llts(ZEBRA_LLT_CSLIP, "Compressed SLIP");
1315 llts(ZEBRA_LLT_SLIP6, "SLIPv6");
1316 llts(ZEBRA_LLT_CSLIP6, "Compressed SLIPv6");
1317 llts(ZEBRA_LLT_ROSE, "ROSE packet radio");
1318 llts(ZEBRA_LLT_X25, "CCITT X.25");
1319 llts(ZEBRA_LLT_PPP, "PPP");
1320 llts(ZEBRA_LLT_CHDLC, "Cisco HDLC");
1321 llts(ZEBRA_LLT_RAWHDLC, "Raw HDLC");
1322 llts(ZEBRA_LLT_LAPB, "LAPB");
1323 llts(ZEBRA_LLT_IPIP, "IPIP Tunnel");
1324 llts(ZEBRA_LLT_IPIP6, "IPIP6 Tunnel");
1325 llts(ZEBRA_LLT_FRAD, "FRAD");
1326 llts(ZEBRA_LLT_SKIP, "SKIP vif");
1327 llts(ZEBRA_LLT_LOOPBACK, "Loopback");
1328 llts(ZEBRA_LLT_LOCALTLK, "Localtalk");
1329 llts(ZEBRA_LLT_FDDI, "FDDI");
1330 llts(ZEBRA_LLT_SIT, "IPv6-in-IPv4 SIT");
1331 llts(ZEBRA_LLT_IPDDP, "IP-in-DDP tunnel");
1332 llts(ZEBRA_LLT_IPGRE, "GRE over IP");
1333 llts(ZEBRA_LLT_PIMREG, "PIMSM registration");
1334 llts(ZEBRA_LLT_HIPPI, "HiPPI");
1335 llts(ZEBRA_LLT_IRDA, "IrDA");
1336 llts(ZEBRA_LLT_FCPP, "Fibre-Channel PtP");
1337 llts(ZEBRA_LLT_FCAL, "Fibre-Channel Arbitrated Loop");
1338 llts(ZEBRA_LLT_FCPL, "Fibre-Channel Public Loop");
1339 llts(ZEBRA_LLT_FCFABRIC, "Fibre-Channel Fabric");
1340 llts(ZEBRA_LLT_IEEE802_TR, "IEEE 802.2 Token Ring");
1341 llts(ZEBRA_LLT_IEEE80211, "IEEE 802.11");
1342 llts(ZEBRA_LLT_IEEE80211_RADIOTAP, "IEEE 802.11 Radiotap");
1343 llts(ZEBRA_LLT_IEEE802154, "IEEE 802.15.4");
1344 llts(ZEBRA_LLT_IEEE802154_PHY, "IEEE 802.15.4 Phy");
1345 default:
1346 zlog_warn ("Unknown value %d", llt);
1347 return "Unknown type!";
1348 #undef llts
1349 }
1350 return NULL;
1351 }
1352
1353 struct if_link_params *
1354 if_link_params_get (struct interface *ifp)
1355 {
1356 int i;
1357
1358 if (ifp->link_params != NULL)
1359 return ifp->link_params;
1360
1361 struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
1362 sizeof (struct if_link_params));
1363 if (iflp == NULL) return NULL;
1364
1365 /* Set TE metric == standard metric */
1366 iflp->te_metric = ifp->metric;
1367
1368 /* Compute default bandwidth based on interface */
1369 int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
1370 * TE_KILO_BIT / TE_BYTE);
1371
1372 /* Set Max, Reservable and Unreserved Bandwidth */
1373 iflp->max_bw = bw;
1374 iflp->max_rsv_bw = bw;
1375 for (i = 0; i < MAX_CLASS_TYPE; i++)
1376 iflp->unrsv_bw[i] = bw;
1377
1378 /* Update Link parameters status */
1379 iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
1380
1381 /* Finally attach newly created Link Parameters */
1382 ifp->link_params = iflp;
1383
1384 return iflp;
1385 }
1386
1387 void
1388 if_link_params_free (struct interface *ifp)
1389 {
1390 if (ifp->link_params == NULL) return;
1391 XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
1392 ifp->link_params = NULL;
1393 }