blob: 9cbbf937971b5c41eb8bc4054a0216adc2f64cc9 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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"
hassoca776982004-06-12 14:33:05 +000042#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000043
paul718e3742002-12-13 20:15:29 +000044
45/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000046static int
paul718e3742002-12-13 20:15:29 +000047if_zebra_new_hook (struct interface *ifp)
48{
49 struct zebra_if *zebra_if;
50
Stephen Hemminger393deb92008-08-18 14:13:29 -070051 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000052
53 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
54 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
55
56#ifdef RTADV
57 {
58 /* Set default router advertise values. */
59 struct rtadvconf *rtadv;
60
61 rtadv = &zebra_if->rtadv;
62
63 rtadv->AdvSendAdvertisements = 0;
64 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
65 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
66 rtadv->AdvIntervalTimer = 0;
67 rtadv->AdvManagedFlag = 0;
68 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000069 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000070 rtadv->AdvLinkMTU = 0;
71 rtadv->AdvReachableTime = 0;
72 rtadv->AdvRetransTimer = 0;
73 rtadv->AdvCurHopLimit = 0;
74 rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME;
vincent7cee1bb2005-03-25 13:08:53 +000075 rtadv->HomeAgentPreference = 0;
76 rtadv->HomeAgentLifetime = RTADV_ADV_DEFAULT_LIFETIME;
77 rtadv->AdvIntervalOption = 0;
paul718e3742002-12-13 20:15:29 +000078
79 rtadv->AdvPrefixList = list_new ();
80 }
81#endif /* RTADV */
82
hassoeef1fe12004-10-03 18:46:08 +000083 /* Initialize installed address chains tree. */
84 zebra_if->ipv4_subnets = route_table_init ();
85
paul718e3742002-12-13 20:15:29 +000086 ifp->info = zebra_if;
87 return 0;
88}
89
90/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000091static int
paul718e3742002-12-13 20:15:29 +000092if_zebra_delete_hook (struct interface *ifp)
93{
hassoeef1fe12004-10-03 18:46:08 +000094 struct zebra_if *zebra_if;
95
paul718e3742002-12-13 20:15:29 +000096 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +000097 {
98 zebra_if = ifp->info;
99
100 /* Free installed address chains tree. */
101 if (zebra_if->ipv4_subnets)
102 route_table_finish (zebra_if->ipv4_subnets);
103
104 XFREE (MTYPE_TMP, zebra_if);
105 }
106
107 return 0;
108}
109
110/* Tie an interface address to its derived subnet list of addresses. */
111int
112if_subnet_add (struct interface *ifp, struct connected *ifc)
113{
114 struct route_node *rn;
115 struct zebra_if *zebra_if;
116 struct prefix cp;
117 struct list *addr_list;
118
119 assert (ifp && ifp->info && ifc);
120 zebra_if = ifp->info;
121
122 /* Get address derived subnet node and associated address list, while marking
123 address secondary attribute appropriately. */
124 cp = *ifc->address;
125 apply_mask (&cp);
126 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
127
128 if ((addr_list = rn->info))
129 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
130 else
131 {
132 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
133 rn->info = addr_list = list_new ();
134 route_lock_node (rn);
135 }
136
137 /* Tie address at the tail of address list. */
138 listnode_add (addr_list, ifc);
139
140 /* Return list element count. */
141 return (addr_list->count);
142}
143
144/* Untie an interface address from its derived subnet list of addresses. */
145int
146if_subnet_delete (struct interface *ifp, struct connected *ifc)
147{
148 struct route_node *rn;
149 struct zebra_if *zebra_if;
150 struct list *addr_list;
151
152 assert (ifp && ifp->info && ifc);
153 zebra_if = ifp->info;
154
155 /* Get address derived subnet node. */
156 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
157 if (! (rn && rn->info))
158 return -1;
159 route_unlock_node (rn);
160
161 /* Untie address from subnet's address list. */
162 addr_list = rn->info;
163 listnode_delete (addr_list, ifc);
164 route_unlock_node (rn);
165
166 /* Return list element count, if not empty. */
167 if (addr_list->count)
168 {
169 /* If deleted address is primary, mark subsequent one as such and distribute. */
170 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
171 {
paul1eb8ef22005-04-07 07:30:20 +0000172 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000173 zebra_interface_address_delete_update (ifp, ifc);
174 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
175 zebra_interface_address_add_update (ifp, ifc);
176 }
177
178 return addr_list->count;
179 }
180
181 /* Otherwise, free list and route node. */
182 list_free (addr_list);
183 rn->info = NULL;
184 route_unlock_node (rn);
185
paul718e3742002-12-13 20:15:29 +0000186 return 0;
187}
188
paul5c78b3d2006-01-25 04:31:40 +0000189/* if_flags_mangle: A place for hacks that require mangling
190 * or tweaking the interface flags.
191 *
192 * ******************** Solaris flags hacks **************************
193 *
194 * Solaris IFF_UP flag reflects only the primary interface as the
195 * routing socket only sends IFINFO for the primary interface. Hence
196 * ~IFF_UP does not per se imply all the logical interfaces are also
197 * down - which we only know of as addresses. Instead we must determine
198 * whether the interface really is up or not according to how many
199 * addresses are still attached. (Solaris always sends RTM_DELADDR if
200 * an interface, logical or not, goes ~IFF_UP).
201 *
202 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
203 * are addresses left in struct connected, not just the actual underlying
204 * IFF_UP flag.
205 *
206 * We must hence remember the real state of IFF_UP, which we do in
207 * struct zebra_if.primary_state.
208 *
209 * Setting IFF_UP within zebra to administratively shutdown the
210 * interface will affect only the primary interface/address on Solaris.
211 ************************End Solaris flags hacks ***********************
212 */
213static inline void
214if_flags_mangle (struct interface *ifp, uint64_t *newflags)
215{
216#ifdef SUNOS_5
217 struct zebra_if *zif = ifp->info;
218
219 zif->primary_state = *newflags & (IFF_UP & 0xff);
220
221 if (CHECK_FLAG (zif->primary_state, IFF_UP)
222 || listcount(ifp->connected) > 0)
223 SET_FLAG (*newflags, IFF_UP);
224 else
225 UNSET_FLAG (*newflags, IFF_UP);
226#endif /* SUNOS_5 */
227}
228
229/* Update the flags field of the ifp with the new flag set provided.
230 * Take whatever actions are required for any changes in flags we care
231 * about.
232 *
233 * newflags should be the raw value, as obtained from the OS.
234 */
235void
236if_flags_update (struct interface *ifp, uint64_t newflags)
237{
238 if_flags_mangle (ifp, &newflags);
239
240 if (if_is_operative (ifp))
241 {
242 /* operative -> inoperative? */
243 ifp->flags = newflags;
244 if (!if_is_operative (ifp))
245 if_down (ifp);
246 }
247 else
248 {
249 /* inoperative -> operative? */
250 ifp->flags = newflags;
251 if (if_is_operative (ifp))
252 if_up (ifp);
253 }
254}
255
paul718e3742002-12-13 20:15:29 +0000256/* Wake up configured address if it is not in current kernel
257 address. */
paula1ac18c2005-06-28 17:17:12 +0000258static void
paul718e3742002-12-13 20:15:29 +0000259if_addr_wakeup (struct interface *ifp)
260{
paul1eb8ef22005-04-07 07:30:20 +0000261 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000262 struct connected *ifc;
263 struct prefix *p;
264 int ret;
265
paul1eb8ef22005-04-07 07:30:20 +0000266 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000267 {
paul718e3742002-12-13 20:15:29 +0000268 p = ifc->address;
269
270 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
271 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
272 {
273 /* Address check. */
274 if (p->family == AF_INET)
275 {
276 if (! if_is_up (ifp))
277 {
paul0752ef02005-11-03 12:35:21 +0000278 /* XXX: WTF is it trying to set flags here?
279 * caller has just gotten a new interface, has been
280 * handed the flags already. This code has no business
281 * trying to override administrative status of the interface.
282 * The only call path to here which doesn't originate from
283 * kernel event is irdp - what on earth is it trying to do?
284 *
285 * further RUNNING is not a settable flag on any system
286 * I (paulj) am aware of.
287 */
paul718e3742002-12-13 20:15:29 +0000288 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
289 if_refresh (ifp);
290 }
291
292 ret = if_set_prefix (ifp, ifc);
293 if (ret < 0)
294 {
295 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000296 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000297 continue;
298 }
hassoeef1fe12004-10-03 18:46:08 +0000299
300 /* Add to subnet chain list. */
301 if_subnet_add (ifp, ifc);
302
paul718e3742002-12-13 20:15:29 +0000303 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
304
305 zebra_interface_address_add_update (ifp, ifc);
306
paul2e3b2e42002-12-13 21:03:13 +0000307 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000308 connected_up_ipv4 (ifp, ifc);
309 }
310#ifdef HAVE_IPV6
311 if (p->family == AF_INET6)
312 {
313 if (! if_is_up (ifp))
314 {
paul0752ef02005-11-03 12:35:21 +0000315 /* XXX: See long comment above */
paul718e3742002-12-13 20:15:29 +0000316 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
317 if_refresh (ifp);
318 }
319
320 ret = if_prefix_add_ipv6 (ifp, ifc);
321 if (ret < 0)
322 {
323 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000324 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000325 continue;
326 }
327 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
328
329 zebra_interface_address_add_update (ifp, ifc);
330
paul2e3b2e42002-12-13 21:03:13 +0000331 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000332 connected_up_ipv6 (ifp, ifc);
333 }
334#endif /* HAVE_IPV6 */
335 }
336 }
337}
338
339/* Handle interface addition */
340void
341if_add_update (struct interface *ifp)
342{
paul48b33aa2002-12-13 20:52:52 +0000343 struct zebra_if *if_data;
344
345 if_data = ifp->info;
346 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
347 if_set_flags (ifp, IFF_MULTICAST);
348 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
349 if_unset_flags (ifp, IFF_MULTICAST);
350
paul718e3742002-12-13 20:15:29 +0000351 zebra_interface_add_update (ifp);
352
353 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
354 {
355 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
356
357 if_addr_wakeup (ifp);
358
359 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000360 zlog_debug ("interface %s index %d becomes active.",
361 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000362 }
363 else
364 {
365 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000366 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000367 }
368}
369
paul6eb88272005-07-29 14:36:00 +0000370/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000371void
372if_delete_update (struct interface *ifp)
373{
paul718e3742002-12-13 20:15:29 +0000374 struct connected *ifc;
375 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000376 struct route_node *rn;
377 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000378
379 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000380
381 if (if_is_up(ifp))
382 {
383 zlog_err ("interface %s index %d is still up while being deleted.",
384 ifp->name, ifp->ifindex);
385 return;
386 }
387
388 /* Mark interface as inactive */
389 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
390
391 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000392 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000393 ifp->name, ifp->ifindex);
394
395 /* Delete connected routes from the kernel. */
396 if (ifp->connected)
397 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000398 struct listnode *node;
399 struct listnode *last = NULL;
400
hassoeef1fe12004-10-03 18:46:08 +0000401 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000402 {
paul1eb8ef22005-04-07 07:30:20 +0000403 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000404 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000405
Paul Jakmabeb56332006-05-11 13:28:05 +0000406 if (p->family == AF_INET
407 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000408 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000409 struct listnode *anode;
410 struct listnode *next;
411 struct listnode *first;
412 struct list *addr_list;
413
hassoeef1fe12004-10-03 18:46:08 +0000414 route_unlock_node (rn);
415 addr_list = (struct list *) rn->info;
416
417 /* Remove addresses, secondaries first. */
418 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000419 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000420 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000421 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000422 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000423 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000424 first = NULL;
425 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000426 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000427
Paul Jakmad9a18f12007-04-10 19:30:20 +0000428 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000429 p = ifc->address;
430
431 connected_down_ipv4 (ifp, ifc);
432
433 zebra_interface_address_delete_update (ifp, ifc);
434
435 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
436
437 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000438 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000439 route_unlock_node (rn);
440
441 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000442 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
443 {
444 listnode_delete (ifp->connected, ifc);
445 connected_free (ifc);
446 }
447 else
448 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000449 }
450
451 /* Free chain list and respective route node. */
452 list_delete (addr_list);
453 rn->info = NULL;
454 route_unlock_node (rn);
455 }
paul718e3742002-12-13 20:15:29 +0000456#ifdef HAVE_IPV6
457 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000458 {
459 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000460
hassoeef1fe12004-10-03 18:46:08 +0000461 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000462
hassoeef1fe12004-10-03 18:46:08 +0000463 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
464
465 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
466 last = node;
467 else
468 {
469 listnode_delete (ifp->connected, ifc);
470 connected_free (ifc);
471 }
paul718e3742002-12-13 20:15:29 +0000472 }
hassoeef1fe12004-10-03 18:46:08 +0000473#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +0000474 }
475 }
476 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000477
478 /* Update ifindex after distributing the delete message. This is in
479 case any client needs to have the old value of ifindex available
480 while processing the deletion. Each client daemon is responsible
481 for setting ifindex to IFINDEX_INTERNAL after processing the
482 interface deletion message. */
483 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000484}
485
486/* Interface is up. */
487void
488if_up (struct interface *ifp)
489{
hasso52dc7ee2004-09-23 19:18:23 +0000490 struct listnode *node;
491 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000492 struct connected *ifc;
493 struct prefix *p;
494
495 /* Notify the protocol daemons. */
496 zebra_interface_up_update (ifp);
497
498 /* Install connected routes to the kernel. */
499 if (ifp->connected)
500 {
paul1eb8ef22005-04-07 07:30:20 +0000501 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000502 {
paul718e3742002-12-13 20:15:29 +0000503 p = ifc->address;
504
505 if (p->family == AF_INET)
506 connected_up_ipv4 (ifp, ifc);
507#ifdef HAVE_IPV6
508 else if (p->family == AF_INET6)
509 connected_up_ipv6 (ifp, ifc);
510#endif /* HAVE_IPV6 */
511 }
512 }
513
514 /* Examine all static routes. */
515 rib_update ();
516}
517
518/* Interface goes down. We have to manage different behavior of based
519 OS. */
520void
521if_down (struct interface *ifp)
522{
hasso52dc7ee2004-09-23 19:18:23 +0000523 struct listnode *node;
524 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000525 struct connected *ifc;
526 struct prefix *p;
527
528 /* Notify to the protocol daemons. */
529 zebra_interface_down_update (ifp);
530
531 /* Delete connected routes from the kernel. */
532 if (ifp->connected)
533 {
paul1eb8ef22005-04-07 07:30:20 +0000534 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000535 {
paul718e3742002-12-13 20:15:29 +0000536 p = ifc->address;
537
538 if (p->family == AF_INET)
539 connected_down_ipv4 (ifp, ifc);
540#ifdef HAVE_IPV6
541 else if (p->family == AF_INET6)
542 connected_down_ipv6 (ifp, ifc);
543#endif /* HAVE_IPV6 */
544 }
545 }
546
547 /* Examine all static routes which direct to the interface. */
548 rib_update ();
549}
550
551void
552if_refresh (struct interface *ifp)
553{
paul5c78b3d2006-01-25 04:31:40 +0000554 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000555}
556
paul718e3742002-12-13 20:15:29 +0000557/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000558static int
paul718e3742002-12-13 20:15:29 +0000559prefix_vty_out (struct vty *vty, struct prefix *p)
560{
561 char str[INET6_ADDRSTRLEN];
562
563 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
564 vty_out (vty, "%s", str);
565 return strlen (str);
566}
567
568/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000569static void
paul718e3742002-12-13 20:15:29 +0000570connected_dump_vty (struct vty *vty, struct connected *connected)
571{
572 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000573
574 /* Print interface address. */
575 p = connected->address;
576 vty_out (vty, " %s ", prefix_family_str (p));
577 prefix_vty_out (vty, p);
578 vty_out (vty, "/%d", p->prefixlen);
579
580 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000581 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000582 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000583 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
584 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000585 }
586
587 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
588 vty_out (vty, " secondary");
589
590 if (connected->label)
591 vty_out (vty, " %s", connected->label);
592
593 vty_out (vty, "%s", VTY_NEWLINE);
594}
595
596#ifdef RTADV
597/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000598static void
paul718e3742002-12-13 20:15:29 +0000599nd_dump_vty (struct vty *vty, struct interface *ifp)
600{
601 struct zebra_if *zif;
602 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000603 int interval;
paul718e3742002-12-13 20:15:29 +0000604
605 zif = (struct zebra_if *) ifp->info;
606 rtadv = &zif->rtadv;
607
608 if (rtadv->AdvSendAdvertisements)
609 {
610 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
611 rtadv->AdvReachableTime, VTY_NEWLINE);
612 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
613 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000614 interval = rtadv->MaxRtrAdvInterval;
615 if (interval % 1000)
616 vty_out (vty, " ND router advertisements are sent every "
617 "%d milliseconds%s", interval,
618 VTY_NEWLINE);
619 else
620 vty_out (vty, " ND router advertisements are sent every "
621 "%d seconds%s", interval / 1000,
622 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000623 vty_out (vty, " ND router advertisements live for %d seconds%s",
624 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
625 if (rtadv->AdvManagedFlag)
626 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
627 VTY_NEWLINE);
628 else
629 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
630 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000631 if (rtadv->AdvHomeAgentFlag)
632 vty_out (vty, " ND router advertisements with "
633 "Home Agent flag bit set.%s",
634 VTY_NEWLINE);
635 if (rtadv->AdvIntervalOption)
636 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
637 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000638 }
639}
640#endif /* RTADV */
641
642/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000643static void
paul718e3742002-12-13 20:15:29 +0000644if_dump_vty (struct vty *vty, struct interface *ifp)
645{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000646#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000647 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000648#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000649 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000650 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000651 struct route_node *rn;
652 struct zebra_if *zebra_if;
653
654 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000655
paul2e3b2e42002-12-13 21:03:13 +0000656 vty_out (vty, "Interface %s is ", ifp->name);
657 if (if_is_up(ifp)) {
658 vty_out (vty, "up, line protocol ");
659
660 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
661 if (if_is_running(ifp))
662 vty_out (vty, "is up%s", VTY_NEWLINE);
663 else
664 vty_out (vty, "is down%s", VTY_NEWLINE);
665 } else {
666 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
667 }
668 } else {
669 vty_out (vty, "down%s", VTY_NEWLINE);
670 }
671
paul718e3742002-12-13 20:15:29 +0000672 if (ifp->desc)
673 vty_out (vty, " Description: %s%s", ifp->desc,
674 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000675 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000676 {
ajsd2fc8892005-04-02 18:38:43 +0000677 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000678 return;
679 }
680 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
681 {
682 vty_out(vty, " index %d inactive interface%s",
683 ifp->ifindex,
684 VTY_NEWLINE);
685 return;
686 }
687
688 vty_out (vty, " index %d metric %d mtu %d ",
689 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000690#ifdef HAVE_IPV6
691 if (ifp->mtu6 != ifp->mtu)
692 vty_out (vty, "mtu6 %d ", ifp->mtu6);
693#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000694 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
695 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000696
paul718e3742002-12-13 20:15:29 +0000697 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000698#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000699 sdl = &ifp->sdl;
700 if (sdl != NULL && sdl->sdl_alen != 0)
701 {
702 int i;
703 u_char *ptr;
704
705 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000706 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
707 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000708 vty_out (vty, "%s", VTY_NEWLINE);
709 }
710#else
711 if (ifp->hw_addr_len != 0)
712 {
713 int i;
714
715 vty_out (vty, " HWaddr: ");
716 for (i = 0; i < ifp->hw_addr_len; i++)
717 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
718 vty_out (vty, "%s", VTY_NEWLINE);
719 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000720#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000721
722 /* Bandwidth in kbps */
723 if (ifp->bandwidth != 0)
724 {
725 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
726 vty_out(vty, "%s", VTY_NEWLINE);
727 }
728
hassoeef1fe12004-10-03 18:46:08 +0000729 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000730 {
hassoeef1fe12004-10-03 18:46:08 +0000731 if (! rn->info)
732 continue;
733
paul1eb8ef22005-04-07 07:30:20 +0000734 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
735 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000736 }
737
paul1eb8ef22005-04-07 07:30:20 +0000738 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000739 {
hasso39db97e2004-10-12 20:50:58 +0000740 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
741 (connected->address->family == AF_INET6))
742 connected_dump_vty (vty, connected);
743 }
744
paul718e3742002-12-13 20:15:29 +0000745#ifdef RTADV
746 nd_dump_vty (vty, ifp);
747#endif /* RTADV */
748
749#ifdef HAVE_PROC_NET_DEV
750 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000751 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
752 "%lu dropped%s",
753 ifp->stats.rx_packets, ifp->stats.rx_multicast,
754 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000755
hasso6f2c27a2005-01-18 13:44:35 +0000756 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000757 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000758 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
759 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000760 ifp->stats.rx_frame_errors, VTY_NEWLINE);
761
762 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000763 ifp->stats.rx_missed_errors, VTY_NEWLINE);
764
hasso6f2c27a2005-01-18 13:44:35 +0000765 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000766 ifp->stats.tx_packets, ifp->stats.tx_bytes,
767 ifp->stats.tx_dropped, VTY_NEWLINE);
768
hasso6f2c27a2005-01-18 13:44:35 +0000769 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
770 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000771 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
772 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000773 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000774
hasso6f2c27a2005-01-18 13:44:35 +0000775 vty_out (vty, " %lu window, %lu collisions%s",
776 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000777#endif /* HAVE_PROC_NET_DEV */
778
779#ifdef HAVE_NET_RT_IFLIST
780#if defined (__bsdi__) || defined (__NetBSD__)
781 /* Statistics print out using sysctl (). */
782 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
783 " multicast packets %qu%s",
784 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
785 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
786 VTY_NEWLINE);
787
788 vty_out (vty, " input errors %qu%s",
789 ifp->stats.ifi_ierrors, VTY_NEWLINE);
790
791 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
792 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
793 ifp->stats.ifi_omcasts, VTY_NEWLINE);
794
795 vty_out (vty, " output errors %qu%s",
796 ifp->stats.ifi_oerrors, VTY_NEWLINE);
797
798 vty_out (vty, " collisions %qu%s",
799 ifp->stats.ifi_collisions, VTY_NEWLINE);
800#else
801 /* Statistics print out using sysctl (). */
802 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
803 " multicast packets %lu%s",
804 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
805 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
806 VTY_NEWLINE);
807
808 vty_out (vty, " input errors %lu%s",
809 ifp->stats.ifi_ierrors, VTY_NEWLINE);
810
811 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
812 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
813 ifp->stats.ifi_omcasts, VTY_NEWLINE);
814
815 vty_out (vty, " output errors %lu%s",
816 ifp->stats.ifi_oerrors, VTY_NEWLINE);
817
818 vty_out (vty, " collisions %lu%s",
819 ifp->stats.ifi_collisions, VTY_NEWLINE);
820#endif /* __bsdi__ || __NetBSD__ */
821#endif /* HAVE_NET_RT_IFLIST */
822}
823
824/* Check supported address family. */
paula1ac18c2005-06-28 17:17:12 +0000825static int
paul718e3742002-12-13 20:15:29 +0000826if_supported_family (int family)
827{
828 if (family == AF_INET)
829 return 1;
830#ifdef HAVE_IPV6
831 if (family == AF_INET6)
832 return 1;
833#endif /* HAVE_IPV6 */
834 return 0;
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 */
841DEFUN_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() */
ajsd2fc8892005-04-02 18:38:43 +0000851 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
852 return ret;
paul718e3742002-12-13 20:15:29 +0000853
854 ifp = vty->index;
855
ajsd2fc8892005-04-02 18:38:43 +0000856 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);
paul718e3742002-12-13 20:15:29 +0000860
861 return ret;
862}
863
paul718e3742002-12-13 20:15:29 +0000864struct cmd_node interface_node =
865{
866 INTERFACE_NODE,
867 "%s(config-if)# ",
868 1
869};
870
871/* Show all or specified interface to vty. */
872DEFUN (show_interface, show_interface_cmd,
873 "show interface [IFNAME]",
874 SHOW_STR
875 "Interface status and configuration\n"
876 "Inteface name\n")
877{
hasso52dc7ee2004-09-23 19:18:23 +0000878 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000879 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. */
paul1eb8ef22005-04-07 07:30:20 +0000905 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
906 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000907
908 return CMD_SUCCESS;
909}
910
hassoed9bb6d2005-03-13 19:17:21 +0000911DEFUN (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);
paul1eb8ef22005-04-07 07:30:20 +0000922 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000923 {
924 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000925
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
paul718e3742002-12-13 20:15:29 +0000956DEFUN (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;
paul48b33aa2002-12-13 20:52:52 +0000966 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000967 {
paul48b33aa2002-12-13 20:52:52 +0000968 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);
paul718e3742002-12-13 20:15:29 +0000975 }
paul718e3742002-12-13 20:15:29 +0000976 if_data = ifp->info;
977 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000978
paul718e3742002-12-13 20:15:29 +0000979 return CMD_SUCCESS;
980}
981
982DEFUN (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;
paul48b33aa2002-12-13 20:52:52 +0000993 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000994 {
paul48b33aa2002-12-13 20:52:52 +0000995 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);
paul718e3742002-12-13 20:15:29 +00001002 }
paul718e3742002-12-13 20:15:29 +00001003 if_data = ifp->info;
1004 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1005
1006 return CMD_SUCCESS;
1007}
1008
paul2e3b2e42002-12-13 21:03:13 +00001009DEFUN (linkdetect,
1010 linkdetect_cmd,
1011 "link-detect",
1012 "Enable link detection on interface\n")
1013{
paul2e3b2e42002-12-13 21:03:13 +00001014 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
1031DEFUN (no_linkdetect,
1032 no_linkdetect_cmd,
1033 "no link-detect",
1034 NO_STR
1035 "Disable link detection on interface\n")
1036{
paul2e3b2e42002-12-13 21:03:13 +00001037 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
paul718e3742002-12-13 20:15:29 +00001052DEFUN (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
1075DEFUN (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
1099DEFUN (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 */
paul2e3b2e42002-12-13 21:03:13 +00001121 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001122 zebra_interface_up_update (ifp);
1123
1124 return CMD_SUCCESS;
1125}
1126
1127DEFUN (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 */
paul2e3b2e42002-12-13 21:03:13 +00001140 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001141 zebra_interface_up_update (ifp);
1142
1143 return CMD_SUCCESS;
1144}
1145
1146ALIAS (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
paula1ac18c2005-06-28 17:17:12 +00001153static int
hasso39db97e2004-10-12 20:50:58 +00001154ip_address_install (struct vty *vty, struct interface *ifp,
1155 const char *addr_str, const char *peer_str,
1156 const char *label)
paul718e3742002-12-13 20:15:29 +00001157{
1158 struct prefix_ipv4 cp;
1159 struct connected *ifc;
1160 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001161 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
paulca162182005-09-12 16:58:52 +00001170 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001171 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. */
hasso3fb9cd62004-10-19 19:44:43 +00001182 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001183 {
1184 p = prefix_ipv4_new ();
1185 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001186 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001187 ifc->destination = (struct prefix *) p;
1188 }
1189
paul718e3742002-12-13 20:15:29 +00001190 /* Label. */
1191 if (label)
paul0752ef02005-11-03 12:35:21 +00001192 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001193
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",
ajs6099b3b2004-11-20 02:06:59 +00001217 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001218 return CMD_WARNING;
1219 }
1220
hassoeef1fe12004-10-03 18:46:08 +00001221 /* Add to subnet chain list (while marking secondary attribute). */
1222 if_subnet_add (ifp, ifc);
1223
paul718e3742002-12-13 20:15:29 +00001224 /* 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. */
paul2e3b2e42002-12-13 21:03:13 +00001231 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001232 connected_up_ipv4 (ifp, ifc);
1233 }
1234
1235 return CMD_SUCCESS;
1236}
1237
paula1ac18c2005-06-28 17:17:12 +00001238static int
hasso39db97e2004-10-12 20:50:58 +00001239ip_address_uninstall (struct vty *vty, struct interface *ifp,
1240 const char *addr_str, const char *peer_str,
1241 const char *label)
paul718e3742002-12-13 20:15:29 +00001242{
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. */
paulca162182005-09-12 16:58:52 +00001256 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001257 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
Paul Jakma74ecdc92006-06-15 18:10:47 +00001267 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1268
paul718e3742002-12-13 20:15:29 +00001269 /* 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",
ajs6099b3b2004-11-20 02:06:59 +00001283 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001284 return CMD_WARNING;
1285 }
1286
hassoeef1fe12004-10-03 18:46:08 +00001287#if 0
paul718e3742002-12-13 20:15:29 +00001288 /* 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);
hassoeef1fe12004-10-03 18:46:08 +00001297#endif
paul718e3742002-12-13 20:15:29 +00001298
1299 return CMD_SUCCESS;
1300}
1301
1302DEFUN (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{
hassoeef1fe12004-10-03 18:46:08 +00001309 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001310}
1311
1312DEFUN (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{
hassoeef1fe12004-10-03 18:46:08 +00001320 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001321}
1322
1323#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001324DEFUN (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{
hassoeef1fe12004-10-03 18:46:08 +00001333 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001334}
1335
1336DEFUN (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{
hassoeef1fe12004-10-03 18:46:08 +00001346 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001347}
1348#endif /* HAVE_NETLINK */
1349
1350#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001351static int
hasso39db97e2004-10-12 20:50:58 +00001352ipv6_address_install (struct vty *vty, struct interface *ifp,
1353 const char *addr_str, const char *peer_str,
1354 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001355{
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
paulca162182005-09-12 16:58:52 +00001368 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001369 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)
paul0752ef02005-11-03 12:35:21 +00001385 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001386
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",
ajs6099b3b2004-11-20 02:06:59 +00001411 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001412 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. */
paul2e3b2e42002-12-13 21:03:13 +00001422 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001423 connected_up_ipv6 (ifp, ifc);
1424 }
1425
1426 return CMD_SUCCESS;
1427}
1428
paula1ac18c2005-06-28 17:17:12 +00001429static int
hasso39db97e2004-10-12 20:50:58 +00001430ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1431 const char *addr_str, const char *peer_str,
1432 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001433{
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. */
paulca162182005-09-12 16:58:52 +00001447 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001448 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",
ajs6099b3b2004-11-20 02:06:59 +00001472 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001473 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
1489DEFUN (ipv6_address,
1490 ipv6_address_cmd,
1491 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001492 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001493 "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
1499DEFUN (no_ipv6_address,
1500 no_ipv6_address_cmd,
1501 "no ipv6 address X:X::X:X/M",
1502 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001503 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001504 "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
paula1ac18c2005-06-28 17:17:12 +00001511static int
paul718e3742002-12-13 20:15:29 +00001512if_config_write (struct vty *vty)
1513{
hasso52dc7ee2004-09-23 19:18:23 +00001514 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001515 struct interface *ifp;
1516 char buf[BUFSIZ];
1517
paul1eb8ef22005-04-07 07:30:20 +00001518 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001519 {
1520 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001521 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001522 struct connected *ifc;
1523 struct prefix *p;
1524
paul718e3742002-12-13 20:15:29 +00001525 if_data = ifp->info;
1526
1527 vty_out (vty, "interface %s%s", ifp->name,
1528 VTY_NEWLINE);
1529
1530 if (ifp->desc)
1531 vty_out (vty, " description %s%s", ifp->desc,
1532 VTY_NEWLINE);
1533
1534 /* Assign bandwidth here to avoid unnecessary interface flap
1535 while processing config script */
1536 if (ifp->bandwidth != 0)
1537 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1538
paul2e3b2e42002-12-13 21:03:13 +00001539 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1540 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1541
paul1eb8ef22005-04-07 07:30:20 +00001542 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001543 {
paul718e3742002-12-13 20:15:29 +00001544 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1545 {
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, BUFSIZ),
1550 p->prefixlen);
1551
paul718e3742002-12-13 20:15:29 +00001552 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
hassoca776982004-06-12 14:33:05 +00001574#ifdef HAVE_IRDP
1575 irdp_config_write (vty, ifp);
1576#endif /* IRDP */
1577
paul718e3742002-12-13 20:15:29 +00001578 vty_out (vty, "!%s", VTY_NEWLINE);
1579 }
1580 return 0;
1581}
1582
1583/* Allocate and initialize interface vector. */
1584void
paula1ac18c2005-06-28 17:17:12 +00001585zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001586{
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);
hassoed9bb6d2005-03-13 19:17:21 +00001597 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001598 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001599 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001600 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);
paul2e3b2e42002-12-13 21:03:13 +00001605 install_element (INTERFACE_NODE, &linkdetect_cmd);
1606 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001607 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 */
paul718e3742002-12-13 20:15:29 +00001618#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001619 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001620 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001621#endif /* HAVE_NETLINK */
1622}