blob: 470df0cdd432fdb6c72e01a71b3b8453f95637d4 [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
Chris Caputob60668d2009-05-03 04:40:57 +000044#ifdef RTADV
45/* Order is intentional. Matches RFC4191. This array is also used for
46 command matching, so only modify with care. */
47const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
48#endif /* RTADV */
paul718e3742002-12-13 20:15:29 +000049
50/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000051static int
paul718e3742002-12-13 20:15:29 +000052if_zebra_new_hook (struct interface *ifp)
53{
54 struct zebra_if *zebra_if;
55
Stephen Hemminger393deb92008-08-18 14:13:29 -070056 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000057
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;
vincent7cee1bb2005-03-25 13:08:53 +000074 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000075 rtadv->AdvLinkMTU = 0;
76 rtadv->AdvReachableTime = 0;
77 rtadv->AdvRetransTimer = 0;
78 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040079 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +000080 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040081 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +000082 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +000083 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +000084
85 rtadv->AdvPrefixList = list_new ();
86 }
87#endif /* RTADV */
88
hassoeef1fe12004-10-03 18:46:08 +000089 /* Initialize installed address chains tree. */
90 zebra_if->ipv4_subnets = route_table_init ();
91
paul718e3742002-12-13 20:15:29 +000092 ifp->info = zebra_if;
93 return 0;
94}
95
96/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000097static int
paul718e3742002-12-13 20:15:29 +000098if_zebra_delete_hook (struct interface *ifp)
99{
hassoeef1fe12004-10-03 18:46:08 +0000100 struct zebra_if *zebra_if;
101
paul718e3742002-12-13 20:15:29 +0000102 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000103 {
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. */
117int
118if_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. */
151int
152if_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))
Christian Franke9db047f2013-01-24 14:04:44 +0000164 {
165 zlog_warn("Trying to remove an address from an unknown subnet."
166 " (please report this bug)");
167 return -1;
168 }
hassoeef1fe12004-10-03 18:46:08 +0000169 route_unlock_node (rn);
170
171 /* Untie address from subnet's address list. */
172 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000173
174 /* Deleting an address that is not registered is a bug.
175 * In any case, we shouldn't decrement the lock counter if the address
176 * is unknown. */
177 if (!listnode_lookup(addr_list, ifc))
178 {
179 zlog_warn("Trying to remove an address from a subnet where it is not"
180 " currently registered. (please report this bug)");
181 return -1;
182 }
183
hassoeef1fe12004-10-03 18:46:08 +0000184 listnode_delete (addr_list, ifc);
185 route_unlock_node (rn);
186
187 /* Return list element count, if not empty. */
188 if (addr_list->count)
189 {
190 /* If deleted address is primary, mark subsequent one as such and distribute. */
191 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
192 {
paul1eb8ef22005-04-07 07:30:20 +0000193 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000194 zebra_interface_address_delete_update (ifp, ifc);
195 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
196 zebra_interface_address_add_update (ifp, ifc);
197 }
198
199 return addr_list->count;
200 }
201
202 /* Otherwise, free list and route node. */
203 list_free (addr_list);
204 rn->info = NULL;
205 route_unlock_node (rn);
206
paul718e3742002-12-13 20:15:29 +0000207 return 0;
208}
209
paul5c78b3d2006-01-25 04:31:40 +0000210/* if_flags_mangle: A place for hacks that require mangling
211 * or tweaking the interface flags.
212 *
213 * ******************** Solaris flags hacks **************************
214 *
215 * Solaris IFF_UP flag reflects only the primary interface as the
216 * routing socket only sends IFINFO for the primary interface. Hence
217 * ~IFF_UP does not per se imply all the logical interfaces are also
218 * down - which we only know of as addresses. Instead we must determine
219 * whether the interface really is up or not according to how many
220 * addresses are still attached. (Solaris always sends RTM_DELADDR if
221 * an interface, logical or not, goes ~IFF_UP).
222 *
223 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
224 * are addresses left in struct connected, not just the actual underlying
225 * IFF_UP flag.
226 *
227 * We must hence remember the real state of IFF_UP, which we do in
228 * struct zebra_if.primary_state.
229 *
230 * Setting IFF_UP within zebra to administratively shutdown the
231 * interface will affect only the primary interface/address on Solaris.
232 ************************End Solaris flags hacks ***********************
233 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100234static void
paul5c78b3d2006-01-25 04:31:40 +0000235if_flags_mangle (struct interface *ifp, uint64_t *newflags)
236{
237#ifdef SUNOS_5
238 struct zebra_if *zif = ifp->info;
239
240 zif->primary_state = *newflags & (IFF_UP & 0xff);
241
242 if (CHECK_FLAG (zif->primary_state, IFF_UP)
243 || listcount(ifp->connected) > 0)
244 SET_FLAG (*newflags, IFF_UP);
245 else
246 UNSET_FLAG (*newflags, IFF_UP);
247#endif /* SUNOS_5 */
248}
249
250/* Update the flags field of the ifp with the new flag set provided.
251 * Take whatever actions are required for any changes in flags we care
252 * about.
253 *
254 * newflags should be the raw value, as obtained from the OS.
255 */
256void
257if_flags_update (struct interface *ifp, uint64_t newflags)
258{
259 if_flags_mangle (ifp, &newflags);
260
261 if (if_is_operative (ifp))
262 {
263 /* operative -> inoperative? */
264 ifp->flags = newflags;
265 if (!if_is_operative (ifp))
266 if_down (ifp);
267 }
268 else
269 {
270 /* inoperative -> operative? */
271 ifp->flags = newflags;
272 if (if_is_operative (ifp))
273 if_up (ifp);
274 }
275}
276
paul718e3742002-12-13 20:15:29 +0000277/* Wake up configured address if it is not in current kernel
278 address. */
paula1ac18c2005-06-28 17:17:12 +0000279static void
paul718e3742002-12-13 20:15:29 +0000280if_addr_wakeup (struct interface *ifp)
281{
paul1eb8ef22005-04-07 07:30:20 +0000282 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000283 struct connected *ifc;
284 struct prefix *p;
285 int ret;
286
paul1eb8ef22005-04-07 07:30:20 +0000287 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000288 {
paul718e3742002-12-13 20:15:29 +0000289 p = ifc->address;
290
291 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000292 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000293 {
294 /* Address check. */
295 if (p->family == AF_INET)
296 {
297 if (! if_is_up (ifp))
298 {
paul0752ef02005-11-03 12:35:21 +0000299 /* XXX: WTF is it trying to set flags here?
300 * caller has just gotten a new interface, has been
301 * handed the flags already. This code has no business
302 * trying to override administrative status of the interface.
303 * The only call path to here which doesn't originate from
304 * kernel event is irdp - what on earth is it trying to do?
305 *
306 * further RUNNING is not a settable flag on any system
307 * I (paulj) am aware of.
308 */
paul718e3742002-12-13 20:15:29 +0000309 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
310 if_refresh (ifp);
311 }
312
313 ret = if_set_prefix (ifp, ifc);
314 if (ret < 0)
315 {
316 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000317 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000318 continue;
319 }
hassoeef1fe12004-10-03 18:46:08 +0000320
321 /* Add to subnet chain list. */
322 if_subnet_add (ifp, ifc);
323
Christian Frankef7f740f2013-01-24 14:04:48 +0000324 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
paul718e3742002-12-13 20:15:29 +0000325 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
326
327 zebra_interface_address_add_update (ifp, ifc);
328
paul2e3b2e42002-12-13 21:03:13 +0000329 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000330 connected_up_ipv4 (ifp, ifc);
331 }
332#ifdef HAVE_IPV6
333 if (p->family == AF_INET6)
334 {
335 if (! if_is_up (ifp))
336 {
paul0752ef02005-11-03 12:35:21 +0000337 /* XXX: See long comment above */
paul718e3742002-12-13 20:15:29 +0000338 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
339 if_refresh (ifp);
340 }
341
342 ret = if_prefix_add_ipv6 (ifp, ifc);
343 if (ret < 0)
344 {
345 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000346 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000347 continue;
348 }
Christian Frankef7f740f2013-01-24 14:04:48 +0000349 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
paul718e3742002-12-13 20:15:29 +0000350 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
351
352 zebra_interface_address_add_update (ifp, ifc);
353
paul2e3b2e42002-12-13 21:03:13 +0000354 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000355 connected_up_ipv6 (ifp, ifc);
356 }
357#endif /* HAVE_IPV6 */
358 }
359 }
360}
361
362/* Handle interface addition */
363void
364if_add_update (struct interface *ifp)
365{
paul48b33aa2002-12-13 20:52:52 +0000366 struct zebra_if *if_data;
367
368 if_data = ifp->info;
369 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
370 if_set_flags (ifp, IFF_MULTICAST);
371 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
372 if_unset_flags (ifp, IFF_MULTICAST);
373
paul718e3742002-12-13 20:15:29 +0000374 zebra_interface_add_update (ifp);
375
376 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
377 {
378 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
379
380 if_addr_wakeup (ifp);
381
382 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000383 zlog_debug ("interface %s index %d becomes active.",
384 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000385 }
386 else
387 {
388 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000389 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000390 }
391}
392
paul6eb88272005-07-29 14:36:00 +0000393/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000394void
395if_delete_update (struct interface *ifp)
396{
paul718e3742002-12-13 20:15:29 +0000397 struct connected *ifc;
398 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000399 struct route_node *rn;
400 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000401
402 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000403
404 if (if_is_up(ifp))
405 {
406 zlog_err ("interface %s index %d is still up while being deleted.",
407 ifp->name, ifp->ifindex);
408 return;
409 }
410
411 /* Mark interface as inactive */
412 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
413
414 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000415 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000416 ifp->name, ifp->ifindex);
417
418 /* Delete connected routes from the kernel. */
419 if (ifp->connected)
420 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000421 struct listnode *node;
422 struct listnode *last = NULL;
423
hassoeef1fe12004-10-03 18:46:08 +0000424 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000425 {
paul1eb8ef22005-04-07 07:30:20 +0000426 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000427 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000428
Paul Jakmabeb56332006-05-11 13:28:05 +0000429 if (p->family == AF_INET
430 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000431 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000432 struct listnode *anode;
433 struct listnode *next;
434 struct listnode *first;
435 struct list *addr_list;
436
hassoeef1fe12004-10-03 18:46:08 +0000437 route_unlock_node (rn);
438 addr_list = (struct list *) rn->info;
439
440 /* Remove addresses, secondaries first. */
441 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000442 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000443 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000444 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000445 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000446 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000447 first = NULL;
448 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000449 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000450
Paul Jakmad9a18f12007-04-10 19:30:20 +0000451 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000452 p = ifc->address;
453
454 connected_down_ipv4 (ifp, ifc);
455
456 zebra_interface_address_delete_update (ifp, ifc);
457
458 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000459 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000460
461 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000462 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000463 route_unlock_node (rn);
464
465 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000466 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
467 {
468 listnode_delete (ifp->connected, ifc);
469 connected_free (ifc);
470 }
471 else
472 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000473 }
474
475 /* Free chain list and respective route node. */
476 list_delete (addr_list);
477 rn->info = NULL;
478 route_unlock_node (rn);
479 }
paul718e3742002-12-13 20:15:29 +0000480#ifdef HAVE_IPV6
481 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000482 {
483 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000484
hassoeef1fe12004-10-03 18:46:08 +0000485 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000486
hassoeef1fe12004-10-03 18:46:08 +0000487 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000488 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000489
490 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
491 last = node;
492 else
493 {
494 listnode_delete (ifp->connected, ifc);
495 connected_free (ifc);
496 }
paul718e3742002-12-13 20:15:29 +0000497 }
hassoeef1fe12004-10-03 18:46:08 +0000498#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200499 else
500 {
501 last = node;
502 }
paul718e3742002-12-13 20:15:29 +0000503 }
504 }
505 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000506
507 /* Update ifindex after distributing the delete message. This is in
508 case any client needs to have the old value of ifindex available
509 while processing the deletion. Each client daemon is responsible
510 for setting ifindex to IFINDEX_INTERNAL after processing the
511 interface deletion message. */
512 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000513}
514
515/* Interface is up. */
516void
517if_up (struct interface *ifp)
518{
hasso52dc7ee2004-09-23 19:18:23 +0000519 struct listnode *node;
520 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000521 struct connected *ifc;
522 struct prefix *p;
523
524 /* Notify the protocol daemons. */
525 zebra_interface_up_update (ifp);
526
527 /* Install connected routes to the kernel. */
528 if (ifp->connected)
529 {
paul1eb8ef22005-04-07 07:30:20 +0000530 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000531 {
paul718e3742002-12-13 20:15:29 +0000532 p = ifc->address;
533
534 if (p->family == AF_INET)
535 connected_up_ipv4 (ifp, ifc);
536#ifdef HAVE_IPV6
537 else if (p->family == AF_INET6)
538 connected_up_ipv6 (ifp, ifc);
539#endif /* HAVE_IPV6 */
540 }
541 }
542
543 /* Examine all static routes. */
544 rib_update ();
545}
546
547/* Interface goes down. We have to manage different behavior of based
548 OS. */
549void
550if_down (struct interface *ifp)
551{
hasso52dc7ee2004-09-23 19:18:23 +0000552 struct listnode *node;
553 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000554 struct connected *ifc;
555 struct prefix *p;
556
557 /* Notify to the protocol daemons. */
558 zebra_interface_down_update (ifp);
559
560 /* Delete connected routes from the kernel. */
561 if (ifp->connected)
562 {
paul1eb8ef22005-04-07 07:30:20 +0000563 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000564 {
paul718e3742002-12-13 20:15:29 +0000565 p = ifc->address;
566
567 if (p->family == AF_INET)
568 connected_down_ipv4 (ifp, ifc);
569#ifdef HAVE_IPV6
570 else if (p->family == AF_INET6)
571 connected_down_ipv6 (ifp, ifc);
572#endif /* HAVE_IPV6 */
573 }
574 }
575
576 /* Examine all static routes which direct to the interface. */
577 rib_update ();
578}
579
580void
581if_refresh (struct interface *ifp)
582{
paul5c78b3d2006-01-25 04:31:40 +0000583 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000584}
585
paul718e3742002-12-13 20:15:29 +0000586/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000587static int
paul718e3742002-12-13 20:15:29 +0000588prefix_vty_out (struct vty *vty, struct prefix *p)
589{
590 char str[INET6_ADDRSTRLEN];
591
592 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
593 vty_out (vty, "%s", str);
594 return strlen (str);
595}
596
597/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000598static void
paul718e3742002-12-13 20:15:29 +0000599connected_dump_vty (struct vty *vty, struct connected *connected)
600{
601 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000602
603 /* Print interface address. */
604 p = connected->address;
605 vty_out (vty, " %s ", prefix_family_str (p));
606 prefix_vty_out (vty, p);
607 vty_out (vty, "/%d", p->prefixlen);
608
609 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000610 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000611 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000612 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
613 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000614 }
615
616 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
617 vty_out (vty, " secondary");
618
619 if (connected->label)
620 vty_out (vty, " %s", connected->label);
621
622 vty_out (vty, "%s", VTY_NEWLINE);
623}
624
625#ifdef RTADV
626/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000627static void
paul718e3742002-12-13 20:15:29 +0000628nd_dump_vty (struct vty *vty, struct interface *ifp)
629{
630 struct zebra_if *zif;
631 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000632 int interval;
paul718e3742002-12-13 20:15:29 +0000633
634 zif = (struct zebra_if *) ifp->info;
635 rtadv = &zif->rtadv;
636
637 if (rtadv->AdvSendAdvertisements)
638 {
639 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
640 rtadv->AdvReachableTime, VTY_NEWLINE);
641 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
642 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000643 interval = rtadv->MaxRtrAdvInterval;
644 if (interval % 1000)
645 vty_out (vty, " ND router advertisements are sent every "
646 "%d milliseconds%s", interval,
647 VTY_NEWLINE);
648 else
649 vty_out (vty, " ND router advertisements are sent every "
650 "%d seconds%s", interval / 1000,
651 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400652 if (rtadv->AdvDefaultLifetime != -1)
653 vty_out (vty, " ND router advertisements live for %d seconds%s",
654 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
655 else
656 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
657 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000658 vty_out (vty, " ND router advertisement default router preference is "
659 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
660 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000661 if (rtadv->AdvManagedFlag)
662 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
663 VTY_NEWLINE);
664 else
665 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
666 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000667 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400668 {
vincent7cee1bb2005-03-25 13:08:53 +0000669 vty_out (vty, " ND router advertisements with "
670 "Home Agent flag bit set.%s",
671 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400672 if (rtadv->HomeAgentLifetime != -1)
673 vty_out (vty, " Home Agent lifetime is %u seconds%s",
674 rtadv->HomeAgentLifetime, VTY_NEWLINE);
675 else
676 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
677 VTY_NEWLINE);
678 vty_out (vty, " Home Agent preference is %u%s",
679 rtadv->HomeAgentPreference, VTY_NEWLINE);
680 }
vincent7cee1bb2005-03-25 13:08:53 +0000681 if (rtadv->AdvIntervalOption)
682 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
683 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000684 }
685}
686#endif /* RTADV */
687
688/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000689static void
paul718e3742002-12-13 20:15:29 +0000690if_dump_vty (struct vty *vty, struct interface *ifp)
691{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000692#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000693 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000694#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000695 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000696 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000697 struct route_node *rn;
698 struct zebra_if *zebra_if;
699
700 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000701
paul2e3b2e42002-12-13 21:03:13 +0000702 vty_out (vty, "Interface %s is ", ifp->name);
703 if (if_is_up(ifp)) {
704 vty_out (vty, "up, line protocol ");
705
706 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
707 if (if_is_running(ifp))
708 vty_out (vty, "is up%s", VTY_NEWLINE);
709 else
710 vty_out (vty, "is down%s", VTY_NEWLINE);
711 } else {
712 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
713 }
714 } else {
715 vty_out (vty, "down%s", VTY_NEWLINE);
716 }
717
paul718e3742002-12-13 20:15:29 +0000718 if (ifp->desc)
719 vty_out (vty, " Description: %s%s", ifp->desc,
720 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000721 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000722 {
ajsd2fc8892005-04-02 18:38:43 +0000723 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000724 return;
725 }
726 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
727 {
728 vty_out(vty, " index %d inactive interface%s",
729 ifp->ifindex,
730 VTY_NEWLINE);
731 return;
732 }
733
734 vty_out (vty, " index %d metric %d mtu %d ",
735 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000736#ifdef HAVE_IPV6
737 if (ifp->mtu6 != ifp->mtu)
738 vty_out (vty, "mtu6 %d ", ifp->mtu6);
739#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000740 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
741 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000742
paul718e3742002-12-13 20:15:29 +0000743 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000744#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000745 sdl = &ifp->sdl;
746 if (sdl != NULL && sdl->sdl_alen != 0)
747 {
748 int i;
749 u_char *ptr;
750
751 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000752 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
753 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000754 vty_out (vty, "%s", VTY_NEWLINE);
755 }
756#else
757 if (ifp->hw_addr_len != 0)
758 {
759 int i;
760
761 vty_out (vty, " HWaddr: ");
762 for (i = 0; i < ifp->hw_addr_len; i++)
763 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
764 vty_out (vty, "%s", VTY_NEWLINE);
765 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000766#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000767
768 /* Bandwidth in kbps */
769 if (ifp->bandwidth != 0)
770 {
771 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
772 vty_out(vty, "%s", VTY_NEWLINE);
773 }
774
hassoeef1fe12004-10-03 18:46:08 +0000775 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000776 {
hassoeef1fe12004-10-03 18:46:08 +0000777 if (! rn->info)
778 continue;
779
paul1eb8ef22005-04-07 07:30:20 +0000780 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
781 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000782 }
783
paul1eb8ef22005-04-07 07:30:20 +0000784 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000785 {
hasso39db97e2004-10-12 20:50:58 +0000786 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
787 (connected->address->family == AF_INET6))
788 connected_dump_vty (vty, connected);
789 }
790
paul718e3742002-12-13 20:15:29 +0000791#ifdef RTADV
792 nd_dump_vty (vty, ifp);
793#endif /* RTADV */
794
795#ifdef HAVE_PROC_NET_DEV
796 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000797 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
798 "%lu dropped%s",
799 ifp->stats.rx_packets, ifp->stats.rx_multicast,
800 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000801
hasso6f2c27a2005-01-18 13:44:35 +0000802 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000803 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000804 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
805 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000806 ifp->stats.rx_frame_errors, VTY_NEWLINE);
807
808 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000809 ifp->stats.rx_missed_errors, VTY_NEWLINE);
810
hasso6f2c27a2005-01-18 13:44:35 +0000811 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000812 ifp->stats.tx_packets, ifp->stats.tx_bytes,
813 ifp->stats.tx_dropped, VTY_NEWLINE);
814
hasso6f2c27a2005-01-18 13:44:35 +0000815 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
816 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000817 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
818 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000819 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000820
hasso6f2c27a2005-01-18 13:44:35 +0000821 vty_out (vty, " %lu window, %lu collisions%s",
822 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000823#endif /* HAVE_PROC_NET_DEV */
824
825#ifdef HAVE_NET_RT_IFLIST
826#if defined (__bsdi__) || defined (__NetBSD__)
827 /* Statistics print out using sysctl (). */
828 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
829 " multicast packets %qu%s",
830 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
831 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
832 VTY_NEWLINE);
833
834 vty_out (vty, " input errors %qu%s",
835 ifp->stats.ifi_ierrors, VTY_NEWLINE);
836
837 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
838 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
839 ifp->stats.ifi_omcasts, VTY_NEWLINE);
840
841 vty_out (vty, " output errors %qu%s",
842 ifp->stats.ifi_oerrors, VTY_NEWLINE);
843
844 vty_out (vty, " collisions %qu%s",
845 ifp->stats.ifi_collisions, VTY_NEWLINE);
846#else
847 /* Statistics print out using sysctl (). */
848 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
849 " multicast packets %lu%s",
850 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
851 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
852 VTY_NEWLINE);
853
854 vty_out (vty, " input errors %lu%s",
855 ifp->stats.ifi_ierrors, VTY_NEWLINE);
856
857 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
858 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
859 ifp->stats.ifi_omcasts, VTY_NEWLINE);
860
861 vty_out (vty, " output errors %lu%s",
862 ifp->stats.ifi_oerrors, VTY_NEWLINE);
863
864 vty_out (vty, " collisions %lu%s",
865 ifp->stats.ifi_collisions, VTY_NEWLINE);
866#endif /* __bsdi__ || __NetBSD__ */
867#endif /* HAVE_NET_RT_IFLIST */
868}
869
paul718e3742002-12-13 20:15:29 +0000870/* Wrapper hook point for zebra daemon so that ifindex can be set
871 * DEFUN macro not used as extract.pl HAS to ignore this
872 * See also interface_cmd in lib/if.c
873 */
874DEFUN_NOSH (zebra_interface,
875 zebra_interface_cmd,
876 "interface IFNAME",
877 "Select an interface to configure\n"
878 "Interface's name\n")
879{
880 int ret;
881 struct interface * ifp;
882
883 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000884 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
885 return ret;
paul718e3742002-12-13 20:15:29 +0000886
887 ifp = vty->index;
888
ajsd2fc8892005-04-02 18:38:43 +0000889 if (ifp->ifindex == IFINDEX_INTERNAL)
890 /* Is this really necessary? Shouldn't status be initialized to 0
891 in that case? */
892 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000893
894 return ret;
895}
896
paul718e3742002-12-13 20:15:29 +0000897struct cmd_node interface_node =
898{
899 INTERFACE_NODE,
900 "%s(config-if)# ",
901 1
902};
903
904/* Show all or specified interface to vty. */
905DEFUN (show_interface, show_interface_cmd,
906 "show interface [IFNAME]",
907 SHOW_STR
908 "Interface status and configuration\n"
909 "Inteface name\n")
910{
hasso52dc7ee2004-09-23 19:18:23 +0000911 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000912 struct interface *ifp;
913
914#ifdef HAVE_PROC_NET_DEV
915 /* If system has interface statistics via proc file system, update
916 statistics. */
917 ifstat_update_proc ();
918#endif /* HAVE_PROC_NET_DEV */
919#ifdef HAVE_NET_RT_IFLIST
920 ifstat_update_sysctl ();
921#endif /* HAVE_NET_RT_IFLIST */
922
923 /* Specified interface print. */
924 if (argc != 0)
925 {
926 ifp = if_lookup_by_name (argv[0]);
927 if (ifp == NULL)
928 {
929 vty_out (vty, "%% Can't find interface %s%s", argv[0],
930 VTY_NEWLINE);
931 return CMD_WARNING;
932 }
933 if_dump_vty (vty, ifp);
934 return CMD_SUCCESS;
935 }
936
937 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000938 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
939 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000940
941 return CMD_SUCCESS;
942}
943
hassoed9bb6d2005-03-13 19:17:21 +0000944DEFUN (show_interface_desc,
945 show_interface_desc_cmd,
946 "show interface description",
947 SHOW_STR
948 "Interface status and configuration\n"
949 "Interface description\n")
950{
951 struct listnode *node;
952 struct interface *ifp;
953
954 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000955 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000956 {
957 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000958
959 len = vty_out (vty, "%s", ifp->name);
960 vty_out (vty, "%*s", (16 - len), " ");
961
962 if (if_is_up(ifp))
963 {
964 vty_out (vty, "up ");
965 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
966 {
967 if (if_is_running(ifp))
968 vty_out (vty, "up ");
969 else
970 vty_out (vty, "down ");
971 }
972 else
973 {
974 vty_out (vty, "unknown ");
975 }
976 }
977 else
978 {
979 vty_out (vty, "down down ");
980 }
981
982 if (ifp->desc)
983 vty_out (vty, "%s", ifp->desc);
984 vty_out (vty, "%s", VTY_NEWLINE);
985 }
986 return CMD_SUCCESS;
987}
988
paul718e3742002-12-13 20:15:29 +0000989DEFUN (multicast,
990 multicast_cmd,
991 "multicast",
992 "Set multicast flag to interface\n")
993{
994 int ret;
995 struct interface *ifp;
996 struct zebra_if *if_data;
997
998 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000999 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001000 {
paul48b33aa2002-12-13 20:52:52 +00001001 ret = if_set_flags (ifp, IFF_MULTICAST);
1002 if (ret < 0)
1003 {
1004 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1005 return CMD_WARNING;
1006 }
1007 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001008 }
paul718e3742002-12-13 20:15:29 +00001009 if_data = ifp->info;
1010 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001011
paul718e3742002-12-13 20:15:29 +00001012 return CMD_SUCCESS;
1013}
1014
1015DEFUN (no_multicast,
1016 no_multicast_cmd,
1017 "no multicast",
1018 NO_STR
1019 "Unset multicast flag to interface\n")
1020{
1021 int ret;
1022 struct interface *ifp;
1023 struct zebra_if *if_data;
1024
1025 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001026 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001027 {
paul48b33aa2002-12-13 20:52:52 +00001028 ret = if_unset_flags (ifp, IFF_MULTICAST);
1029 if (ret < 0)
1030 {
1031 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1032 return CMD_WARNING;
1033 }
1034 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001035 }
paul718e3742002-12-13 20:15:29 +00001036 if_data = ifp->info;
1037 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1038
1039 return CMD_SUCCESS;
1040}
1041
paul2e3b2e42002-12-13 21:03:13 +00001042DEFUN (linkdetect,
1043 linkdetect_cmd,
1044 "link-detect",
1045 "Enable link detection on interface\n")
1046{
paul2e3b2e42002-12-13 21:03:13 +00001047 struct interface *ifp;
1048 int if_was_operative;
1049
1050 ifp = (struct interface *) vty->index;
1051 if_was_operative = if_is_operative(ifp);
1052 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1053
1054 /* When linkdetection is enabled, if might come down */
1055 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1056
1057 /* FIXME: Will defer status change forwarding if interface
1058 does not come down! */
1059
1060 return CMD_SUCCESS;
1061}
1062
1063
1064DEFUN (no_linkdetect,
1065 no_linkdetect_cmd,
1066 "no link-detect",
1067 NO_STR
1068 "Disable link detection on interface\n")
1069{
paul2e3b2e42002-12-13 21:03:13 +00001070 struct interface *ifp;
1071 int if_was_operative;
1072
1073 ifp = (struct interface *) vty->index;
1074 if_was_operative = if_is_operative(ifp);
1075 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1076
1077 /* Interface may come up after disabling link detection */
1078 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1079
1080 /* FIXME: see linkdetect_cmd */
1081
1082 return CMD_SUCCESS;
1083}
1084
paul718e3742002-12-13 20:15:29 +00001085DEFUN (shutdown_if,
1086 shutdown_if_cmd,
1087 "shutdown",
1088 "Shutdown the selected interface\n")
1089{
1090 int ret;
1091 struct interface *ifp;
1092 struct zebra_if *if_data;
1093
1094 ifp = (struct interface *) vty->index;
1095 ret = if_unset_flags (ifp, IFF_UP);
1096 if (ret < 0)
1097 {
1098 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1099 return CMD_WARNING;
1100 }
1101 if_refresh (ifp);
1102 if_data = ifp->info;
1103 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1104
1105 return CMD_SUCCESS;
1106}
1107
1108DEFUN (no_shutdown_if,
1109 no_shutdown_if_cmd,
1110 "no shutdown",
1111 NO_STR
1112 "Shutdown the selected interface\n")
1113{
1114 int ret;
1115 struct interface *ifp;
1116 struct zebra_if *if_data;
1117
1118 ifp = (struct interface *) vty->index;
1119 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1120 if (ret < 0)
1121 {
1122 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1123 return CMD_WARNING;
1124 }
1125 if_refresh (ifp);
1126 if_data = ifp->info;
1127 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1128
1129 return CMD_SUCCESS;
1130}
1131
1132DEFUN (bandwidth_if,
1133 bandwidth_if_cmd,
1134 "bandwidth <1-10000000>",
1135 "Set bandwidth informational parameter\n"
1136 "Bandwidth in kilobits\n")
1137{
1138 struct interface *ifp;
1139 unsigned int bandwidth;
1140
1141 ifp = (struct interface *) vty->index;
1142 bandwidth = strtol(argv[0], NULL, 10);
1143
1144 /* bandwidth range is <1-10000000> */
1145 if (bandwidth < 1 || bandwidth > 10000000)
1146 {
1147 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1148 return CMD_WARNING;
1149 }
1150
1151 ifp->bandwidth = bandwidth;
1152
1153 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001154 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001155 zebra_interface_up_update (ifp);
1156
1157 return CMD_SUCCESS;
1158}
1159
1160DEFUN (no_bandwidth_if,
1161 no_bandwidth_if_cmd,
1162 "no bandwidth",
1163 NO_STR
1164 "Set bandwidth informational parameter\n")
1165{
1166 struct interface *ifp;
1167
1168 ifp = (struct interface *) vty->index;
1169
1170 ifp->bandwidth = 0;
1171
1172 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001173 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001174 zebra_interface_up_update (ifp);
1175
1176 return CMD_SUCCESS;
1177}
1178
1179ALIAS (no_bandwidth_if,
1180 no_bandwidth_if_val_cmd,
1181 "no bandwidth <1-10000000>",
1182 NO_STR
1183 "Set bandwidth informational parameter\n"
1184 "Bandwidth in kilobits\n")
1185
paula1ac18c2005-06-28 17:17:12 +00001186static int
hasso39db97e2004-10-12 20:50:58 +00001187ip_address_install (struct vty *vty, struct interface *ifp,
1188 const char *addr_str, const char *peer_str,
1189 const char *label)
paul718e3742002-12-13 20:15:29 +00001190{
1191 struct prefix_ipv4 cp;
1192 struct connected *ifc;
1193 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001194 int ret;
1195
1196 ret = str2prefix_ipv4 (addr_str, &cp);
1197 if (ret <= 0)
1198 {
1199 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1200 return CMD_WARNING;
1201 }
1202
paulca162182005-09-12 16:58:52 +00001203 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001204 if (! ifc)
1205 {
1206 ifc = connected_new ();
1207 ifc->ifp = ifp;
1208
1209 /* Address. */
1210 p = prefix_ipv4_new ();
1211 *p = cp;
1212 ifc->address = (struct prefix *) p;
1213
1214 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001215 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001216 {
1217 p = prefix_ipv4_new ();
1218 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001219 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001220 ifc->destination = (struct prefix *) p;
1221 }
1222
paul718e3742002-12-13 20:15:29 +00001223 /* Label. */
1224 if (label)
paul0752ef02005-11-03 12:35:21 +00001225 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001226
1227 /* Add to linked list. */
1228 listnode_add (ifp->connected, ifc);
1229 }
1230
1231 /* This address is configured from zebra. */
1232 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1233 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1234
1235 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001236 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001237 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1238 {
1239 /* Some system need to up the interface to set IP address. */
1240 if (! if_is_up (ifp))
1241 {
1242 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1243 if_refresh (ifp);
1244 }
1245
1246 ret = if_set_prefix (ifp, ifc);
1247 if (ret < 0)
1248 {
1249 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001250 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001251 return CMD_WARNING;
1252 }
1253
hassoeef1fe12004-10-03 18:46:08 +00001254 /* Add to subnet chain list (while marking secondary attribute). */
1255 if_subnet_add (ifp, ifc);
1256
paul718e3742002-12-13 20:15:29 +00001257 /* IP address propery set. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001258 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
paul718e3742002-12-13 20:15:29 +00001259 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1260
1261 /* Update interface address information to protocol daemon. */
1262 zebra_interface_address_add_update (ifp, ifc);
1263
1264 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001265 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001266 connected_up_ipv4 (ifp, ifc);
1267 }
1268
1269 return CMD_SUCCESS;
1270}
1271
paula1ac18c2005-06-28 17:17:12 +00001272static int
hasso39db97e2004-10-12 20:50:58 +00001273ip_address_uninstall (struct vty *vty, struct interface *ifp,
1274 const char *addr_str, const char *peer_str,
1275 const char *label)
paul718e3742002-12-13 20:15:29 +00001276{
1277 struct prefix_ipv4 cp;
1278 struct connected *ifc;
1279 int ret;
1280
1281 /* Convert to prefix structure. */
1282 ret = str2prefix_ipv4 (addr_str, &cp);
1283 if (ret <= 0)
1284 {
1285 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1286 return CMD_WARNING;
1287 }
1288
1289 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001290 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001291 if (! ifc)
1292 {
1293 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
1296
1297 /* This is not configured address. */
1298 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1299 return CMD_WARNING;
1300
Paul Jakma74ecdc92006-06-15 18:10:47 +00001301 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1302
paul718e3742002-12-13 20:15:29 +00001303 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001304 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001305 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1306 {
1307 listnode_delete (ifp->connected, ifc);
1308 connected_free (ifc);
1309 return CMD_WARNING;
1310 }
1311
1312 /* This is real route. */
1313 ret = if_unset_prefix (ifp, ifc);
1314 if (ret < 0)
1315 {
1316 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001317 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001318 return CMD_WARNING;
1319 }
David Lamparter7f062c22010-02-01 16:41:26 +01001320 /* success! call returned that the address deletion went through.
1321 * this is a synchronous operation, so we know it succeeded and can
1322 * now update all internal state. */
paul718e3742002-12-13 20:15:29 +00001323
David Lamparter7f062c22010-02-01 16:41:26 +01001324 /* the HAVE_NETLINK check is only here because, on BSD, although the
1325 * call above is still synchronous, we get a second confirmation later
1326 * through the route socket, and we don't want to touch that behaviour
1327 * for now. It should work without the #ifdef, but why take the risk...
1328 * -- equinox 2012-07-13 */
Christian Frankef7f740f2013-01-24 14:04:48 +00001329 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
David Lamparter7f062c22010-02-01 16:41:26 +01001330#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001331
1332 /* Remove connected route. */
1333 connected_down_ipv4 (ifp, ifc);
1334
David Lamparter7f062c22010-02-01 16:41:26 +01001335 /* Redistribute this information. */
1336 zebra_interface_address_delete_update (ifp, ifc);
1337
1338 /* IP address propery set. */
1339 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1340
1341 /* remove from interface, remark secondaries */
1342 if_subnet_delete (ifp, ifc);
1343
paul718e3742002-12-13 20:15:29 +00001344 /* Free address information. */
1345 listnode_delete (ifp->connected, ifc);
1346 connected_free (ifc);
hassoeef1fe12004-10-03 18:46:08 +00001347#endif
paul718e3742002-12-13 20:15:29 +00001348
1349 return CMD_SUCCESS;
1350}
1351
1352DEFUN (ip_address,
1353 ip_address_cmd,
1354 "ip address A.B.C.D/M",
1355 "Interface Internet Protocol config commands\n"
1356 "Set the IP address of an interface\n"
1357 "IP address (e.g. 10.0.0.1/8)\n")
1358{
hassoeef1fe12004-10-03 18:46:08 +00001359 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001360}
1361
1362DEFUN (no_ip_address,
1363 no_ip_address_cmd,
1364 "no ip address A.B.C.D/M",
1365 NO_STR
1366 "Interface Internet Protocol config commands\n"
1367 "Set the IP address of an interface\n"
1368 "IP Address (e.g. 10.0.0.1/8)")
1369{
hassoeef1fe12004-10-03 18:46:08 +00001370 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001371}
1372
1373#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001374DEFUN (ip_address_label,
1375 ip_address_label_cmd,
1376 "ip address A.B.C.D/M label LINE",
1377 "Interface Internet Protocol config commands\n"
1378 "Set the IP address of an interface\n"
1379 "IP address (e.g. 10.0.0.1/8)\n"
1380 "Label of this address\n"
1381 "Label\n")
1382{
hassoeef1fe12004-10-03 18:46:08 +00001383 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001384}
1385
1386DEFUN (no_ip_address_label,
1387 no_ip_address_label_cmd,
1388 "no ip address A.B.C.D/M label LINE",
1389 NO_STR
1390 "Interface Internet Protocol config commands\n"
1391 "Set the IP address of an interface\n"
1392 "IP address (e.g. 10.0.0.1/8)\n"
1393 "Label of this address\n"
1394 "Label\n")
1395{
hassoeef1fe12004-10-03 18:46:08 +00001396 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001397}
1398#endif /* HAVE_NETLINK */
1399
1400#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001401static int
hasso39db97e2004-10-12 20:50:58 +00001402ipv6_address_install (struct vty *vty, struct interface *ifp,
1403 const char *addr_str, const char *peer_str,
1404 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001405{
1406 struct prefix_ipv6 cp;
1407 struct connected *ifc;
1408 struct prefix_ipv6 *p;
1409 int ret;
1410
1411 ret = str2prefix_ipv6 (addr_str, &cp);
1412 if (ret <= 0)
1413 {
1414 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1415 return CMD_WARNING;
1416 }
1417
paulca162182005-09-12 16:58:52 +00001418 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001419 if (! ifc)
1420 {
1421 ifc = connected_new ();
1422 ifc->ifp = ifp;
1423
1424 /* Address. */
1425 p = prefix_ipv6_new ();
1426 *p = cp;
1427 ifc->address = (struct prefix *) p;
1428
1429 /* Secondary. */
1430 if (secondary)
1431 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1432
1433 /* Label. */
1434 if (label)
paul0752ef02005-11-03 12:35:21 +00001435 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001436
1437 /* Add to linked list. */
1438 listnode_add (ifp->connected, ifc);
1439 }
1440
1441 /* This address is configured from zebra. */
1442 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1443 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1444
1445 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001446 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001447 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1448 {
1449 /* Some system need to up the interface to set IP address. */
1450 if (! if_is_up (ifp))
1451 {
1452 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1453 if_refresh (ifp);
1454 }
1455
1456 ret = if_prefix_add_ipv6 (ifp, ifc);
1457
1458 if (ret < 0)
1459 {
1460 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001461 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001462 return CMD_WARNING;
1463 }
1464
1465 /* IP address propery set. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001466 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
paul718e3742002-12-13 20:15:29 +00001467 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1468
1469 /* Update interface address information to protocol daemon. */
1470 zebra_interface_address_add_update (ifp, ifc);
1471
1472 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001473 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001474 connected_up_ipv6 (ifp, ifc);
1475 }
1476
1477 return CMD_SUCCESS;
1478}
1479
paula1ac18c2005-06-28 17:17:12 +00001480static int
hasso39db97e2004-10-12 20:50:58 +00001481ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1482 const char *addr_str, const char *peer_str,
1483 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001484{
1485 struct prefix_ipv6 cp;
1486 struct connected *ifc;
1487 int ret;
1488
1489 /* Convert to prefix structure. */
1490 ret = str2prefix_ipv6 (addr_str, &cp);
1491 if (ret <= 0)
1492 {
1493 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1494 return CMD_WARNING;
1495 }
1496
1497 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001498 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001499 if (! ifc)
1500 {
1501 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1502 return CMD_WARNING;
1503 }
1504
1505 /* This is not configured address. */
1506 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1507 return CMD_WARNING;
1508
Christian Franke676e1a02013-01-24 14:04:45 +00001509 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1510
paul718e3742002-12-13 20:15:29 +00001511 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001512 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001513 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1514 {
1515 listnode_delete (ifp->connected, ifc);
1516 connected_free (ifc);
1517 return CMD_WARNING;
1518 }
1519
1520 /* This is real route. */
1521 ret = if_prefix_delete_ipv6 (ifp, ifc);
1522 if (ret < 0)
1523 {
1524 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001525 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001526 return CMD_WARNING;
1527 }
1528
Christian Frankef7f740f2013-01-24 14:04:48 +00001529 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
1530
paul718e3742002-12-13 20:15:29 +00001531 /* Redistribute this information. */
1532 zebra_interface_address_delete_update (ifp, ifc);
1533
1534 /* Remove connected route. */
1535 connected_down_ipv6 (ifp, ifc);
1536
1537 /* Free address information. */
1538 listnode_delete (ifp->connected, ifc);
1539 connected_free (ifc);
1540
1541 return CMD_SUCCESS;
1542}
1543
1544DEFUN (ipv6_address,
1545 ipv6_address_cmd,
1546 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001547 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001548 "Set the IP address of an interface\n"
1549 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1550{
1551 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1552}
1553
1554DEFUN (no_ipv6_address,
1555 no_ipv6_address_cmd,
1556 "no ipv6 address X:X::X:X/M",
1557 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001558 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001559 "Set the IP address of an interface\n"
1560 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1561{
1562 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1563}
1564#endif /* HAVE_IPV6 */
1565
paula1ac18c2005-06-28 17:17:12 +00001566static int
paul718e3742002-12-13 20:15:29 +00001567if_config_write (struct vty *vty)
1568{
hasso52dc7ee2004-09-23 19:18:23 +00001569 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001570 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001571
paul1eb8ef22005-04-07 07:30:20 +00001572 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001573 {
1574 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001575 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001576 struct connected *ifc;
1577 struct prefix *p;
1578
paul718e3742002-12-13 20:15:29 +00001579 if_data = ifp->info;
1580
1581 vty_out (vty, "interface %s%s", ifp->name,
1582 VTY_NEWLINE);
1583
1584 if (ifp->desc)
1585 vty_out (vty, " description %s%s", ifp->desc,
1586 VTY_NEWLINE);
1587
1588 /* Assign bandwidth here to avoid unnecessary interface flap
1589 while processing config script */
1590 if (ifp->bandwidth != 0)
1591 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1592
paul2e3b2e42002-12-13 21:03:13 +00001593 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1594 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1595
paul1eb8ef22005-04-07 07:30:20 +00001596 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001597 {
paul718e3742002-12-13 20:15:29 +00001598 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1599 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001600 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001601 p = ifc->address;
1602 vty_out (vty, " ip%s address %s/%d",
1603 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001604 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001605 p->prefixlen);
1606
paul718e3742002-12-13 20:15:29 +00001607 if (ifc->label)
1608 vty_out (vty, " label %s", ifc->label);
1609
1610 vty_out (vty, "%s", VTY_NEWLINE);
1611 }
1612 }
1613
1614 if (if_data)
1615 {
1616 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1617 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1618
1619 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1620 vty_out (vty, " %smulticast%s",
1621 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1622 VTY_NEWLINE);
1623 }
1624
1625#ifdef RTADV
1626 rtadv_config_write (vty, ifp);
1627#endif /* RTADV */
1628
hassoca776982004-06-12 14:33:05 +00001629#ifdef HAVE_IRDP
1630 irdp_config_write (vty, ifp);
1631#endif /* IRDP */
1632
paul718e3742002-12-13 20:15:29 +00001633 vty_out (vty, "!%s", VTY_NEWLINE);
1634 }
1635 return 0;
1636}
1637
1638/* Allocate and initialize interface vector. */
1639void
paula1ac18c2005-06-28 17:17:12 +00001640zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001641{
1642 /* Initialize interface and new hook. */
1643 if_init ();
1644 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1645 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1646
1647 /* Install configuration write function. */
1648 install_node (&interface_node, if_config_write);
1649
1650 install_element (VIEW_NODE, &show_interface_cmd);
1651 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001652 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001653 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001654 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001655 install_default (INTERFACE_NODE);
1656 install_element (INTERFACE_NODE, &interface_desc_cmd);
1657 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1658 install_element (INTERFACE_NODE, &multicast_cmd);
1659 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001660 install_element (INTERFACE_NODE, &linkdetect_cmd);
1661 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001662 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1663 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1664 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1665 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1666 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1667 install_element (INTERFACE_NODE, &ip_address_cmd);
1668 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1669#ifdef HAVE_IPV6
1670 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1671 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1672#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001673#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001674 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001675 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001676#endif /* HAVE_NETLINK */
1677}