Annotation of embedaddon/quagga/zebra/interface.c, revision 1.1.1.2
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;
1.1.1.2 ! misho 79: rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
1.1 misho 80: rtadv->HomeAgentPreference = 0;
1.1.1.2 ! misho 81: rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
1.1 misho 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: */
1.1.1.2 ! misho 219: static void
1.1 misho 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);
1.1.1.2 ! misho 633: if (rtadv->AdvDefaultLifetime != -1)
! 634: vty_out (vty, " ND router advertisements live for %d seconds%s",
! 635: rtadv->AdvDefaultLifetime, VTY_NEWLINE);
! 636: else
! 637: vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
! 638: VTY_NEWLINE);
1.1 misho 639: vty_out (vty, " ND router advertisement default router preference is "
640: "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
641: VTY_NEWLINE);
642: if (rtadv->AdvManagedFlag)
643: vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
644: VTY_NEWLINE);
645: else
646: vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
647: VTY_NEWLINE);
648: if (rtadv->AdvHomeAgentFlag)
1.1.1.2 ! misho 649: {
1.1 misho 650: vty_out (vty, " ND router advertisements with "
651: "Home Agent flag bit set.%s",
652: VTY_NEWLINE);
1.1.1.2 ! misho 653: if (rtadv->HomeAgentLifetime != -1)
! 654: vty_out (vty, " Home Agent lifetime is %u seconds%s",
! 655: rtadv->HomeAgentLifetime, VTY_NEWLINE);
! 656: else
! 657: vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
! 658: VTY_NEWLINE);
! 659: vty_out (vty, " Home Agent preference is %u%s",
! 660: rtadv->HomeAgentPreference, VTY_NEWLINE);
! 661: }
1.1 misho 662: if (rtadv->AdvIntervalOption)
663: vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
664: VTY_NEWLINE);
665: }
666: }
667: #endif /* RTADV */
668:
669: /* Interface's information print out to vty interface. */
670: static void
671: if_dump_vty (struct vty *vty, struct interface *ifp)
672: {
673: #ifdef HAVE_STRUCT_SOCKADDR_DL
674: struct sockaddr_dl *sdl;
675: #endif /* HAVE_STRUCT_SOCKADDR_DL */
676: struct connected *connected;
677: struct listnode *node;
678: struct route_node *rn;
679: struct zebra_if *zebra_if;
680:
681: zebra_if = ifp->info;
682:
683: vty_out (vty, "Interface %s is ", ifp->name);
684: if (if_is_up(ifp)) {
685: vty_out (vty, "up, line protocol ");
686:
687: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
688: if (if_is_running(ifp))
689: vty_out (vty, "is up%s", VTY_NEWLINE);
690: else
691: vty_out (vty, "is down%s", VTY_NEWLINE);
692: } else {
693: vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
694: }
695: } else {
696: vty_out (vty, "down%s", VTY_NEWLINE);
697: }
698:
699: if (ifp->desc)
700: vty_out (vty, " Description: %s%s", ifp->desc,
701: VTY_NEWLINE);
702: if (ifp->ifindex == IFINDEX_INTERNAL)
703: {
704: vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
705: return;
706: }
707: else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
708: {
709: vty_out(vty, " index %d inactive interface%s",
710: ifp->ifindex,
711: VTY_NEWLINE);
712: return;
713: }
714:
715: vty_out (vty, " index %d metric %d mtu %d ",
716: ifp->ifindex, ifp->metric, ifp->mtu);
717: #ifdef HAVE_IPV6
718: if (ifp->mtu6 != ifp->mtu)
719: vty_out (vty, "mtu6 %d ", ifp->mtu6);
720: #endif
721: vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
722: if_flag_dump (ifp->flags), VTY_NEWLINE);
723:
724: /* Hardware address. */
725: #ifdef HAVE_STRUCT_SOCKADDR_DL
726: sdl = &ifp->sdl;
727: if (sdl != NULL && sdl->sdl_alen != 0)
728: {
729: int i;
730: u_char *ptr;
731:
732: vty_out (vty, " HWaddr: ");
733: for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
734: vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
735: vty_out (vty, "%s", VTY_NEWLINE);
736: }
737: #else
738: if (ifp->hw_addr_len != 0)
739: {
740: int i;
741:
742: vty_out (vty, " HWaddr: ");
743: for (i = 0; i < ifp->hw_addr_len; i++)
744: vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
745: vty_out (vty, "%s", VTY_NEWLINE);
746: }
747: #endif /* HAVE_STRUCT_SOCKADDR_DL */
748:
749: /* Bandwidth in kbps */
750: if (ifp->bandwidth != 0)
751: {
752: vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
753: vty_out(vty, "%s", VTY_NEWLINE);
754: }
755:
756: for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
757: {
758: if (! rn->info)
759: continue;
760:
761: for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
762: connected_dump_vty (vty, connected);
763: }
764:
765: for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
766: {
767: if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
768: (connected->address->family == AF_INET6))
769: connected_dump_vty (vty, connected);
770: }
771:
772: #ifdef RTADV
773: nd_dump_vty (vty, ifp);
774: #endif /* RTADV */
775:
776: #ifdef HAVE_PROC_NET_DEV
777: /* Statistics print out using proc file system. */
778: vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
779: "%lu dropped%s",
780: ifp->stats.rx_packets, ifp->stats.rx_multicast,
781: ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
782:
783: vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
784: " %lu CRC, %lu frame%s",
785: ifp->stats.rx_errors, ifp->stats.rx_length_errors,
786: ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
787: ifp->stats.rx_frame_errors, VTY_NEWLINE);
788:
789: vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
790: ifp->stats.rx_missed_errors, VTY_NEWLINE);
791:
792: vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
793: ifp->stats.tx_packets, ifp->stats.tx_bytes,
794: ifp->stats.tx_dropped, VTY_NEWLINE);
795:
796: vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
797: " %lu fifo, %lu heartbeat%s",
798: ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
799: ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
800: ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
801:
802: vty_out (vty, " %lu window, %lu collisions%s",
803: ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
804: #endif /* HAVE_PROC_NET_DEV */
805:
806: #ifdef HAVE_NET_RT_IFLIST
807: #if defined (__bsdi__) || defined (__NetBSD__)
808: /* Statistics print out using sysctl (). */
809: vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
810: " multicast packets %qu%s",
811: ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
812: ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
813: VTY_NEWLINE);
814:
815: vty_out (vty, " input errors %qu%s",
816: ifp->stats.ifi_ierrors, VTY_NEWLINE);
817:
818: vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
819: ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
820: ifp->stats.ifi_omcasts, VTY_NEWLINE);
821:
822: vty_out (vty, " output errors %qu%s",
823: ifp->stats.ifi_oerrors, VTY_NEWLINE);
824:
825: vty_out (vty, " collisions %qu%s",
826: ifp->stats.ifi_collisions, VTY_NEWLINE);
827: #else
828: /* Statistics print out using sysctl (). */
829: vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
830: " multicast packets %lu%s",
831: ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
832: ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
833: VTY_NEWLINE);
834:
835: vty_out (vty, " input errors %lu%s",
836: ifp->stats.ifi_ierrors, VTY_NEWLINE);
837:
838: vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
839: ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
840: ifp->stats.ifi_omcasts, VTY_NEWLINE);
841:
842: vty_out (vty, " output errors %lu%s",
843: ifp->stats.ifi_oerrors, VTY_NEWLINE);
844:
845: vty_out (vty, " collisions %lu%s",
846: ifp->stats.ifi_collisions, VTY_NEWLINE);
847: #endif /* __bsdi__ || __NetBSD__ */
848: #endif /* HAVE_NET_RT_IFLIST */
849: }
850:
851: /* Wrapper hook point for zebra daemon so that ifindex can be set
852: * DEFUN macro not used as extract.pl HAS to ignore this
853: * See also interface_cmd in lib/if.c
854: */
855: DEFUN_NOSH (zebra_interface,
856: zebra_interface_cmd,
857: "interface IFNAME",
858: "Select an interface to configure\n"
859: "Interface's name\n")
860: {
861: int ret;
862: struct interface * ifp;
863:
864: /* Call lib interface() */
865: if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
866: return ret;
867:
868: ifp = vty->index;
869:
870: if (ifp->ifindex == IFINDEX_INTERNAL)
871: /* Is this really necessary? Shouldn't status be initialized to 0
872: in that case? */
873: UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
874:
875: return ret;
876: }
877:
878: struct cmd_node interface_node =
879: {
880: INTERFACE_NODE,
881: "%s(config-if)# ",
882: 1
883: };
884:
885: /* Show all or specified interface to vty. */
886: DEFUN (show_interface, show_interface_cmd,
887: "show interface [IFNAME]",
888: SHOW_STR
889: "Interface status and configuration\n"
890: "Inteface name\n")
891: {
892: struct listnode *node;
893: struct interface *ifp;
894:
895: #ifdef HAVE_PROC_NET_DEV
896: /* If system has interface statistics via proc file system, update
897: statistics. */
898: ifstat_update_proc ();
899: #endif /* HAVE_PROC_NET_DEV */
900: #ifdef HAVE_NET_RT_IFLIST
901: ifstat_update_sysctl ();
902: #endif /* HAVE_NET_RT_IFLIST */
903:
904: /* Specified interface print. */
905: if (argc != 0)
906: {
907: ifp = if_lookup_by_name (argv[0]);
908: if (ifp == NULL)
909: {
910: vty_out (vty, "%% Can't find interface %s%s", argv[0],
911: VTY_NEWLINE);
912: return CMD_WARNING;
913: }
914: if_dump_vty (vty, ifp);
915: return CMD_SUCCESS;
916: }
917:
918: /* All interface print. */
919: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
920: if_dump_vty (vty, ifp);
921:
922: return CMD_SUCCESS;
923: }
924:
925: DEFUN (show_interface_desc,
926: show_interface_desc_cmd,
927: "show interface description",
928: SHOW_STR
929: "Interface status and configuration\n"
930: "Interface description\n")
931: {
932: struct listnode *node;
933: struct interface *ifp;
934:
935: vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
936: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
937: {
938: int len;
939:
940: len = vty_out (vty, "%s", ifp->name);
941: vty_out (vty, "%*s", (16 - len), " ");
942:
943: if (if_is_up(ifp))
944: {
945: vty_out (vty, "up ");
946: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
947: {
948: if (if_is_running(ifp))
949: vty_out (vty, "up ");
950: else
951: vty_out (vty, "down ");
952: }
953: else
954: {
955: vty_out (vty, "unknown ");
956: }
957: }
958: else
959: {
960: vty_out (vty, "down down ");
961: }
962:
963: if (ifp->desc)
964: vty_out (vty, "%s", ifp->desc);
965: vty_out (vty, "%s", VTY_NEWLINE);
966: }
967: return CMD_SUCCESS;
968: }
969:
970: DEFUN (multicast,
971: multicast_cmd,
972: "multicast",
973: "Set multicast flag to interface\n")
974: {
975: int ret;
976: struct interface *ifp;
977: struct zebra_if *if_data;
978:
979: ifp = (struct interface *) vty->index;
980: if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
981: {
982: ret = if_set_flags (ifp, IFF_MULTICAST);
983: if (ret < 0)
984: {
985: vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
986: return CMD_WARNING;
987: }
988: if_refresh (ifp);
989: }
990: if_data = ifp->info;
991: if_data->multicast = IF_ZEBRA_MULTICAST_ON;
992:
993: return CMD_SUCCESS;
994: }
995:
996: DEFUN (no_multicast,
997: no_multicast_cmd,
998: "no multicast",
999: NO_STR
1000: "Unset multicast flag to interface\n")
1001: {
1002: int ret;
1003: struct interface *ifp;
1004: struct zebra_if *if_data;
1005:
1006: ifp = (struct interface *) vty->index;
1007: if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1008: {
1009: ret = if_unset_flags (ifp, IFF_MULTICAST);
1010: if (ret < 0)
1011: {
1012: vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1013: return CMD_WARNING;
1014: }
1015: if_refresh (ifp);
1016: }
1017: if_data = ifp->info;
1018: if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1019:
1020: return CMD_SUCCESS;
1021: }
1022:
1023: DEFUN (linkdetect,
1024: linkdetect_cmd,
1025: "link-detect",
1026: "Enable link detection on interface\n")
1027: {
1028: struct interface *ifp;
1029: int if_was_operative;
1030:
1031: ifp = (struct interface *) vty->index;
1032: if_was_operative = if_is_operative(ifp);
1033: SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1034:
1035: /* When linkdetection is enabled, if might come down */
1036: if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1037:
1038: /* FIXME: Will defer status change forwarding if interface
1039: does not come down! */
1040:
1041: return CMD_SUCCESS;
1042: }
1043:
1044:
1045: DEFUN (no_linkdetect,
1046: no_linkdetect_cmd,
1047: "no link-detect",
1048: NO_STR
1049: "Disable link detection on interface\n")
1050: {
1051: struct interface *ifp;
1052: int if_was_operative;
1053:
1054: ifp = (struct interface *) vty->index;
1055: if_was_operative = if_is_operative(ifp);
1056: UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1057:
1058: /* Interface may come up after disabling link detection */
1059: if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1060:
1061: /* FIXME: see linkdetect_cmd */
1062:
1063: return CMD_SUCCESS;
1064: }
1065:
1066: DEFUN (shutdown_if,
1067: shutdown_if_cmd,
1068: "shutdown",
1069: "Shutdown the selected interface\n")
1070: {
1071: int ret;
1072: struct interface *ifp;
1073: struct zebra_if *if_data;
1074:
1075: ifp = (struct interface *) vty->index;
1076: ret = if_unset_flags (ifp, IFF_UP);
1077: if (ret < 0)
1078: {
1079: vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1080: return CMD_WARNING;
1081: }
1082: if_refresh (ifp);
1083: if_data = ifp->info;
1084: if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1085:
1086: return CMD_SUCCESS;
1087: }
1088:
1089: DEFUN (no_shutdown_if,
1090: no_shutdown_if_cmd,
1091: "no shutdown",
1092: NO_STR
1093: "Shutdown the selected interface\n")
1094: {
1095: int ret;
1096: struct interface *ifp;
1097: struct zebra_if *if_data;
1098:
1099: ifp = (struct interface *) vty->index;
1100: ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1101: if (ret < 0)
1102: {
1103: vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1104: return CMD_WARNING;
1105: }
1106: if_refresh (ifp);
1107: if_data = ifp->info;
1108: if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1109:
1110: return CMD_SUCCESS;
1111: }
1112:
1113: DEFUN (bandwidth_if,
1114: bandwidth_if_cmd,
1115: "bandwidth <1-10000000>",
1116: "Set bandwidth informational parameter\n"
1117: "Bandwidth in kilobits\n")
1118: {
1119: struct interface *ifp;
1120: unsigned int bandwidth;
1121:
1122: ifp = (struct interface *) vty->index;
1123: bandwidth = strtol(argv[0], NULL, 10);
1124:
1125: /* bandwidth range is <1-10000000> */
1126: if (bandwidth < 1 || bandwidth > 10000000)
1127: {
1128: vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1129: return CMD_WARNING;
1130: }
1131:
1132: ifp->bandwidth = bandwidth;
1133:
1134: /* force protocols to recalculate routes due to cost change */
1135: if (if_is_operative (ifp))
1136: zebra_interface_up_update (ifp);
1137:
1138: return CMD_SUCCESS;
1139: }
1140:
1141: DEFUN (no_bandwidth_if,
1142: no_bandwidth_if_cmd,
1143: "no bandwidth",
1144: NO_STR
1145: "Set bandwidth informational parameter\n")
1146: {
1147: struct interface *ifp;
1148:
1149: ifp = (struct interface *) vty->index;
1150:
1151: ifp->bandwidth = 0;
1152:
1153: /* force protocols to recalculate routes due to cost change */
1154: if (if_is_operative (ifp))
1155: zebra_interface_up_update (ifp);
1156:
1157: return CMD_SUCCESS;
1158: }
1159:
1160: ALIAS (no_bandwidth_if,
1161: no_bandwidth_if_val_cmd,
1162: "no bandwidth <1-10000000>",
1163: NO_STR
1164: "Set bandwidth informational parameter\n"
1165: "Bandwidth in kilobits\n")
1166:
1167: static int
1168: ip_address_install (struct vty *vty, struct interface *ifp,
1169: const char *addr_str, const char *peer_str,
1170: const char *label)
1171: {
1172: struct prefix_ipv4 cp;
1173: struct connected *ifc;
1174: struct prefix_ipv4 *p;
1175: int ret;
1176:
1177: ret = str2prefix_ipv4 (addr_str, &cp);
1178: if (ret <= 0)
1179: {
1180: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1181: return CMD_WARNING;
1182: }
1183:
1184: ifc = connected_check (ifp, (struct prefix *) &cp);
1185: if (! ifc)
1186: {
1187: ifc = connected_new ();
1188: ifc->ifp = ifp;
1189:
1190: /* Address. */
1191: p = prefix_ipv4_new ();
1192: *p = cp;
1193: ifc->address = (struct prefix *) p;
1194:
1195: /* Broadcast. */
1196: if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
1197: {
1198: p = prefix_ipv4_new ();
1199: *p = cp;
1200: p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
1201: ifc->destination = (struct prefix *) p;
1202: }
1203:
1204: /* Label. */
1205: if (label)
1206: ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
1207:
1208: /* Add to linked list. */
1209: listnode_add (ifp->connected, ifc);
1210: }
1211:
1212: /* This address is configured from zebra. */
1213: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1214: SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1215:
1216: /* In case of this route need to install kernel. */
1217: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1218: && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1219: {
1220: /* Some system need to up the interface to set IP address. */
1221: if (! if_is_up (ifp))
1222: {
1223: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1224: if_refresh (ifp);
1225: }
1226:
1227: ret = if_set_prefix (ifp, ifc);
1228: if (ret < 0)
1229: {
1230: vty_out (vty, "%% Can't set interface IP address: %s.%s",
1231: safe_strerror(errno), VTY_NEWLINE);
1232: return CMD_WARNING;
1233: }
1234:
1235: /* Add to subnet chain list (while marking secondary attribute). */
1236: if_subnet_add (ifp, ifc);
1237:
1238: /* IP address propery set. */
1239: SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1240:
1241: /* Update interface address information to protocol daemon. */
1242: zebra_interface_address_add_update (ifp, ifc);
1243:
1244: /* If interface is up register connected route. */
1245: if (if_is_operative(ifp))
1246: connected_up_ipv4 (ifp, ifc);
1247: }
1248:
1249: return CMD_SUCCESS;
1250: }
1251:
1252: static int
1253: ip_address_uninstall (struct vty *vty, struct interface *ifp,
1254: const char *addr_str, const char *peer_str,
1255: const char *label)
1256: {
1257: struct prefix_ipv4 cp;
1258: struct connected *ifc;
1259: int ret;
1260:
1261: /* Convert to prefix structure. */
1262: ret = str2prefix_ipv4 (addr_str, &cp);
1263: if (ret <= 0)
1264: {
1265: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1266: return CMD_WARNING;
1267: }
1268:
1269: /* Check current interface address. */
1270: ifc = connected_check (ifp, (struct prefix *) &cp);
1271: if (! ifc)
1272: {
1273: vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1274: return CMD_WARNING;
1275: }
1276:
1277: /* This is not configured address. */
1278: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1279: return CMD_WARNING;
1280:
1281: UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1282:
1283: /* This is not real address or interface is not active. */
1284: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1285: || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1286: {
1287: listnode_delete (ifp->connected, ifc);
1288: connected_free (ifc);
1289: return CMD_WARNING;
1290: }
1291:
1292: /* This is real route. */
1293: ret = if_unset_prefix (ifp, ifc);
1294: if (ret < 0)
1295: {
1296: vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1297: safe_strerror(errno), VTY_NEWLINE);
1298: return CMD_WARNING;
1299: }
1300:
1301: #if 0
1302: /* Redistribute this information. */
1303: zebra_interface_address_delete_update (ifp, ifc);
1304:
1305: /* Remove connected route. */
1306: connected_down_ipv4 (ifp, ifc);
1307:
1308: /* Free address information. */
1309: listnode_delete (ifp->connected, ifc);
1310: connected_free (ifc);
1311: #endif
1312:
1313: return CMD_SUCCESS;
1314: }
1315:
1316: DEFUN (ip_address,
1317: ip_address_cmd,
1318: "ip address A.B.C.D/M",
1319: "Interface Internet Protocol config commands\n"
1320: "Set the IP address of an interface\n"
1321: "IP address (e.g. 10.0.0.1/8)\n")
1322: {
1323: return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
1324: }
1325:
1326: DEFUN (no_ip_address,
1327: no_ip_address_cmd,
1328: "no ip address A.B.C.D/M",
1329: NO_STR
1330: "Interface Internet Protocol config commands\n"
1331: "Set the IP address of an interface\n"
1332: "IP Address (e.g. 10.0.0.1/8)")
1333: {
1334: return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
1335: }
1336:
1337: #ifdef HAVE_NETLINK
1338: DEFUN (ip_address_label,
1339: ip_address_label_cmd,
1340: "ip address A.B.C.D/M label LINE",
1341: "Interface Internet Protocol config commands\n"
1342: "Set the IP address of an interface\n"
1343: "IP address (e.g. 10.0.0.1/8)\n"
1344: "Label of this address\n"
1345: "Label\n")
1346: {
1347: return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
1348: }
1349:
1350: DEFUN (no_ip_address_label,
1351: no_ip_address_label_cmd,
1352: "no ip address A.B.C.D/M label LINE",
1353: NO_STR
1354: "Interface Internet Protocol config commands\n"
1355: "Set the IP address of an interface\n"
1356: "IP address (e.g. 10.0.0.1/8)\n"
1357: "Label of this address\n"
1358: "Label\n")
1359: {
1360: return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
1361: }
1362: #endif /* HAVE_NETLINK */
1363:
1364: #ifdef HAVE_IPV6
1365: static int
1366: ipv6_address_install (struct vty *vty, struct interface *ifp,
1367: const char *addr_str, const char *peer_str,
1368: const char *label, int secondary)
1369: {
1370: struct prefix_ipv6 cp;
1371: struct connected *ifc;
1372: struct prefix_ipv6 *p;
1373: int ret;
1374:
1375: ret = str2prefix_ipv6 (addr_str, &cp);
1376: if (ret <= 0)
1377: {
1378: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1379: return CMD_WARNING;
1380: }
1381:
1382: ifc = connected_check (ifp, (struct prefix *) &cp);
1383: if (! ifc)
1384: {
1385: ifc = connected_new ();
1386: ifc->ifp = ifp;
1387:
1388: /* Address. */
1389: p = prefix_ipv6_new ();
1390: *p = cp;
1391: ifc->address = (struct prefix *) p;
1392:
1393: /* Secondary. */
1394: if (secondary)
1395: SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1396:
1397: /* Label. */
1398: if (label)
1399: ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
1400:
1401: /* Add to linked list. */
1402: listnode_add (ifp->connected, ifc);
1403: }
1404:
1405: /* This address is configured from zebra. */
1406: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1407: SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1408:
1409: /* In case of this route need to install kernel. */
1410: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1411: && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1412: {
1413: /* Some system need to up the interface to set IP address. */
1414: if (! if_is_up (ifp))
1415: {
1416: if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1417: if_refresh (ifp);
1418: }
1419:
1420: ret = if_prefix_add_ipv6 (ifp, ifc);
1421:
1422: if (ret < 0)
1423: {
1424: vty_out (vty, "%% Can't set interface IP address: %s.%s",
1425: safe_strerror(errno), VTY_NEWLINE);
1426: return CMD_WARNING;
1427: }
1428:
1429: /* IP address propery set. */
1430: SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1431:
1432: /* Update interface address information to protocol daemon. */
1433: zebra_interface_address_add_update (ifp, ifc);
1434:
1435: /* If interface is up register connected route. */
1436: if (if_is_operative(ifp))
1437: connected_up_ipv6 (ifp, ifc);
1438: }
1439:
1440: return CMD_SUCCESS;
1441: }
1442:
1443: static int
1444: ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1445: const char *addr_str, const char *peer_str,
1446: const char *label, int secondry)
1447: {
1448: struct prefix_ipv6 cp;
1449: struct connected *ifc;
1450: int ret;
1451:
1452: /* Convert to prefix structure. */
1453: ret = str2prefix_ipv6 (addr_str, &cp);
1454: if (ret <= 0)
1455: {
1456: vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1457: return CMD_WARNING;
1458: }
1459:
1460: /* Check current interface address. */
1461: ifc = connected_check (ifp, (struct prefix *) &cp);
1462: if (! ifc)
1463: {
1464: vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1465: return CMD_WARNING;
1466: }
1467:
1468: /* This is not configured address. */
1469: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1470: return CMD_WARNING;
1471:
1472: /* This is not real address or interface is not active. */
1473: if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1474: || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1475: {
1476: listnode_delete (ifp->connected, ifc);
1477: connected_free (ifc);
1478: return CMD_WARNING;
1479: }
1480:
1481: /* This is real route. */
1482: ret = if_prefix_delete_ipv6 (ifp, ifc);
1483: if (ret < 0)
1484: {
1485: vty_out (vty, "%% Can't unset interface IP address: %s.%s",
1486: safe_strerror(errno), VTY_NEWLINE);
1487: return CMD_WARNING;
1488: }
1489:
1490: /* Redistribute this information. */
1491: zebra_interface_address_delete_update (ifp, ifc);
1492:
1493: /* Remove connected route. */
1494: connected_down_ipv6 (ifp, ifc);
1495:
1496: /* Free address information. */
1497: listnode_delete (ifp->connected, ifc);
1498: connected_free (ifc);
1499:
1500: return CMD_SUCCESS;
1501: }
1502:
1503: DEFUN (ipv6_address,
1504: ipv6_address_cmd,
1505: "ipv6 address X:X::X:X/M",
1506: "Interface IPv6 config commands\n"
1507: "Set the IP address of an interface\n"
1508: "IPv6 address (e.g. 3ffe:506::1/48)\n")
1509: {
1510: return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1511: }
1512:
1513: DEFUN (no_ipv6_address,
1514: no_ipv6_address_cmd,
1515: "no ipv6 address X:X::X:X/M",
1516: NO_STR
1517: "Interface IPv6 config commands\n"
1518: "Set the IP address of an interface\n"
1519: "IPv6 address (e.g. 3ffe:506::1/48)\n")
1520: {
1521: return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1522: }
1523: #endif /* HAVE_IPV6 */
1524:
1525: static int
1526: if_config_write (struct vty *vty)
1527: {
1528: struct listnode *node;
1529: struct interface *ifp;
1530:
1531: for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
1532: {
1533: struct zebra_if *if_data;
1534: struct listnode *addrnode;
1535: struct connected *ifc;
1536: struct prefix *p;
1537:
1538: if_data = ifp->info;
1539:
1540: vty_out (vty, "interface %s%s", ifp->name,
1541: VTY_NEWLINE);
1542:
1543: if (ifp->desc)
1544: vty_out (vty, " description %s%s", ifp->desc,
1545: VTY_NEWLINE);
1546:
1547: /* Assign bandwidth here to avoid unnecessary interface flap
1548: while processing config script */
1549: if (ifp->bandwidth != 0)
1550: vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1551:
1552: if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1553: vty_out(vty, " link-detect%s", VTY_NEWLINE);
1554:
1555: for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
1556: {
1557: if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1558: {
1559: char buf[INET6_ADDRSTRLEN];
1560: p = ifc->address;
1561: vty_out (vty, " ip%s address %s/%d",
1562: p->family == AF_INET ? "" : "v6",
1563: inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
1564: p->prefixlen);
1565:
1566: if (ifc->label)
1567: vty_out (vty, " label %s", ifc->label);
1568:
1569: vty_out (vty, "%s", VTY_NEWLINE);
1570: }
1571: }
1572:
1573: if (if_data)
1574: {
1575: if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1576: vty_out (vty, " shutdown%s", VTY_NEWLINE);
1577:
1578: if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1579: vty_out (vty, " %smulticast%s",
1580: if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1581: VTY_NEWLINE);
1582: }
1583:
1584: #ifdef RTADV
1585: rtadv_config_write (vty, ifp);
1586: #endif /* RTADV */
1587:
1588: #ifdef HAVE_IRDP
1589: irdp_config_write (vty, ifp);
1590: #endif /* IRDP */
1591:
1592: vty_out (vty, "!%s", VTY_NEWLINE);
1593: }
1594: return 0;
1595: }
1596:
1597: /* Allocate and initialize interface vector. */
1598: void
1599: zebra_if_init (void)
1600: {
1601: /* Initialize interface and new hook. */
1602: if_init ();
1603: if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1604: if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1605:
1606: /* Install configuration write function. */
1607: install_node (&interface_node, if_config_write);
1608:
1609: install_element (VIEW_NODE, &show_interface_cmd);
1610: install_element (ENABLE_NODE, &show_interface_cmd);
1611: install_element (ENABLE_NODE, &show_interface_desc_cmd);
1612: install_element (CONFIG_NODE, &zebra_interface_cmd);
1613: install_element (CONFIG_NODE, &no_interface_cmd);
1614: install_default (INTERFACE_NODE);
1615: install_element (INTERFACE_NODE, &interface_desc_cmd);
1616: install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1617: install_element (INTERFACE_NODE, &multicast_cmd);
1618: install_element (INTERFACE_NODE, &no_multicast_cmd);
1619: install_element (INTERFACE_NODE, &linkdetect_cmd);
1620: install_element (INTERFACE_NODE, &no_linkdetect_cmd);
1621: install_element (INTERFACE_NODE, &shutdown_if_cmd);
1622: install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1623: install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1624: install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1625: install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1626: install_element (INTERFACE_NODE, &ip_address_cmd);
1627: install_element (INTERFACE_NODE, &no_ip_address_cmd);
1628: #ifdef HAVE_IPV6
1629: install_element (INTERFACE_NODE, &ipv6_address_cmd);
1630: install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1631: #endif /* HAVE_IPV6 */
1632: #ifdef HAVE_NETLINK
1633: install_element (INTERFACE_NODE, &ip_address_label_cmd);
1634: install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
1635: #endif /* HAVE_NETLINK */
1636: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>