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