1: /*
2: * Interface function.
3: * Copyright (C) 1997, 1999 Kunihiro Ishiguro
4: *
5: * This file is part of GNU Zebra.
6: *
7: * GNU Zebra is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2, or (at your option) any
10: * later version.
11: *
12: * GNU Zebra is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with GNU Zebra; see the file COPYING. If not, write to the Free
19: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20: * 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #include "if.h"
26: #include "vty.h"
27: #include "sockunion.h"
28: #include "prefix.h"
29: #include "command.h"
30: #include "memory.h"
31: #include "ioctl.h"
32: #include "connected.h"
33: #include "log.h"
34: #include "zclient.h"
35: #include "vrf.h"
36:
37: #include "zebra/interface.h"
38: #include "zebra/rtadv.h"
39: #include "zebra/rib.h"
40: #include "zebra/zserv.h"
41: #include "zebra/redistribute.h"
42: #include "zebra/debug.h"
43: #include "zebra/irdp.h"
44:
45: #if defined (HAVE_RTADV)
46: /* Order is intentional. Matches RFC4191. This array is also used for
47: command matching, so only modify with care. */
48: const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
49: #endif /* HAVE_RTADV */
50:
51: /* Called when new interface is added. */
52: static int
53: if_zebra_new_hook (struct interface *ifp)
54: {
55: struct zebra_if *zebra_if;
56:
57: zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
58:
59: zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
60: zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
61:
62: #if defined (HAVE_RTADV)
63: {
64: /* Set default router advertise values. */
65: struct rtadvconf *rtadv;
66:
67: rtadv = &zebra_if->rtadv;
68:
69: rtadv->AdvSendAdvertisements = 0;
70: rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
71: rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
72: rtadv->AdvIntervalTimer = 0;
73: rtadv->AdvManagedFlag = 0;
74: rtadv->AdvOtherConfigFlag = 0;
75: rtadv->AdvHomeAgentFlag = 0;
76: rtadv->AdvLinkMTU = 0;
77: rtadv->AdvReachableTime = 0;
78: rtadv->AdvRetransTimer = 0;
79: rtadv->AdvCurHopLimit = 0;
80: rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
81: rtadv->HomeAgentPreference = 0;
82: rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
83: rtadv->AdvIntervalOption = 0;
84: rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
85:
86: rtadv->AdvPrefixList = list_new ();
87: }
88: #endif /* HAVE_RTADV */
89:
90: /* Initialize installed address chains tree. */
91: zebra_if->ipv4_subnets = route_table_init ();
92:
93: ifp->info = zebra_if;
94: return 0;
95: }
96:
97: /* Called when interface is deleted. */
98: static int
99: if_zebra_delete_hook (struct interface *ifp)
100: {
101: struct zebra_if *zebra_if;
102:
103: if (ifp->info)
104: {
105: zebra_if = ifp->info;
106:
107: /* Free installed address chains tree. */
108: if (zebra_if->ipv4_subnets)
109: route_table_finish (zebra_if->ipv4_subnets);
110:
111: XFREE (MTYPE_TMP, zebra_if);
112: }
113:
114: return 0;
115: }
116:
117: /* Tie an interface address to its derived subnet list of addresses. */
118: int
119: if_subnet_add (struct interface *ifp, struct connected *ifc)
120: {
121: struct route_node *rn;
122: struct zebra_if *zebra_if;
123: struct prefix cp;
124: struct list *addr_list;
125:
126: assert (ifp && ifp->info && ifc);
127: zebra_if = ifp->info;
128:
129: /* Get address derived subnet node and associated address list, while marking
130: address secondary attribute appropriately. */
131: cp = *ifc->address;
132: apply_mask (&cp);
133: rn = route_node_get (zebra_if->ipv4_subnets, &cp);
134:
135: if ((addr_list = rn->info))
136: SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
137: else
138: {
139: UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
140: rn->info = addr_list = list_new ();
141: route_lock_node (rn);
142: }
143:
144: /* Tie address at the tail of address list. */
145: listnode_add (addr_list, ifc);
146:
147: /* Return list element count. */
148: return (addr_list->count);
149: }
150:
151: /* Untie an interface address from its derived subnet list of addresses. */
152: int
153: if_subnet_delete (struct interface *ifp, struct connected *ifc)
154: {
155: struct route_node *rn;
156: struct zebra_if *zebra_if;
157: struct list *addr_list;
158:
159: assert (ifp && ifp->info && ifc);
160: zebra_if = ifp->info;
161:
162: /* Get address derived subnet node. */
163: rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
164: if (! (rn && rn->info))
165: {
166: zlog_warn("Trying to remove an address from an unknown subnet."
167: " (please report this bug)");
168: return -1;
169: }
170: route_unlock_node (rn);
171:
172: /* Untie address from subnet's address list. */
173: addr_list = rn->info;
174:
175: /* Deleting an address that is not registered is a bug.
176: * In any case, we shouldn't decrement the lock counter if the address
177: * is unknown. */
178: if (!listnode_lookup(addr_list, ifc))
179: {
180: zlog_warn("Trying to remove an address from a subnet where it is not"
181: " currently registered. (please report this bug)");
182: return -1;
183: }
184:
185: listnode_delete (addr_list, ifc);
186: route_unlock_node (rn);
187:
188: /* Return list element count, if not empty. */
189: if (addr_list->count)
190: {
191: /* If deleted address is primary, mark subsequent one as such and distribute. */
192: if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
193: {
194: ifc = listgetdata (listhead (addr_list));
195: zebra_interface_address_delete_update (ifp, ifc);
196: UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
197: /* XXX: Linux kernel removes all the secondary addresses when the primary
198: * address is removed. We could try to work around that, though this is
199: * non-trivial. */
200: zebra_interface_address_add_update (ifp, ifc);
201: }
202:
203: return addr_list->count;
204: }
205:
206: /* Otherwise, free list and route node. */
207: list_free (addr_list);
208: rn->info = NULL;
209: route_unlock_node (rn);
210:
211: return 0;
212: }
213:
214: /* if_flags_mangle: A place for hacks that require mangling
215: * or tweaking the interface flags.
216: *
217: * ******************** Solaris flags hacks **************************
218: *
219: * Solaris IFF_UP flag reflects only the primary interface as the
220: * routing socket only sends IFINFO for the primary interface. Hence
221: * ~IFF_UP does not per se imply all the logical interfaces are also
222: * down - which we only know of as addresses. Instead we must determine
223: * whether the interface really is up or not according to how many
224: * addresses are still attached. (Solaris always sends RTM_DELADDR if
225: * an interface, logical or not, goes ~IFF_UP).
226: *
227: * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
228: * are addresses left in struct connected, not just the actual underlying
229: * IFF_UP flag.
230: *
231: * We must hence remember the real state of IFF_UP, which we do in
232: * struct zebra_if.primary_state.
233: *
234: * Setting IFF_UP within zebra to administratively shutdown the
235: * interface will affect only the primary interface/address on Solaris.
236: ************************End Solaris flags hacks ***********************
237: */
238: static void
239: if_flags_mangle (struct interface *ifp, uint64_t *newflags)
240: {
241: #ifdef SUNOS_5
242: struct zebra_if *zif = ifp->info;
243:
244: zif->primary_state = *newflags & (IFF_UP & 0xff);
245:
246: if (CHECK_FLAG (zif->primary_state, IFF_UP)
247: || listcount(ifp->connected) > 0)
248: SET_FLAG (*newflags, IFF_UP);
249: else
250: UNSET_FLAG (*newflags, IFF_UP);
251: #endif /* SUNOS_5 */
252: }
253:
254: /* Update the flags field of the ifp with the new flag set provided.
255: * Take whatever actions are required for any changes in flags we care
256: * about.
257: *
258: * newflags should be the raw value, as obtained from the OS.
259: */
260: void
261: if_flags_update (struct interface *ifp, uint64_t newflags)
262: {
263: if_flags_mangle (ifp, &newflags);
264:
265: if (if_is_operative (ifp))
266: {
267: /* operative -> inoperative? */
268: ifp->flags = newflags;
269: if (!if_is_operative (ifp))
270: if_down (ifp);
271: }
272: else
273: {
274: /* inoperative -> operative? */
275: ifp->flags = newflags;
276: if (if_is_operative (ifp))
277: if_up (ifp);
278: }
279: }
280:
281: /* Wake up configured address if it is not in current kernel
282: address. */
283: static void
284: if_addr_wakeup (struct interface *ifp)
285: {
286: struct listnode *node, *nnode;
287: struct connected *ifc;
288: struct prefix *p;
289: int ret;
290:
291: for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
292: {
293: p = ifc->address;
294:
295: if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
296: && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
297: {
298: /* Address check. */
299: if (p->family == AF_INET)
300: {
301: if (! if_is_up (ifp))
302: {
303: /* Assume zebra is configured like following:
304: *
305: * interface gre0
306: * ip addr 192.0.2.1/24
307: * !
308: *
309: * As soon as zebra becomes first aware that gre0 exists in the
310: * kernel, it will set gre0 up and configure its addresses.
311: *
312: * (This may happen at startup when the interface already exists
313: * or during runtime when the interface is added to the kernel)
314: *
315: * XXX: IRDP code is calling here via if_add_update - this seems
316: * somewhat weird.
317: * XXX: RUNNING is not a settable flag on any system
318: * I (paulj) am aware of.
319: */
320: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
321: if_refresh (ifp);
322: }
323:
324: ret = if_set_prefix (ifp, ifc);
325: if (ret < 0)
326: {
327: zlog_warn ("Can't set interface's address: %s",
328: safe_strerror(errno));
329: continue;
330: }
331:
332: SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
333: /* The address will be advertised to zebra clients when the notification
334: * from the kernel has been received.
335: * It will also be added to the interface's subnet list then. */
336: }
337: #ifdef HAVE_IPV6
338: if (p->family == AF_INET6)
339: {
340: if (! if_is_up (ifp))
341: {
342: /* See long comment above */
343: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
344: if_refresh (ifp);
345: }
346:
347: ret = if_prefix_add_ipv6 (ifp, ifc);
348: if (ret < 0)
349: {
350: zlog_warn ("Can't set interface's address: %s",
351: safe_strerror(errno));
352: continue;
353: }
354:
355: SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
356: /* The address will be advertised to zebra clients when the notification
357: * from the kernel has been received. */
358: }
359: #endif /* HAVE_IPV6 */
360: }
361: }
362: }
363:
364: /* Handle interface addition */
365: void
366: if_add_update (struct interface *ifp)
367: {
368: struct zebra_if *if_data;
369:
370: if_data = ifp->info;
371: assert(if_data);
372:
373: if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
374: if_set_flags (ifp, IFF_MULTICAST);
375: else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
376: if_unset_flags (ifp, IFF_MULTICAST);
377:
378: zebra_interface_add_update (ifp);
379:
380: if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
381: {
382: SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
383:
384: if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
385: {
386: if (IS_ZEBRA_DEBUG_KERNEL)
387: zlog_debug ("interface %s vrf %u index %d is shutdown. "
388: "Won't wake it up.",
389: ifp->name, ifp->vrf_id, ifp->ifindex);
390: return;
391: }
392:
393: if_addr_wakeup (ifp);
394:
395: if (IS_ZEBRA_DEBUG_KERNEL)
396: zlog_debug ("interface %s vrf %u index %d becomes active.",
397: ifp->name, ifp->vrf_id, ifp->ifindex);
398: }
399: else
400: {
401: if (IS_ZEBRA_DEBUG_KERNEL)
402: zlog_debug ("interface %s vrf %u index %d is added.",
403: ifp->name, ifp->vrf_id, ifp->ifindex);
404: }
405: }
406:
407: /* Handle an interface delete event */
408: void
409: if_delete_update (struct interface *ifp)
410: {
411: struct connected *ifc;
412: struct prefix *p;
413: struct route_node *rn;
414: struct zebra_if *zebra_if;
415:
416: zebra_if = ifp->info;
417:
418: if (if_is_up(ifp))
419: {
420: zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
421: ifp->name, ifp->vrf_id, ifp->ifindex);
422: return;
423: }
424:
425: /* Mark interface as inactive */
426: UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
427:
428: if (IS_ZEBRA_DEBUG_KERNEL)
429: zlog_debug ("interface %s vrf %u index %d is now inactive.",
430: ifp->name, ifp->vrf_id, ifp->ifindex);
431:
432: /* Delete connected routes from the kernel. */
433: if (ifp->connected)
434: {
435: struct listnode *node;
436: struct listnode *last = NULL;
437:
438: while ((node = (last ? last->next : listhead (ifp->connected))))
439: {
440: ifc = listgetdata (node);
441: p = ifc->address;
442:
443: if (p->family == AF_INET
444: && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
445: {
446: struct listnode *anode;
447: struct listnode *next;
448: struct listnode *first;
449: struct list *addr_list;
450:
451: route_unlock_node (rn);
452: addr_list = (struct list *) rn->info;
453:
454: /* Remove addresses, secondaries first. */
455: first = listhead (addr_list);
456: for (anode = first->next; anode || first; anode = next)
457: {
458: if (!anode)
459: {
460: anode = first;
461: first = NULL;
462: }
463: next = anode->next;
464:
465: ifc = listgetdata (anode);
466: p = ifc->address;
467: connected_down_ipv4 (ifp, ifc);
468:
469: /* XXX: We have to send notifications here explicitly, because we destroy
470: * the ifc before receiving the notification about the address being deleted.
471: */
472: zebra_interface_address_delete_update (ifp, ifc);
473:
474: UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
475: UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
476:
477: /* Remove from subnet chain. */
478: list_delete_node (addr_list, anode);
479: route_unlock_node (rn);
480:
481: /* Remove from interface address list (unconditionally). */
482: if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
483: {
484: listnode_delete (ifp->connected, ifc);
485: connected_free (ifc);
486: }
487: else
488: last = node;
489: }
490:
491: /* Free chain list and respective route node. */
492: list_delete (addr_list);
493: rn->info = NULL;
494: route_unlock_node (rn);
495: }
496: #ifdef HAVE_IPV6
497: else if (p->family == AF_INET6)
498: {
499: connected_down_ipv6 (ifp, ifc);
500:
501: zebra_interface_address_delete_update (ifp, ifc);
502:
503: UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
504: UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
505:
506: if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
507: last = node;
508: else
509: {
510: listnode_delete (ifp->connected, ifc);
511: connected_free (ifc);
512: }
513: }
514: #endif /* HAVE_IPV6 */
515: else
516: {
517: last = node;
518: }
519: }
520: }
521: zebra_interface_delete_update (ifp);
522:
523: /* Update ifindex after distributing the delete message. This is in
524: case any client needs to have the old value of ifindex available
525: while processing the deletion. Each client daemon is responsible
526: for setting ifindex to IFINDEX_INTERNAL after processing the
527: interface deletion message. */
528: ifp->ifindex = IFINDEX_INTERNAL;
529: }
530:
531: /* Interface is up. */
532: void
533: if_up (struct interface *ifp)
534: {
535: struct listnode *node;
536: struct listnode *next;
537: struct connected *ifc;
538: struct prefix *p;
539:
540: /* Notify the protocol daemons. */
541: zebra_interface_up_update (ifp);
542:
543: /* Install connected routes to the kernel. */
544: if (ifp->connected)
545: {
546: for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
547: {
548: p = ifc->address;
549:
550: if (p->family == AF_INET)
551: connected_up_ipv4 (ifp, ifc);
552: #ifdef HAVE_IPV6
553: else if (p->family == AF_INET6)
554: connected_up_ipv6 (ifp, ifc);
555: #endif /* HAVE_IPV6 */
556: }
557: }
558:
559: /* Examine all static routes. */
560: rib_update (ifp->vrf_id);
561: }
562:
563: /* Interface goes down. We have to manage different behavior of based
564: OS. */
565: void
566: if_down (struct interface *ifp)
567: {
568: struct listnode *node;
569: struct listnode *next;
570: struct connected *ifc;
571: struct prefix *p;
572:
573: /* Notify to the protocol daemons. */
574: zebra_interface_down_update (ifp);
575:
576: /* Delete connected routes from the kernel. */
577: if (ifp->connected)
578: {
579: for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
580: {
581: p = ifc->address;
582:
583: if (p->family == AF_INET)
584: connected_down_ipv4 (ifp, ifc);
585: #ifdef HAVE_IPV6
586: else if (p->family == AF_INET6)
587: connected_down_ipv6 (ifp, ifc);
588: #endif /* HAVE_IPV6 */
589: }
590: }
591:
592: /* Examine all static routes which direct to the interface. */
593: rib_update (ifp->vrf_id);
594: }
595:
596: void
597: if_refresh (struct interface *ifp)
598: {
599: if_get_flags (ifp);
600: }
601:
602: /* Output prefix string to vty. */
603: static int
604: prefix_vty_out (struct vty *vty, struct prefix *p)
605: {
606: char str[INET6_ADDRSTRLEN];
607:
608: inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
609: vty_out (vty, "%s", str);
610: return strlen (str);
611: }
612:
613: /* Dump if address information to vty. */
614: static void
615: connected_dump_vty (struct vty *vty, struct connected *connected)
616: {
617: struct prefix *p;
618:
619: /* Print interface address. */
620: p = connected->address;
621: vty_out (vty, " %s ", prefix_family_str (p));
622: prefix_vty_out (vty, p);
623: vty_out (vty, "/%d", p->prefixlen);
624:
625: /* If there is destination address, print it. */
626: if (connected->destination)
627: {
628: vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
629: prefix_vty_out (vty, connected->destination);
630: }
631:
632: if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
633: vty_out (vty, " secondary");
634:
635: if (connected->label)
636: vty_out (vty, " %s", connected->label);
637:
638: vty_out (vty, "%s", VTY_NEWLINE);
639: }
640:
641: #if defined (HAVE_RTADV)
642: /* Dump interface ND information to vty. */
643: static void
644: nd_dump_vty (struct vty *vty, struct interface *ifp)
645: {
646: struct zebra_if *zif;
647: struct rtadvconf *rtadv;
648: int interval;
649:
650: zif = (struct zebra_if *) ifp->info;
651: rtadv = &zif->rtadv;
652:
653: if (rtadv->AdvSendAdvertisements)
654: {
655: vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
656: rtadv->AdvReachableTime, VTY_NEWLINE);
657: vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
658: rtadv->AdvRetransTimer, VTY_NEWLINE);
659: interval = rtadv->MaxRtrAdvInterval;
660: if (interval % 1000)
661: vty_out (vty, " ND router advertisements are sent every "
662: "%d milliseconds%s", interval,
663: VTY_NEWLINE);
664: else
665: vty_out (vty, " ND router advertisements are sent every "
666: "%d seconds%s", interval / 1000,
667: VTY_NEWLINE);
668: if (rtadv->AdvDefaultLifetime != -1)
669: vty_out (vty, " ND router advertisements live for %d seconds%s",
670: rtadv->AdvDefaultLifetime, VTY_NEWLINE);
671: else
672: vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
673: VTY_NEWLINE);
674: vty_out (vty, " ND router advertisement default router preference is "
675: "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
676: VTY_NEWLINE);
677: if (rtadv->AdvManagedFlag)
678: vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
679: VTY_NEWLINE);
680: else
681: vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
682: VTY_NEWLINE);
683: if (rtadv->AdvHomeAgentFlag)
684: {
685: vty_out (vty, " ND router advertisements with "
686: "Home Agent flag bit set.%s",
687: VTY_NEWLINE);
688: if (rtadv->HomeAgentLifetime != -1)
689: vty_out (vty, " Home Agent lifetime is %u seconds%s",
690: rtadv->HomeAgentLifetime, VTY_NEWLINE);
691: else
692: vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
693: VTY_NEWLINE);
694: vty_out (vty, " Home Agent preference is %u%s",
695: rtadv->HomeAgentPreference, VTY_NEWLINE);
696: }
697: if (rtadv->AdvIntervalOption)
698: vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
699: VTY_NEWLINE);
700: }
701: }
702: #endif /* HAVE_RTADV */
703:
704: /* Interface's information print out to vty interface. */
705: static void
706: if_dump_vty (struct vty *vty, struct interface *ifp)
707: {
708: struct connected *connected;
709: struct listnode *node;
710: struct route_node *rn;
711: struct zebra_if *zebra_if;
712:
713: zebra_if = ifp->info;
714:
715: vty_out (vty, "Interface %s is ", ifp->name);
716: if (if_is_up(ifp)) {
717: vty_out (vty, "up, line protocol ");
718:
719: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
720: if (if_is_running(ifp))
721: vty_out (vty, "is up%s", VTY_NEWLINE);
722: else
723: vty_out (vty, "is down%s", VTY_NEWLINE);
724: } else {
725: vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
726: }
727: } else {
728: vty_out (vty, "down%s", VTY_NEWLINE);
729: }
730:
731: vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
732:
733: if (ifp->desc)
734: vty_out (vty, " Description: %s%s", ifp->desc,
735: VTY_NEWLINE);
736: if (ifp->ifindex == IFINDEX_INTERNAL)
737: {
738: vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
739: return;
740: }
741: else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
742: {
743: vty_out(vty, " index %d inactive interface%s",
744: ifp->ifindex,
745: VTY_NEWLINE);
746: return;
747: }
748:
749: vty_out (vty, " index %d metric %d mtu %d ",
750: ifp->ifindex, ifp->metric, ifp->mtu);
751: #ifdef HAVE_IPV6
752: if (ifp->mtu6 != ifp->mtu)
753: vty_out (vty, "mtu6 %d ", ifp->mtu6);
754: #endif
755: vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
756: if_flag_dump (ifp->flags), VTY_NEWLINE);
757:
758: /* Hardware address. */
759: vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
760: if (ifp->hw_addr_len != 0)
761: {
762: int i;
763:
764: vty_out (vty, " HWaddr: ");
765: for (i = 0; i < ifp->hw_addr_len; i++)
766: vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
767: vty_out (vty, "%s", VTY_NEWLINE);
768: }
769:
770: /* Bandwidth in kbps */
771: if (ifp->bandwidth != 0)
772: {
773: vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
774: vty_out(vty, "%s", VTY_NEWLINE);
775: }
776:
777: for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
778: {
779: if (! rn->info)
780: continue;
781:
782: for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
783: connected_dump_vty (vty, connected);
784: }
785:
786: for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
787: {
788: if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
789: (connected->address->family == AF_INET6))
790: connected_dump_vty (vty, connected);
791: }
792:
793: #if defined (HAVE_RTADV)
794: nd_dump_vty (vty, ifp);
795: #endif /* HAVE_RTADV */
796:
797: #ifdef HAVE_PROC_NET_DEV
798: /* Statistics print out using proc file system. */
799: vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
800: "%lu dropped%s",
801: ifp->stats.rx_packets, ifp->stats.rx_multicast,
802: ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
803:
804: vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
805: " %lu CRC, %lu frame%s",
806: ifp->stats.rx_errors, ifp->stats.rx_length_errors,
807: ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
808: ifp->stats.rx_frame_errors, VTY_NEWLINE);
809:
810: vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
811: ifp->stats.rx_missed_errors, VTY_NEWLINE);
812:
813: vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
814: ifp->stats.tx_packets, ifp->stats.tx_bytes,
815: ifp->stats.tx_dropped, VTY_NEWLINE);
816:
817: vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
818: " %lu fifo, %lu heartbeat%s",
819: ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
820: ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
821: ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
822:
823: vty_out (vty, " %lu window, %lu collisions%s",
824: ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
825: #endif /* HAVE_PROC_NET_DEV */
826:
827: #ifdef HAVE_NET_RT_IFLIST
828: #if defined (__bsdi__) || defined (__NetBSD__)
829: /* Statistics print out using sysctl (). */
830: vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
831: " multicast packets %llu%s",
832: (unsigned long long)ifp->stats.ifi_ipackets,
833: (unsigned long long)ifp->stats.ifi_ibytes,
834: (unsigned long long)ifp->stats.ifi_iqdrops,
835: (unsigned long long)ifp->stats.ifi_imcasts,
836: VTY_NEWLINE);
837:
838: vty_out (vty, " input errors %llu%s",
839: (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
840:
841: vty_out (vty, " output packets %llu, bytes %llu,"
842: " multicast packets %llu%s",
843: (unsigned long long)ifp->stats.ifi_opackets,
844: (unsigned long long)ifp->stats.ifi_obytes,
845: (unsigned long long)ifp->stats.ifi_omcasts,
846: VTY_NEWLINE);
847:
848: vty_out (vty, " output errors %llu%s",
849: (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
850:
851: vty_out (vty, " collisions %llu%s",
852: (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
853: #else
854: /* Statistics print out using sysctl (). */
855: vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
856: " multicast packets %lu%s",
857: ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
858: ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
859: VTY_NEWLINE);
860:
861: vty_out (vty, " input errors %lu%s",
862: ifp->stats.ifi_ierrors, VTY_NEWLINE);
863:
864: vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
865: ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
866: ifp->stats.ifi_omcasts, VTY_NEWLINE);
867:
868: vty_out (vty, " output errors %lu%s",
869: ifp->stats.ifi_oerrors, VTY_NEWLINE);
870:
871: vty_out (vty, " collisions %lu%s",
872: ifp->stats.ifi_collisions, VTY_NEWLINE);
873: #endif /* __bsdi__ || __NetBSD__ */
874: #endif /* HAVE_NET_RT_IFLIST */
875: }
876:
877: /* Wrapper hook point for zebra daemon so that ifindex can be set
878: * DEFUN macro not used as extract.pl HAS to ignore this
879: * See also interface_cmd in lib/if.c
880: */
881: DEFUN_NOSH (zebra_interface,
882: zebra_interface_cmd,
883: "interface IFNAME",
884: "Select an interface to configure\n"
885: "Interface's name\n")
886: {
887: int ret;
888: struct interface * ifp;
889:
890: /* Call lib interface() */
891: if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
892: return ret;
893:
894: ifp = vty->index;
895:
896: if (ifp->ifindex == IFINDEX_INTERNAL)
897: /* Is this really necessary? Shouldn't status be initialized to 0
898: in that case? */
899: UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
900:
901: return ret;
902: }
903:
904: ALIAS (zebra_interface,
905: zebra_interface_vrf_cmd,
906: "interface IFNAME " VRF_CMD_STR,
907: "Select an interface to configure\n"
908: "Interface's name\n"
909: VRF_CMD_HELP_STR)
910:
911: struct cmd_node interface_node =
912: {
913: INTERFACE_NODE,
914: "%s(config-if)# ",
915: 1
916: };
917:
918: /* Show all interfaces to vty. */
919: DEFUN (show_interface, show_interface_cmd,
920: "show interface",
921: SHOW_STR
922: "Interface status and configuration\n")
923: {
924: struct listnode *node;
925: struct interface *ifp;
926: vrf_id_t vrf_id = VRF_DEFAULT;
927:
928: #ifdef HAVE_PROC_NET_DEV
929: /* If system has interface statistics via proc file system, update
930: statistics. */
931: ifstat_update_proc ();
932: #endif /* HAVE_PROC_NET_DEV */
933: #ifdef HAVE_NET_RT_IFLIST
934: ifstat_update_sysctl ();
935: #endif /* HAVE_NET_RT_IFLIST */
936:
937: if (argc > 0)
938: VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
939:
940: /* All interface print. */
941: for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
942: if_dump_vty (vty, ifp);
943:
944: return CMD_SUCCESS;
945: }
946:
947: ALIAS (show_interface,
948: show_interface_vrf_cmd,
949: "show interface " VRF_CMD_STR,
950: SHOW_STR
951: "Interface status and configuration\n"
952: VRF_CMD_HELP_STR)
953:
954: /* Show all interfaces to vty. */
955: DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
956: "show interface " VRF_ALL_CMD_STR,
957: SHOW_STR
958: "Interface status and configuration\n"
959: VRF_ALL_CMD_HELP_STR)
960: {
961: struct listnode *node;
962: struct interface *ifp;
963: vrf_iter_t iter;
964:
965: #ifdef HAVE_PROC_NET_DEV
966: /* If system has interface statistics via proc file system, update
967: statistics. */
968: ifstat_update_proc ();
969: #endif /* HAVE_PROC_NET_DEV */
970: #ifdef HAVE_NET_RT_IFLIST
971: ifstat_update_sysctl ();
972: #endif /* HAVE_NET_RT_IFLIST */
973:
974: /* All interface print. */
975: for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
976: for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
977: if_dump_vty (vty, ifp);
978:
979: return CMD_SUCCESS;
980: }
981:
982: /* Show specified interface to vty. */
983: DEFUN (show_interface_name, show_interface_name_cmd,
984: "show interface IFNAME",
985: SHOW_STR
986: "Interface status and configuration\n"
987: "Inteface name\n")
988: {
989: struct interface *ifp;
990: vrf_id_t vrf_id = VRF_DEFAULT;
991:
992: #ifdef HAVE_PROC_NET_DEV
993: /* If system has interface statistics via proc file system, update
994: statistics. */
995: ifstat_update_proc ();
996: #endif /* HAVE_PROC_NET_DEV */
997: #ifdef HAVE_NET_RT_IFLIST
998: ifstat_update_sysctl ();
999: #endif /* HAVE_NET_RT_IFLIST */
1000:
1001: if (argc > 1)
1002: VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1003:
1004: /* Specified interface print. */
1005: ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1006: if (ifp == NULL)
1007: {
1008: vty_out (vty, "%% Can't find interface %s%s", argv[0],
1009: VTY_NEWLINE);
1010: return CMD_WARNING;
1011: }
1012: if_dump_vty (vty, ifp);
1013:
1014: return CMD_SUCCESS;
1015: }
1016:
1017: ALIAS (show_interface_name,
1018: show_interface_name_vrf_cmd,
1019: "show interface IFNAME " VRF_CMD_STR,
1020: SHOW_STR
1021: "Interface status and configuration\n"
1022: "Inteface name\n"
1023: VRF_CMD_HELP_STR)
1024:
1025: /* Show specified interface to vty. */
1026: DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1027: "show interface IFNAME " VRF_ALL_CMD_STR,
1028: SHOW_STR
1029: "Interface status and configuration\n"
1030: "Inteface name\n"
1031: VRF_ALL_CMD_HELP_STR)
1032: {
1033: struct interface *ifp;
1034: vrf_iter_t iter;
1035: int found = 0;
1036:
1037: #ifdef HAVE_PROC_NET_DEV
1038: /* If system has interface statistics via proc file system, update
1039: statistics. */
1040: ifstat_update_proc ();
1041: #endif /* HAVE_PROC_NET_DEV */
1042: #ifdef HAVE_NET_RT_IFLIST
1043: ifstat_update_sysctl ();
1044: #endif /* HAVE_NET_RT_IFLIST */
1045:
1046: /* All interface print. */
1047: for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1048: {
1049: /* Specified interface print. */
1050: ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1051: if (ifp)
1052: {
1053: if_dump_vty (vty, ifp);
1054: found++;
1055: }
1056: }
1057:
1058: if (!found)
1059: {
1060: vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1061: return CMD_WARNING;
1062: }
1063:
1064: return CMD_SUCCESS;
1065: }
1066:
1067: static void
1068: if_show_description (struct vty *vty, vrf_id_t vrf_id)
1069: {
1070: struct listnode *node;
1071: struct interface *ifp;
1072:
1073: vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
1074: for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1075: {
1076: int len;
1077:
1078: len = vty_out (vty, "%s", ifp->name);
1079: vty_out (vty, "%*s", (16 - len), " ");
1080:
1081: if (if_is_up(ifp))
1082: {
1083: vty_out (vty, "up ");
1084: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1085: {
1086: if (if_is_running(ifp))
1087: vty_out (vty, "up ");
1088: else
1089: vty_out (vty, "down ");
1090: }
1091: else
1092: {
1093: vty_out (vty, "unknown ");
1094: }
1095: }
1096: else
1097: {
1098: vty_out (vty, "down down ");
1099: }
1100:
1101: if (ifp->desc)
1102: vty_out (vty, "%s", ifp->desc);
1103: vty_out (vty, "%s", VTY_NEWLINE);
1104: }
1105: }
1106:
1107: DEFUN (show_interface_desc,
1108: show_interface_desc_cmd,
1109: "show interface description",
1110: SHOW_STR
1111: "Interface status and configuration\n"
1112: "Interface description\n")
1113: {
1114: vrf_id_t vrf_id = VRF_DEFAULT;
1115:
1116: if (argc > 0)
1117: VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1118:
1119: if_show_description (vty, vrf_id);
1120:
1121: return CMD_SUCCESS;
1122: }
1123:
1124: ALIAS (show_interface_desc,
1125: show_interface_desc_vrf_cmd,
1126: "show interface description " VRF_CMD_STR,
1127: SHOW_STR
1128: "Interface status and configuration\n"
1129: "Interface description\n"
1130: VRF_CMD_HELP_STR)
1131:
1132: DEFUN (show_interface_desc_vrf_all,
1133: show_interface_desc_vrf_all_cmd,
1134: "show interface description " VRF_ALL_CMD_STR,
1135: SHOW_STR
1136: "Interface status and configuration\n"
1137: "Interface description\n"
1138: VRF_ALL_CMD_HELP_STR)
1139: {
1140: vrf_iter_t iter;
1141:
1142: for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1143: if (!list_isempty (vrf_iter2iflist (iter)))
1144: {
1145: vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1146: vrf_iter2id (iter),
1147: VTY_NEWLINE, VTY_NEWLINE);
1148: if_show_description (vty, vrf_iter2id (iter));
1149: }
1150:
1151: return CMD_SUCCESS;
1152: }
1153:
1154: DEFUN (multicast,
1155: multicast_cmd,
1156: "multicast",
1157: "Set multicast flag to interface\n")
1158: {
1159: int ret;
1160: struct interface *ifp;
1161: struct zebra_if *if_data;
1162:
1163: ifp = (struct interface *) vty->index;
1164: if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1165: {
1166: ret = if_set_flags (ifp, IFF_MULTICAST);
1167: if (ret < 0)
1168: {
1169: vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1170: return CMD_WARNING;
1171: }
1172: if_refresh (ifp);
1173: }
1174: if_data = ifp->info;
1175: if_data->multicast = IF_ZEBRA_MULTICAST_ON;
1176:
1177: return CMD_SUCCESS;
1178: }
1179:
1180: DEFUN (no_multicast,
1181: no_multicast_cmd,
1182: "no multicast",
1183: NO_STR
1184: "Unset multicast flag to interface\n")
1185: {
1186: int ret;
1187: struct interface *ifp;
1188: struct zebra_if *if_data;
1189:
1190: ifp = (struct interface *) vty->index;
1191: if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1192: {
1193: ret = if_unset_flags (ifp, IFF_MULTICAST);
1194: if (ret < 0)
1195: {
1196: vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1197: return CMD_WARNING;
1198: }
1199: if_refresh (ifp);
1200: }
1201: if_data = ifp->info;
1202: if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1203:
1204: return CMD_SUCCESS;
1205: }
1206:
1207: DEFUN (linkdetect,
1208: linkdetect_cmd,
1209: "link-detect",
1210: "Enable link detection on interface\n")
1211: {
1212: struct interface *ifp;
1213: int if_was_operative;
1214:
1215: ifp = (struct interface *) vty->index;
1216: if_was_operative = if_is_operative(ifp);
1217: SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1218:
1219: /* When linkdetection is enabled, if might come down */
1220: if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1221:
1222: /* FIXME: Will defer status change forwarding if interface
1223: does not come down! */
1224:
1225: return CMD_SUCCESS;
1226: }
1227:
1228:
1229: DEFUN (no_linkdetect,
1230: no_linkdetect_cmd,
1231: "no link-detect",
1232: NO_STR
1233: "Disable link detection on interface\n")
1234: {
1235: struct interface *ifp;
1236: int if_was_operative;
1237:
1238: ifp = (struct interface *) vty->index;
1239: if_was_operative = if_is_operative(ifp);
1240: UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1241:
1242: /* Interface may come up after disabling link detection */
1243: if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1244:
1245: /* FIXME: see linkdetect_cmd */
1246:
1247: return CMD_SUCCESS;
1248: }
1249:
1250: DEFUN (shutdown_if,
1251: shutdown_if_cmd,
1252: "shutdown",
1253: "Shutdown the selected interface\n")
1254: {
1255: int ret;
1256: struct interface *ifp;
1257: struct zebra_if *if_data;
1258:
1259: ifp = (struct interface *) vty->index;
1260: if (ifp->ifindex != IFINDEX_INTERNAL)
1261: {
1262: ret = if_unset_flags (ifp, IFF_UP);
1263: if (ret < 0)
1264: {
1265: vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1266: return CMD_WARNING;
1267: }
1268: if_refresh (ifp);
1269: }
1270: if_data = ifp->info;
1271: if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1272:
1273: return CMD_SUCCESS;
1274: }
1275:
1276: DEFUN (no_shutdown_if,
1277: no_shutdown_if_cmd,
1278: "no shutdown",
1279: NO_STR
1280: "Shutdown the selected interface\n")
1281: {
1282: int ret;
1283: struct interface *ifp;
1284: struct zebra_if *if_data;
1285:
1286: ifp = (struct interface *) vty->index;
1287:
1288: if (ifp->ifindex != IFINDEX_INTERNAL)
1289: {
1290: ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1291: if (ret < 0)
1292: {
1293: vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1294: return CMD_WARNING;
1295: }
1296: if_refresh (ifp);
1297:
1298: /* Some addresses (in particular, IPv6 addresses on Linux) get
1299: * removed when the interface goes down. They need to be readded.
1300: */
1301: if_addr_wakeup(ifp);
1302: }
1303:
1304: if_data = ifp->info;
1305: if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1306:
1307: return CMD_SUCCESS;
1308: }
1309:
1310: DEFUN (bandwidth_if,
1311: bandwidth_if_cmd,
1312: "bandwidth <1-10000000>",
1313: "Set bandwidth informational parameter\n"
1314: "Bandwidth in kilobits\n")
1315: {
1316: struct interface *ifp;
1317: unsigned int bandwidth;
1318:
1319: ifp = (struct interface *) vty->index;
1320: bandwidth = strtol(argv[0], NULL, 10);
1321:
1322: /* bandwidth range is <1-10000000> */
1323: if (bandwidth < 1 || bandwidth > 10000000)
1324: {
1325: vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1326: return CMD_WARNING;
1327: }
1328:
1329: ifp->bandwidth = bandwidth;
1330:
1331: /* force protocols to recalculate routes due to cost change */
1332: if (if_is_operative (ifp))
1333: zebra_interface_up_update (ifp);
1334:
1335: return CMD_SUCCESS;
1336: }
1337:
1338: DEFUN (no_bandwidth_if,
1339: no_bandwidth_if_cmd,
1340: "no bandwidth",
1341: NO_STR
1342: "Set bandwidth informational parameter\n")
1343: {
1344: struct interface *ifp;
1345:
1346: ifp = (struct interface *) vty->index;
1347:
1348: ifp->bandwidth = 0;
1349:
1350: /* force protocols to recalculate routes due to cost change */
1351: if (if_is_operative (ifp))
1352: zebra_interface_up_update (ifp);
1353:
1354: return CMD_SUCCESS;
1355: }
1356:
1357: ALIAS (no_bandwidth_if,
1358: no_bandwidth_if_val_cmd,
1359: "no bandwidth <1-10000000>",
1360: NO_STR
1361: "Set bandwidth informational parameter\n"
1362: "Bandwidth in kilobits\n")
1363:
1364: static int
1365: ip_address_install (struct vty *vty, struct interface *ifp,
1366: const char *addr_str, const char *peer_str,
1367: const char *label)
1368: {
1369: struct zebra_if *if_data;
1370: struct prefix_ipv4 cp;
1371: struct connected *ifc;
1372: struct prefix_ipv4 *p;
1373: int ret;
1374:
1375: if_data = ifp->info;
1376:
1377: ret = str2prefix_ipv4 (addr_str, &cp);
1378: if (ret <= 0)
1379: {
1380: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1381: return CMD_WARNING;
1382: }
1383:
1384: ifc = connected_check (ifp, (struct prefix *) &cp);
1385: if (! ifc)
1386: {
1387: ifc = connected_new ();
1388: ifc->ifp = ifp;
1389:
1390: /* Address. */
1391: p = prefix_ipv4_new ();
1392: *p = cp;
1393: ifc->address = (struct prefix *) p;
1394:
1395: /* Broadcast. */
1396: if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
1397: {
1398: p = prefix_ipv4_new ();
1399: *p = cp;
1400: p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
1401: ifc->destination = (struct prefix *) p;
1402: }
1403:
1404: /* Label. */
1405: if (label)
1406: ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
1407:
1408: /* Add to linked list. */
1409: listnode_add (ifp->connected, ifc);
1410: }
1411:
1412: /* This address is configured from zebra. */
1413: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1414: SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1415:
1416: /* In case of this route need to install kernel. */
1417: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1418: && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1419: && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
1420: {
1421: /* Some system need to up the interface to set IP address. */
1422: if (! if_is_up (ifp))
1423: {
1424: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1425: if_refresh (ifp);
1426: }
1427:
1428: ret = if_set_prefix (ifp, ifc);
1429: if (ret < 0)
1430: {
1431: vty_out (vty, "%% Can't set interface IP address: %s.%s",
1432: safe_strerror(errno), VTY_NEWLINE);
1433: return CMD_WARNING;
1434: }
1435:
1436: SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1437: /* The address will be advertised to zebra clients when the notification
1438: * from the kernel has been received.
1439: * It will also be added to the subnet chain list, then. */
1440: }
1441:
1442: return CMD_SUCCESS;
1443: }
1444:
1445: static int
1446: ip_address_uninstall (struct vty *vty, struct interface *ifp,
1447: const char *addr_str, const char *peer_str,
1448: const char *label)
1449: {
1450: struct prefix_ipv4 cp;
1451: struct connected *ifc;
1452: int ret;
1453:
1454: /* Convert to prefix structure. */
1455: ret = str2prefix_ipv4 (addr_str, &cp);
1456: if (ret <= 0)
1457: {
1458: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1459: return CMD_WARNING;
1460: }
1461:
1462: /* Check current interface address. */
1463: ifc = connected_check (ifp, (struct prefix *) &cp);
1464: if (! ifc)
1465: {
1466: vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1467: return CMD_WARNING;
1468: }
1469:
1470: /* This is not configured address. */
1471: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1472: return CMD_WARNING;
1473:
1474: UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1475:
1476: /* This is not real address or interface is not active. */
1477: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1478: || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1479: {
1480: listnode_delete (ifp->connected, ifc);
1481: connected_free (ifc);
1482: return CMD_WARNING;
1483: }
1484:
1485: /* This is real route. */
1486: ret = if_unset_prefix (ifp, ifc);
1487: if (ret < 0)
1488: {
1489: vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1490: safe_strerror(errno), VTY_NEWLINE);
1491: return CMD_WARNING;
1492: }
1493: UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1494: /* we will receive a kernel notification about this route being removed.
1495: * this will trigger its removal from the connected list. */
1496: return CMD_SUCCESS;
1497: }
1498:
1499: DEFUN (ip_address,
1500: ip_address_cmd,
1501: "ip address A.B.C.D/M",
1502: "Interface Internet Protocol config commands\n"
1503: "Set the IP address of an interface\n"
1504: "IP address (e.g. 10.0.0.1/8)\n")
1505: {
1506: return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
1507: }
1508:
1509: DEFUN (no_ip_address,
1510: no_ip_address_cmd,
1511: "no ip address A.B.C.D/M",
1512: NO_STR
1513: "Interface Internet Protocol config commands\n"
1514: "Set the IP address of an interface\n"
1515: "IP Address (e.g. 10.0.0.1/8)")
1516: {
1517: return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
1518: }
1519:
1520: #ifdef HAVE_NETLINK
1521: DEFUN (ip_address_label,
1522: ip_address_label_cmd,
1523: "ip address A.B.C.D/M label LINE",
1524: "Interface Internet Protocol config commands\n"
1525: "Set the IP address of an interface\n"
1526: "IP address (e.g. 10.0.0.1/8)\n"
1527: "Label of this address\n"
1528: "Label\n")
1529: {
1530: return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
1531: }
1532:
1533: DEFUN (no_ip_address_label,
1534: no_ip_address_label_cmd,
1535: "no ip address A.B.C.D/M label LINE",
1536: NO_STR
1537: "Interface Internet Protocol config commands\n"
1538: "Set the IP address of an interface\n"
1539: "IP address (e.g. 10.0.0.1/8)\n"
1540: "Label of this address\n"
1541: "Label\n")
1542: {
1543: return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
1544: }
1545: #endif /* HAVE_NETLINK */
1546:
1547: #ifdef HAVE_IPV6
1548: static int
1549: ipv6_address_install (struct vty *vty, struct interface *ifp,
1550: const char *addr_str, const char *peer_str,
1551: const char *label, int secondary)
1552: {
1553: struct zebra_if *if_data;
1554: struct prefix_ipv6 cp;
1555: struct connected *ifc;
1556: struct prefix_ipv6 *p;
1557: int ret;
1558:
1559: if_data = ifp->info;
1560:
1561: ret = str2prefix_ipv6 (addr_str, &cp);
1562: if (ret <= 0)
1563: {
1564: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1565: return CMD_WARNING;
1566: }
1567:
1568: ifc = connected_check (ifp, (struct prefix *) &cp);
1569: if (! ifc)
1570: {
1571: ifc = connected_new ();
1572: ifc->ifp = ifp;
1573:
1574: /* Address. */
1575: p = prefix_ipv6_new ();
1576: *p = cp;
1577: ifc->address = (struct prefix *) p;
1578:
1579: /* Secondary. */
1580: if (secondary)
1581: SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1582:
1583: /* Label. */
1584: if (label)
1585: ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
1586:
1587: /* Add to linked list. */
1588: listnode_add (ifp->connected, ifc);
1589: }
1590:
1591: /* This address is configured from zebra. */
1592: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1593: SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1594:
1595: /* In case of this route need to install kernel. */
1596: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1597: && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1598: && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
1599: {
1600: /* Some system need to up the interface to set IP address. */
1601: if (! if_is_up (ifp))
1602: {
1603: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1604: if_refresh (ifp);
1605: }
1606:
1607: ret = if_prefix_add_ipv6 (ifp, ifc);
1608:
1609: if (ret < 0)
1610: {
1611: vty_out (vty, "%% Can't set interface IP address: %s.%s",
1612: safe_strerror(errno), VTY_NEWLINE);
1613: return CMD_WARNING;
1614: }
1615:
1616: SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1617: /* The address will be advertised to zebra clients when the notification
1618: * from the kernel has been received. */
1619: }
1620:
1621: return CMD_SUCCESS;
1622: }
1623:
1624: static int
1625: ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1626: const char *addr_str, const char *peer_str,
1627: const char *label, int secondry)
1628: {
1629: struct prefix_ipv6 cp;
1630: struct connected *ifc;
1631: int ret;
1632:
1633: /* Convert to prefix structure. */
1634: ret = str2prefix_ipv6 (addr_str, &cp);
1635: if (ret <= 0)
1636: {
1637: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1638: return CMD_WARNING;
1639: }
1640:
1641: /* Check current interface address. */
1642: ifc = connected_check (ifp, (struct prefix *) &cp);
1643: if (! ifc)
1644: {
1645: vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1646: return CMD_WARNING;
1647: }
1648:
1649: /* This is not configured address. */
1650: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1651: return CMD_WARNING;
1652:
1653: UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1654:
1655: /* This is not real address or interface is not active. */
1656: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
1657: || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1658: {
1659: listnode_delete (ifp->connected, ifc);
1660: connected_free (ifc);
1661: return CMD_WARNING;
1662: }
1663:
1664: /* This is real route. */
1665: ret = if_prefix_delete_ipv6 (ifp, ifc);
1666: if (ret < 0)
1667: {
1668: vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1669: safe_strerror(errno), VTY_NEWLINE);
1670: return CMD_WARNING;
1671: }
1672:
1673: UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1674: /* This information will be propagated to the zclients when the
1675: * kernel notification is received. */
1676: return CMD_SUCCESS;
1677: }
1678:
1679: DEFUN (ipv6_address,
1680: ipv6_address_cmd,
1681: "ipv6 address X:X::X:X/M",
1682: "Interface IPv6 config commands\n"
1683: "Set the IP address of an interface\n"
1684: "IPv6 address (e.g. 3ffe:506::1/48)\n")
1685: {
1686: return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1687: }
1688:
1689: DEFUN (no_ipv6_address,
1690: no_ipv6_address_cmd,
1691: "no ipv6 address X:X::X:X/M",
1692: NO_STR
1693: "Interface IPv6 config commands\n"
1694: "Set the IP address of an interface\n"
1695: "IPv6 address (e.g. 3ffe:506::1/48)\n")
1696: {
1697: return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1698: }
1699: #endif /* HAVE_IPV6 */
1700:
1701: static int
1702: if_config_write (struct vty *vty)
1703: {
1704: struct listnode *node;
1705: struct interface *ifp;
1706: vrf_iter_t iter;
1707:
1708: for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1709: for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1710: {
1711: struct zebra_if *if_data;
1712: struct listnode *addrnode;
1713: struct connected *ifc;
1714: struct prefix *p;
1715:
1716: if_data = ifp->info;
1717:
1718: if (ifp->vrf_id == VRF_DEFAULT)
1719: vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1720: else
1721: vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1722: VTY_NEWLINE);
1723:
1724: if (if_data)
1725: {
1726: if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1727: vty_out (vty, " shutdown%s", VTY_NEWLINE);
1728: }
1729:
1730: if (ifp->desc)
1731: vty_out (vty, " description %s%s", ifp->desc,
1732: VTY_NEWLINE);
1733:
1734: /* Assign bandwidth here to avoid unnecessary interface flap
1735: while processing config script */
1736: if (ifp->bandwidth != 0)
1737: vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1738:
1739: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1740: vty_out(vty, " link-detect%s", VTY_NEWLINE);
1741: else
1742: vty_out(vty, " no link-detect%s", VTY_NEWLINE);
1743:
1744: for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
1745: {
1746: if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1747: {
1748: char buf[INET6_ADDRSTRLEN];
1749: p = ifc->address;
1750: vty_out (vty, " ip%s address %s",
1751: p->family == AF_INET ? "" : "v6",
1752: prefix2str (p, buf, sizeof(buf)));
1753:
1754: if (ifc->label)
1755: vty_out (vty, " label %s", ifc->label);
1756:
1757: vty_out (vty, "%s", VTY_NEWLINE);
1758: }
1759: }
1760:
1761: if (if_data)
1762: {
1763: if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1764: vty_out (vty, " %smulticast%s",
1765: if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1766: VTY_NEWLINE);
1767: }
1768:
1769: #if defined (HAVE_RTADV)
1770: rtadv_config_write (vty, ifp);
1771: #endif /* HAVE_RTADV */
1772:
1773: #ifdef HAVE_IRDP
1774: irdp_config_write (vty, ifp);
1775: #endif /* IRDP */
1776:
1777: vty_out (vty, "!%s", VTY_NEWLINE);
1778: }
1779: return 0;
1780: }
1781:
1782: /* Allocate and initialize interface vector. */
1783: void
1784: zebra_if_init (void)
1785: {
1786: /* Initialize interface and new hook. */
1787: if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1788: if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1789:
1790: /* Install configuration write function. */
1791: install_node (&interface_node, if_config_write);
1792:
1793: install_element (VIEW_NODE, &show_interface_cmd);
1794: install_element (VIEW_NODE, &show_interface_vrf_cmd);
1795: install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
1796: install_element (VIEW_NODE, &show_interface_name_cmd);
1797: install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
1798: install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
1799: install_element (ENABLE_NODE, &show_interface_cmd);
1800: install_element (ENABLE_NODE, &show_interface_vrf_cmd);
1801: install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
1802: install_element (ENABLE_NODE, &show_interface_name_cmd);
1803: install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
1804: install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
1805: install_element (ENABLE_NODE, &show_interface_desc_cmd);
1806: install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
1807: install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
1808: install_element (CONFIG_NODE, &zebra_interface_cmd);
1809: install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
1810: install_element (CONFIG_NODE, &no_interface_cmd);
1811: install_element (CONFIG_NODE, &no_interface_vrf_cmd);
1812: install_default (INTERFACE_NODE);
1813: install_element (INTERFACE_NODE, &interface_desc_cmd);
1814: install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1815: install_element (INTERFACE_NODE, &multicast_cmd);
1816: install_element (INTERFACE_NODE, &no_multicast_cmd);
1817: install_element (INTERFACE_NODE, &linkdetect_cmd);
1818: install_element (INTERFACE_NODE, &no_linkdetect_cmd);
1819: install_element (INTERFACE_NODE, &shutdown_if_cmd);
1820: install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1821: install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1822: install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1823: install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1824: install_element (INTERFACE_NODE, &ip_address_cmd);
1825: install_element (INTERFACE_NODE, &no_ip_address_cmd);
1826: #ifdef HAVE_IPV6
1827: install_element (INTERFACE_NODE, &ipv6_address_cmd);
1828: install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1829: #endif /* HAVE_IPV6 */
1830: #ifdef HAVE_NETLINK
1831: install_element (INTERFACE_NODE, &ip_address_label_cmd);
1832: install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
1833: #endif /* HAVE_NETLINK */
1834: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>