blob: 51798ca6c511b965d266abb6e6d889eeb199ef1b [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);
Christian Franke02b48052013-01-24 14:04:49 +0000196 /* XXX: Linux kernel removes all the secondary addresses when the primary
197 * address is removed. We could try to work around that, though this is
198 * non-trivial. */
hassoeef1fe12004-10-03 18:46:08 +0000199 zebra_interface_address_add_update (ifp, ifc);
200 }
201
202 return addr_list->count;
203 }
204
205 /* Otherwise, free list and route node. */
206 list_free (addr_list);
207 rn->info = NULL;
208 route_unlock_node (rn);
209
paul718e3742002-12-13 20:15:29 +0000210 return 0;
211}
212
paul5c78b3d2006-01-25 04:31:40 +0000213/* if_flags_mangle: A place for hacks that require mangling
214 * or tweaking the interface flags.
215 *
216 * ******************** Solaris flags hacks **************************
217 *
218 * Solaris IFF_UP flag reflects only the primary interface as the
219 * routing socket only sends IFINFO for the primary interface. Hence
220 * ~IFF_UP does not per se imply all the logical interfaces are also
221 * down - which we only know of as addresses. Instead we must determine
222 * whether the interface really is up or not according to how many
223 * addresses are still attached. (Solaris always sends RTM_DELADDR if
224 * an interface, logical or not, goes ~IFF_UP).
225 *
226 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
227 * are addresses left in struct connected, not just the actual underlying
228 * IFF_UP flag.
229 *
230 * We must hence remember the real state of IFF_UP, which we do in
231 * struct zebra_if.primary_state.
232 *
233 * Setting IFF_UP within zebra to administratively shutdown the
234 * interface will affect only the primary interface/address on Solaris.
235 ************************End Solaris flags hacks ***********************
236 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100237static void
paul5c78b3d2006-01-25 04:31:40 +0000238if_flags_mangle (struct interface *ifp, uint64_t *newflags)
239{
240#ifdef SUNOS_5
241 struct zebra_if *zif = ifp->info;
242
243 zif->primary_state = *newflags & (IFF_UP & 0xff);
244
245 if (CHECK_FLAG (zif->primary_state, IFF_UP)
246 || listcount(ifp->connected) > 0)
247 SET_FLAG (*newflags, IFF_UP);
248 else
249 UNSET_FLAG (*newflags, IFF_UP);
250#endif /* SUNOS_5 */
251}
252
253/* Update the flags field of the ifp with the new flag set provided.
254 * Take whatever actions are required for any changes in flags we care
255 * about.
256 *
257 * newflags should be the raw value, as obtained from the OS.
258 */
259void
260if_flags_update (struct interface *ifp, uint64_t newflags)
261{
262 if_flags_mangle (ifp, &newflags);
263
264 if (if_is_operative (ifp))
265 {
266 /* operative -> inoperative? */
267 ifp->flags = newflags;
268 if (!if_is_operative (ifp))
269 if_down (ifp);
270 }
271 else
272 {
273 /* inoperative -> operative? */
274 ifp->flags = newflags;
275 if (if_is_operative (ifp))
276 if_up (ifp);
277 }
278}
279
paul718e3742002-12-13 20:15:29 +0000280/* Wake up configured address if it is not in current kernel
281 address. */
paula1ac18c2005-06-28 17:17:12 +0000282static void
paul718e3742002-12-13 20:15:29 +0000283if_addr_wakeup (struct interface *ifp)
284{
paul1eb8ef22005-04-07 07:30:20 +0000285 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000286 struct connected *ifc;
287 struct prefix *p;
288 int ret;
289
paul1eb8ef22005-04-07 07:30:20 +0000290 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000291 {
paul718e3742002-12-13 20:15:29 +0000292 p = ifc->address;
293
294 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000295 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000296 {
297 /* Address check. */
298 if (p->family == AF_INET)
299 {
300 if (! if_is_up (ifp))
301 {
Christian Franke02b48052013-01-24 14:04:49 +0000302 /* Assume zebra is configured like following:
303 *
304 * interface gre0
305 * ip addr 192.0.2.1/24
306 * !
307 *
308 * As soon as zebra becomes first aware that gre0 exists in the
309 * kernel, it will set gre0 up and configure its addresses.
310 *
311 * (This may happen at startup when the interface already exists
312 * or during runtime when the interface is added to the kernel)
313 *
314 * XXX: IRDP code is calling here via if_add_update - this seems
315 * somewhat weird.
316 * XXX: RUNNING is not a settable flag on any system
317 * I (paulj) am aware of.
318 */
paul718e3742002-12-13 20:15:29 +0000319 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
320 if_refresh (ifp);
321 }
322
323 ret = if_set_prefix (ifp, ifc);
324 if (ret < 0)
325 {
326 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000327 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000328 continue;
329 }
hassoeef1fe12004-10-03 18:46:08 +0000330
Christian Frankef7f740f2013-01-24 14:04:48 +0000331 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000332 /* The address will be advertised to zebra clients when the notification
333 * from the kernel has been received.
334 * It will also be added to the interface's subnet list then. */
paul718e3742002-12-13 20:15:29 +0000335 }
336#ifdef HAVE_IPV6
337 if (p->family == AF_INET6)
338 {
339 if (! if_is_up (ifp))
340 {
Christian Franke02b48052013-01-24 14:04:49 +0000341 /* See long comment above */
paul718e3742002-12-13 20:15:29 +0000342 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
343 if_refresh (ifp);
344 }
345
346 ret = if_prefix_add_ipv6 (ifp, ifc);
347 if (ret < 0)
348 {
349 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000350 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000351 continue;
352 }
Christian Franke02b48052013-01-24 14:04:49 +0000353
Christian Frankef7f740f2013-01-24 14:04:48 +0000354 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000355 /* The address will be advertised to zebra clients when the notification
356 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +0000357 }
358#endif /* HAVE_IPV6 */
359 }
360 }
361}
362
363/* Handle interface addition */
364void
365if_add_update (struct interface *ifp)
366{
paul48b33aa2002-12-13 20:52:52 +0000367 struct zebra_if *if_data;
368
369 if_data = ifp->info;
370 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
371 if_set_flags (ifp, IFF_MULTICAST);
372 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
373 if_unset_flags (ifp, IFF_MULTICAST);
374
paul718e3742002-12-13 20:15:29 +0000375 zebra_interface_add_update (ifp);
376
377 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
378 {
379 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
380
381 if_addr_wakeup (ifp);
382
383 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000384 zlog_debug ("interface %s index %d becomes active.",
385 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000386 }
387 else
388 {
389 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000390 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000391 }
392}
393
paul6eb88272005-07-29 14:36:00 +0000394/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000395void
396if_delete_update (struct interface *ifp)
397{
paul718e3742002-12-13 20:15:29 +0000398 struct connected *ifc;
399 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000400 struct route_node *rn;
401 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000402
403 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000404
405 if (if_is_up(ifp))
406 {
407 zlog_err ("interface %s index %d is still up while being deleted.",
408 ifp->name, ifp->ifindex);
409 return;
410 }
411
412 /* Mark interface as inactive */
413 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
414
415 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000416 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000417 ifp->name, ifp->ifindex);
418
419 /* Delete connected routes from the kernel. */
420 if (ifp->connected)
421 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000422 struct listnode *node;
423 struct listnode *last = NULL;
424
hassoeef1fe12004-10-03 18:46:08 +0000425 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000426 {
paul1eb8ef22005-04-07 07:30:20 +0000427 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000428 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000429
Paul Jakmabeb56332006-05-11 13:28:05 +0000430 if (p->family == AF_INET
431 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000432 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000433 struct listnode *anode;
434 struct listnode *next;
435 struct listnode *first;
436 struct list *addr_list;
437
hassoeef1fe12004-10-03 18:46:08 +0000438 route_unlock_node (rn);
439 addr_list = (struct list *) rn->info;
440
441 /* Remove addresses, secondaries first. */
442 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000443 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000444 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000445 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000446 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000447 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000448 first = NULL;
449 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000450 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000451
Paul Jakmad9a18f12007-04-10 19:30:20 +0000452 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000453 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000454 connected_down_ipv4 (ifp, ifc);
455
Christian Franke02b48052013-01-24 14:04:49 +0000456 /* XXX: We have to send notifications here explicitly, because we destroy
457 * the ifc before receiving the notification about the address being deleted.
458 */
hassoeef1fe12004-10-03 18:46:08 +0000459 zebra_interface_address_delete_update (ifp, ifc);
460
461 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000462 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000463
464 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000465 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000466 route_unlock_node (rn);
467
468 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000469 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
470 {
471 listnode_delete (ifp->connected, ifc);
472 connected_free (ifc);
473 }
474 else
475 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000476 }
477
478 /* Free chain list and respective route node. */
479 list_delete (addr_list);
480 rn->info = NULL;
481 route_unlock_node (rn);
482 }
paul718e3742002-12-13 20:15:29 +0000483#ifdef HAVE_IPV6
484 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000485 {
486 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000487
hassoeef1fe12004-10-03 18:46:08 +0000488 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000489
hassoeef1fe12004-10-03 18:46:08 +0000490 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000491 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000492
493 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
494 last = node;
495 else
496 {
497 listnode_delete (ifp->connected, ifc);
498 connected_free (ifc);
499 }
paul718e3742002-12-13 20:15:29 +0000500 }
hassoeef1fe12004-10-03 18:46:08 +0000501#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200502 else
503 {
504 last = node;
505 }
paul718e3742002-12-13 20:15:29 +0000506 }
507 }
508 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000509
510 /* Update ifindex after distributing the delete message. This is in
511 case any client needs to have the old value of ifindex available
512 while processing the deletion. Each client daemon is responsible
513 for setting ifindex to IFINDEX_INTERNAL after processing the
514 interface deletion message. */
515 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000516}
517
518/* Interface is up. */
519void
520if_up (struct interface *ifp)
521{
hasso52dc7ee2004-09-23 19:18:23 +0000522 struct listnode *node;
523 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000524 struct connected *ifc;
525 struct prefix *p;
526
527 /* Notify the protocol daemons. */
528 zebra_interface_up_update (ifp);
529
530 /* Install connected routes to the kernel. */
531 if (ifp->connected)
532 {
paul1eb8ef22005-04-07 07:30:20 +0000533 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000534 {
paul718e3742002-12-13 20:15:29 +0000535 p = ifc->address;
536
537 if (p->family == AF_INET)
538 connected_up_ipv4 (ifp, ifc);
539#ifdef HAVE_IPV6
540 else if (p->family == AF_INET6)
541 connected_up_ipv6 (ifp, ifc);
542#endif /* HAVE_IPV6 */
543 }
544 }
545
546 /* Examine all static routes. */
547 rib_update ();
548}
549
550/* Interface goes down. We have to manage different behavior of based
551 OS. */
552void
553if_down (struct interface *ifp)
554{
hasso52dc7ee2004-09-23 19:18:23 +0000555 struct listnode *node;
556 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000557 struct connected *ifc;
558 struct prefix *p;
559
560 /* Notify to the protocol daemons. */
561 zebra_interface_down_update (ifp);
562
563 /* Delete connected routes from the kernel. */
564 if (ifp->connected)
565 {
paul1eb8ef22005-04-07 07:30:20 +0000566 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000567 {
paul718e3742002-12-13 20:15:29 +0000568 p = ifc->address;
569
570 if (p->family == AF_INET)
571 connected_down_ipv4 (ifp, ifc);
572#ifdef HAVE_IPV6
573 else if (p->family == AF_INET6)
574 connected_down_ipv6 (ifp, ifc);
575#endif /* HAVE_IPV6 */
576 }
577 }
578
579 /* Examine all static routes which direct to the interface. */
580 rib_update ();
581}
582
583void
584if_refresh (struct interface *ifp)
585{
paul5c78b3d2006-01-25 04:31:40 +0000586 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000587}
588
paul718e3742002-12-13 20:15:29 +0000589/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000590static int
paul718e3742002-12-13 20:15:29 +0000591prefix_vty_out (struct vty *vty, struct prefix *p)
592{
593 char str[INET6_ADDRSTRLEN];
594
595 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
596 vty_out (vty, "%s", str);
597 return strlen (str);
598}
599
600/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000601static void
paul718e3742002-12-13 20:15:29 +0000602connected_dump_vty (struct vty *vty, struct connected *connected)
603{
604 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000605
606 /* Print interface address. */
607 p = connected->address;
608 vty_out (vty, " %s ", prefix_family_str (p));
609 prefix_vty_out (vty, p);
610 vty_out (vty, "/%d", p->prefixlen);
611
612 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000613 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000614 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000615 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
616 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000617 }
618
619 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
620 vty_out (vty, " secondary");
621
622 if (connected->label)
623 vty_out (vty, " %s", connected->label);
624
625 vty_out (vty, "%s", VTY_NEWLINE);
626}
627
628#ifdef RTADV
629/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000630static void
paul718e3742002-12-13 20:15:29 +0000631nd_dump_vty (struct vty *vty, struct interface *ifp)
632{
633 struct zebra_if *zif;
634 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000635 int interval;
paul718e3742002-12-13 20:15:29 +0000636
637 zif = (struct zebra_if *) ifp->info;
638 rtadv = &zif->rtadv;
639
640 if (rtadv->AdvSendAdvertisements)
641 {
642 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
643 rtadv->AdvReachableTime, VTY_NEWLINE);
644 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
645 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000646 interval = rtadv->MaxRtrAdvInterval;
647 if (interval % 1000)
648 vty_out (vty, " ND router advertisements are sent every "
649 "%d milliseconds%s", interval,
650 VTY_NEWLINE);
651 else
652 vty_out (vty, " ND router advertisements are sent every "
653 "%d seconds%s", interval / 1000,
654 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400655 if (rtadv->AdvDefaultLifetime != -1)
656 vty_out (vty, " ND router advertisements live for %d seconds%s",
657 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
658 else
659 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
660 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000661 vty_out (vty, " ND router advertisement default router preference is "
662 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
663 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000664 if (rtadv->AdvManagedFlag)
665 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
666 VTY_NEWLINE);
667 else
668 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
669 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000670 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400671 {
vincent7cee1bb2005-03-25 13:08:53 +0000672 vty_out (vty, " ND router advertisements with "
673 "Home Agent flag bit set.%s",
674 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400675 if (rtadv->HomeAgentLifetime != -1)
676 vty_out (vty, " Home Agent lifetime is %u seconds%s",
677 rtadv->HomeAgentLifetime, VTY_NEWLINE);
678 else
679 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
680 VTY_NEWLINE);
681 vty_out (vty, " Home Agent preference is %u%s",
682 rtadv->HomeAgentPreference, VTY_NEWLINE);
683 }
vincent7cee1bb2005-03-25 13:08:53 +0000684 if (rtadv->AdvIntervalOption)
685 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
686 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000687 }
688}
689#endif /* RTADV */
690
691/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000692static void
paul718e3742002-12-13 20:15:29 +0000693if_dump_vty (struct vty *vty, struct interface *ifp)
694{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000695#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000696 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000697#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000698 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000699 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000700 struct route_node *rn;
701 struct zebra_if *zebra_if;
702
703 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000704
paul2e3b2e42002-12-13 21:03:13 +0000705 vty_out (vty, "Interface %s is ", ifp->name);
706 if (if_is_up(ifp)) {
707 vty_out (vty, "up, line protocol ");
708
709 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
710 if (if_is_running(ifp))
711 vty_out (vty, "is up%s", VTY_NEWLINE);
712 else
713 vty_out (vty, "is down%s", VTY_NEWLINE);
714 } else {
715 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
716 }
717 } else {
718 vty_out (vty, "down%s", VTY_NEWLINE);
719 }
720
paul718e3742002-12-13 20:15:29 +0000721 if (ifp->desc)
722 vty_out (vty, " Description: %s%s", ifp->desc,
723 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000724 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000725 {
ajsd2fc8892005-04-02 18:38:43 +0000726 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000727 return;
728 }
729 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
730 {
731 vty_out(vty, " index %d inactive interface%s",
732 ifp->ifindex,
733 VTY_NEWLINE);
734 return;
735 }
736
737 vty_out (vty, " index %d metric %d mtu %d ",
738 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000739#ifdef HAVE_IPV6
740 if (ifp->mtu6 != ifp->mtu)
741 vty_out (vty, "mtu6 %d ", ifp->mtu6);
742#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000743 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
744 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000745
paul718e3742002-12-13 20:15:29 +0000746 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000747#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000748 sdl = &ifp->sdl;
749 if (sdl != NULL && sdl->sdl_alen != 0)
750 {
751 int i;
752 u_char *ptr;
753
754 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000755 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
756 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000757 vty_out (vty, "%s", VTY_NEWLINE);
758 }
759#else
760 if (ifp->hw_addr_len != 0)
761 {
762 int i;
763
764 vty_out (vty, " HWaddr: ");
765 for (i = 0; i < ifp->hw_addr_len; i++)
766 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
767 vty_out (vty, "%s", VTY_NEWLINE);
768 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000769#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000770
771 /* Bandwidth in kbps */
772 if (ifp->bandwidth != 0)
773 {
774 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
775 vty_out(vty, "%s", VTY_NEWLINE);
776 }
777
hassoeef1fe12004-10-03 18:46:08 +0000778 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000779 {
hassoeef1fe12004-10-03 18:46:08 +0000780 if (! rn->info)
781 continue;
782
paul1eb8ef22005-04-07 07:30:20 +0000783 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
784 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000785 }
786
paul1eb8ef22005-04-07 07:30:20 +0000787 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000788 {
hasso39db97e2004-10-12 20:50:58 +0000789 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
790 (connected->address->family == AF_INET6))
791 connected_dump_vty (vty, connected);
792 }
793
paul718e3742002-12-13 20:15:29 +0000794#ifdef RTADV
795 nd_dump_vty (vty, ifp);
796#endif /* RTADV */
797
798#ifdef HAVE_PROC_NET_DEV
799 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000800 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
801 "%lu dropped%s",
802 ifp->stats.rx_packets, ifp->stats.rx_multicast,
803 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000804
hasso6f2c27a2005-01-18 13:44:35 +0000805 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000806 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000807 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
808 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000809 ifp->stats.rx_frame_errors, VTY_NEWLINE);
810
811 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000812 ifp->stats.rx_missed_errors, VTY_NEWLINE);
813
hasso6f2c27a2005-01-18 13:44:35 +0000814 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000815 ifp->stats.tx_packets, ifp->stats.tx_bytes,
816 ifp->stats.tx_dropped, VTY_NEWLINE);
817
hasso6f2c27a2005-01-18 13:44:35 +0000818 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
819 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000820 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
821 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000822 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000823
hasso6f2c27a2005-01-18 13:44:35 +0000824 vty_out (vty, " %lu window, %lu collisions%s",
825 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000826#endif /* HAVE_PROC_NET_DEV */
827
828#ifdef HAVE_NET_RT_IFLIST
829#if defined (__bsdi__) || defined (__NetBSD__)
830 /* Statistics print out using sysctl (). */
831 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
832 " multicast packets %qu%s",
833 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
834 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
835 VTY_NEWLINE);
836
837 vty_out (vty, " input errors %qu%s",
838 ifp->stats.ifi_ierrors, VTY_NEWLINE);
839
840 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
841 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
842 ifp->stats.ifi_omcasts, VTY_NEWLINE);
843
844 vty_out (vty, " output errors %qu%s",
845 ifp->stats.ifi_oerrors, VTY_NEWLINE);
846
847 vty_out (vty, " collisions %qu%s",
848 ifp->stats.ifi_collisions, VTY_NEWLINE);
849#else
850 /* Statistics print out using sysctl (). */
851 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
852 " multicast packets %lu%s",
853 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
854 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
855 VTY_NEWLINE);
856
857 vty_out (vty, " input errors %lu%s",
858 ifp->stats.ifi_ierrors, VTY_NEWLINE);
859
860 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
861 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
862 ifp->stats.ifi_omcasts, VTY_NEWLINE);
863
864 vty_out (vty, " output errors %lu%s",
865 ifp->stats.ifi_oerrors, VTY_NEWLINE);
866
867 vty_out (vty, " collisions %lu%s",
868 ifp->stats.ifi_collisions, VTY_NEWLINE);
869#endif /* __bsdi__ || __NetBSD__ */
870#endif /* HAVE_NET_RT_IFLIST */
871}
872
paul718e3742002-12-13 20:15:29 +0000873/* Wrapper hook point for zebra daemon so that ifindex can be set
874 * DEFUN macro not used as extract.pl HAS to ignore this
875 * See also interface_cmd in lib/if.c
876 */
877DEFUN_NOSH (zebra_interface,
878 zebra_interface_cmd,
879 "interface IFNAME",
880 "Select an interface to configure\n"
881 "Interface's name\n")
882{
883 int ret;
884 struct interface * ifp;
885
886 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000887 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
888 return ret;
paul718e3742002-12-13 20:15:29 +0000889
890 ifp = vty->index;
891
ajsd2fc8892005-04-02 18:38:43 +0000892 if (ifp->ifindex == IFINDEX_INTERNAL)
893 /* Is this really necessary? Shouldn't status be initialized to 0
894 in that case? */
895 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000896
897 return ret;
898}
899
paul718e3742002-12-13 20:15:29 +0000900struct cmd_node interface_node =
901{
902 INTERFACE_NODE,
903 "%s(config-if)# ",
904 1
905};
906
907/* Show all or specified interface to vty. */
908DEFUN (show_interface, show_interface_cmd,
909 "show interface [IFNAME]",
910 SHOW_STR
911 "Interface status and configuration\n"
912 "Inteface name\n")
913{
hasso52dc7ee2004-09-23 19:18:23 +0000914 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000915 struct interface *ifp;
916
917#ifdef HAVE_PROC_NET_DEV
918 /* If system has interface statistics via proc file system, update
919 statistics. */
920 ifstat_update_proc ();
921#endif /* HAVE_PROC_NET_DEV */
922#ifdef HAVE_NET_RT_IFLIST
923 ifstat_update_sysctl ();
924#endif /* HAVE_NET_RT_IFLIST */
925
926 /* Specified interface print. */
927 if (argc != 0)
928 {
929 ifp = if_lookup_by_name (argv[0]);
930 if (ifp == NULL)
931 {
932 vty_out (vty, "%% Can't find interface %s%s", argv[0],
933 VTY_NEWLINE);
934 return CMD_WARNING;
935 }
936 if_dump_vty (vty, ifp);
937 return CMD_SUCCESS;
938 }
939
940 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000941 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
942 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000943
944 return CMD_SUCCESS;
945}
946
hassoed9bb6d2005-03-13 19:17:21 +0000947DEFUN (show_interface_desc,
948 show_interface_desc_cmd,
949 "show interface description",
950 SHOW_STR
951 "Interface status and configuration\n"
952 "Interface description\n")
953{
954 struct listnode *node;
955 struct interface *ifp;
956
957 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000958 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000959 {
960 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000961
962 len = vty_out (vty, "%s", ifp->name);
963 vty_out (vty, "%*s", (16 - len), " ");
964
965 if (if_is_up(ifp))
966 {
967 vty_out (vty, "up ");
968 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
969 {
970 if (if_is_running(ifp))
971 vty_out (vty, "up ");
972 else
973 vty_out (vty, "down ");
974 }
975 else
976 {
977 vty_out (vty, "unknown ");
978 }
979 }
980 else
981 {
982 vty_out (vty, "down down ");
983 }
984
985 if (ifp->desc)
986 vty_out (vty, "%s", ifp->desc);
987 vty_out (vty, "%s", VTY_NEWLINE);
988 }
989 return CMD_SUCCESS;
990}
991
paul718e3742002-12-13 20:15:29 +0000992DEFUN (multicast,
993 multicast_cmd,
994 "multicast",
995 "Set multicast flag to interface\n")
996{
997 int ret;
998 struct interface *ifp;
999 struct zebra_if *if_data;
1000
1001 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001002 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001003 {
paul48b33aa2002-12-13 20:52:52 +00001004 ret = if_set_flags (ifp, IFF_MULTICAST);
1005 if (ret < 0)
1006 {
1007 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1008 return CMD_WARNING;
1009 }
1010 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001011 }
paul718e3742002-12-13 20:15:29 +00001012 if_data = ifp->info;
1013 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001014
paul718e3742002-12-13 20:15:29 +00001015 return CMD_SUCCESS;
1016}
1017
1018DEFUN (no_multicast,
1019 no_multicast_cmd,
1020 "no multicast",
1021 NO_STR
1022 "Unset multicast flag to interface\n")
1023{
1024 int ret;
1025 struct interface *ifp;
1026 struct zebra_if *if_data;
1027
1028 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001029 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001030 {
paul48b33aa2002-12-13 20:52:52 +00001031 ret = if_unset_flags (ifp, IFF_MULTICAST);
1032 if (ret < 0)
1033 {
1034 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1035 return CMD_WARNING;
1036 }
1037 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001038 }
paul718e3742002-12-13 20:15:29 +00001039 if_data = ifp->info;
1040 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1041
1042 return CMD_SUCCESS;
1043}
1044
paul2e3b2e42002-12-13 21:03:13 +00001045DEFUN (linkdetect,
1046 linkdetect_cmd,
1047 "link-detect",
1048 "Enable link detection on interface\n")
1049{
paul2e3b2e42002-12-13 21:03:13 +00001050 struct interface *ifp;
1051 int if_was_operative;
1052
1053 ifp = (struct interface *) vty->index;
1054 if_was_operative = if_is_operative(ifp);
1055 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1056
1057 /* When linkdetection is enabled, if might come down */
1058 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1059
1060 /* FIXME: Will defer status change forwarding if interface
1061 does not come down! */
1062
1063 return CMD_SUCCESS;
1064}
1065
1066
1067DEFUN (no_linkdetect,
1068 no_linkdetect_cmd,
1069 "no link-detect",
1070 NO_STR
1071 "Disable link detection on interface\n")
1072{
paul2e3b2e42002-12-13 21:03:13 +00001073 struct interface *ifp;
1074 int if_was_operative;
1075
1076 ifp = (struct interface *) vty->index;
1077 if_was_operative = if_is_operative(ifp);
1078 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1079
1080 /* Interface may come up after disabling link detection */
1081 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1082
1083 /* FIXME: see linkdetect_cmd */
1084
1085 return CMD_SUCCESS;
1086}
1087
paul718e3742002-12-13 20:15:29 +00001088DEFUN (shutdown_if,
1089 shutdown_if_cmd,
1090 "shutdown",
1091 "Shutdown the selected interface\n")
1092{
1093 int ret;
1094 struct interface *ifp;
1095 struct zebra_if *if_data;
1096
1097 ifp = (struct interface *) vty->index;
1098 ret = if_unset_flags (ifp, IFF_UP);
1099 if (ret < 0)
1100 {
1101 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1102 return CMD_WARNING;
1103 }
1104 if_refresh (ifp);
1105 if_data = ifp->info;
1106 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1107
1108 return CMD_SUCCESS;
1109}
1110
1111DEFUN (no_shutdown_if,
1112 no_shutdown_if_cmd,
1113 "no shutdown",
1114 NO_STR
1115 "Shutdown the selected interface\n")
1116{
1117 int ret;
1118 struct interface *ifp;
1119 struct zebra_if *if_data;
1120
1121 ifp = (struct interface *) vty->index;
1122 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1123 if (ret < 0)
1124 {
1125 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1126 return CMD_WARNING;
1127 }
1128 if_refresh (ifp);
1129 if_data = ifp->info;
1130 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1131
1132 return CMD_SUCCESS;
1133}
1134
1135DEFUN (bandwidth_if,
1136 bandwidth_if_cmd,
1137 "bandwidth <1-10000000>",
1138 "Set bandwidth informational parameter\n"
1139 "Bandwidth in kilobits\n")
1140{
1141 struct interface *ifp;
1142 unsigned int bandwidth;
1143
1144 ifp = (struct interface *) vty->index;
1145 bandwidth = strtol(argv[0], NULL, 10);
1146
1147 /* bandwidth range is <1-10000000> */
1148 if (bandwidth < 1 || bandwidth > 10000000)
1149 {
1150 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1151 return CMD_WARNING;
1152 }
1153
1154 ifp->bandwidth = bandwidth;
1155
1156 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001157 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001158 zebra_interface_up_update (ifp);
1159
1160 return CMD_SUCCESS;
1161}
1162
1163DEFUN (no_bandwidth_if,
1164 no_bandwidth_if_cmd,
1165 "no bandwidth",
1166 NO_STR
1167 "Set bandwidth informational parameter\n")
1168{
1169 struct interface *ifp;
1170
1171 ifp = (struct interface *) vty->index;
1172
1173 ifp->bandwidth = 0;
1174
1175 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001176 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001177 zebra_interface_up_update (ifp);
1178
1179 return CMD_SUCCESS;
1180}
1181
1182ALIAS (no_bandwidth_if,
1183 no_bandwidth_if_val_cmd,
1184 "no bandwidth <1-10000000>",
1185 NO_STR
1186 "Set bandwidth informational parameter\n"
1187 "Bandwidth in kilobits\n")
1188
paula1ac18c2005-06-28 17:17:12 +00001189static int
hasso39db97e2004-10-12 20:50:58 +00001190ip_address_install (struct vty *vty, struct interface *ifp,
1191 const char *addr_str, const char *peer_str,
1192 const char *label)
paul718e3742002-12-13 20:15:29 +00001193{
1194 struct prefix_ipv4 cp;
1195 struct connected *ifc;
1196 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001197 int ret;
1198
1199 ret = str2prefix_ipv4 (addr_str, &cp);
1200 if (ret <= 0)
1201 {
1202 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1203 return CMD_WARNING;
1204 }
1205
paulca162182005-09-12 16:58:52 +00001206 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001207 if (! ifc)
1208 {
1209 ifc = connected_new ();
1210 ifc->ifp = ifp;
1211
1212 /* Address. */
1213 p = prefix_ipv4_new ();
1214 *p = cp;
1215 ifc->address = (struct prefix *) p;
1216
1217 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001218 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001219 {
1220 p = prefix_ipv4_new ();
1221 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001222 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001223 ifc->destination = (struct prefix *) p;
1224 }
1225
paul718e3742002-12-13 20:15:29 +00001226 /* Label. */
1227 if (label)
paul0752ef02005-11-03 12:35:21 +00001228 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001229
1230 /* Add to linked list. */
1231 listnode_add (ifp->connected, ifc);
1232 }
1233
1234 /* This address is configured from zebra. */
1235 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1236 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1237
1238 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001239 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001240 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1241 {
1242 /* Some system need to up the interface to set IP address. */
1243 if (! if_is_up (ifp))
1244 {
1245 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1246 if_refresh (ifp);
1247 }
1248
1249 ret = if_set_prefix (ifp, ifc);
1250 if (ret < 0)
1251 {
1252 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001253 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001254 return CMD_WARNING;
1255 }
1256
Christian Frankef7f740f2013-01-24 14:04:48 +00001257 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001258 /* The address will be advertised to zebra clients when the notification
1259 * from the kernel has been received.
1260 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001261 }
1262
1263 return CMD_SUCCESS;
1264}
1265
paula1ac18c2005-06-28 17:17:12 +00001266static int
hasso39db97e2004-10-12 20:50:58 +00001267ip_address_uninstall (struct vty *vty, struct interface *ifp,
1268 const char *addr_str, const char *peer_str,
1269 const char *label)
paul718e3742002-12-13 20:15:29 +00001270{
1271 struct prefix_ipv4 cp;
1272 struct connected *ifc;
1273 int ret;
1274
1275 /* Convert to prefix structure. */
1276 ret = str2prefix_ipv4 (addr_str, &cp);
1277 if (ret <= 0)
1278 {
1279 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1280 return CMD_WARNING;
1281 }
1282
1283 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001284 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001285 if (! ifc)
1286 {
1287 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1288 return CMD_WARNING;
1289 }
1290
1291 /* This is not configured address. */
1292 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1293 return CMD_WARNING;
1294
Paul Jakma74ecdc92006-06-15 18:10:47 +00001295 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1296
paul718e3742002-12-13 20:15:29 +00001297 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001298 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001299 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1300 {
1301 listnode_delete (ifp->connected, ifc);
1302 connected_free (ifc);
1303 return CMD_WARNING;
1304 }
1305
1306 /* This is real route. */
1307 ret = if_unset_prefix (ifp, ifc);
1308 if (ret < 0)
1309 {
1310 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001311 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001312 return CMD_WARNING;
1313 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001314 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001315 /* we will receive a kernel notification about this route being removed.
1316 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001317 return CMD_SUCCESS;
1318}
1319
1320DEFUN (ip_address,
1321 ip_address_cmd,
1322 "ip address A.B.C.D/M",
1323 "Interface Internet Protocol config commands\n"
1324 "Set the IP address of an interface\n"
1325 "IP address (e.g. 10.0.0.1/8)\n")
1326{
hassoeef1fe12004-10-03 18:46:08 +00001327 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001328}
1329
1330DEFUN (no_ip_address,
1331 no_ip_address_cmd,
1332 "no ip address A.B.C.D/M",
1333 NO_STR
1334 "Interface Internet Protocol config commands\n"
1335 "Set the IP address of an interface\n"
1336 "IP Address (e.g. 10.0.0.1/8)")
1337{
hassoeef1fe12004-10-03 18:46:08 +00001338 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001339}
1340
1341#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001342DEFUN (ip_address_label,
1343 ip_address_label_cmd,
1344 "ip address A.B.C.D/M label LINE",
1345 "Interface Internet Protocol config commands\n"
1346 "Set the IP address of an interface\n"
1347 "IP address (e.g. 10.0.0.1/8)\n"
1348 "Label of this address\n"
1349 "Label\n")
1350{
hassoeef1fe12004-10-03 18:46:08 +00001351 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001352}
1353
1354DEFUN (no_ip_address_label,
1355 no_ip_address_label_cmd,
1356 "no ip address A.B.C.D/M label LINE",
1357 NO_STR
1358 "Interface Internet Protocol config commands\n"
1359 "Set the IP address of an interface\n"
1360 "IP address (e.g. 10.0.0.1/8)\n"
1361 "Label of this address\n"
1362 "Label\n")
1363{
hassoeef1fe12004-10-03 18:46:08 +00001364 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001365}
1366#endif /* HAVE_NETLINK */
1367
1368#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001369static int
hasso39db97e2004-10-12 20:50:58 +00001370ipv6_address_install (struct vty *vty, struct interface *ifp,
1371 const char *addr_str, const char *peer_str,
1372 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001373{
1374 struct prefix_ipv6 cp;
1375 struct connected *ifc;
1376 struct prefix_ipv6 *p;
1377 int ret;
1378
1379 ret = str2prefix_ipv6 (addr_str, &cp);
1380 if (ret <= 0)
1381 {
1382 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1383 return CMD_WARNING;
1384 }
1385
paulca162182005-09-12 16:58:52 +00001386 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001387 if (! ifc)
1388 {
1389 ifc = connected_new ();
1390 ifc->ifp = ifp;
1391
1392 /* Address. */
1393 p = prefix_ipv6_new ();
1394 *p = cp;
1395 ifc->address = (struct prefix *) p;
1396
1397 /* Secondary. */
1398 if (secondary)
1399 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1400
1401 /* Label. */
1402 if (label)
paul0752ef02005-11-03 12:35:21 +00001403 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001404
1405 /* Add to linked list. */
1406 listnode_add (ifp->connected, ifc);
1407 }
1408
1409 /* This address is configured from zebra. */
1410 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1411 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1412
1413 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001414 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001415 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1416 {
1417 /* Some system need to up the interface to set IP address. */
1418 if (! if_is_up (ifp))
1419 {
1420 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1421 if_refresh (ifp);
1422 }
1423
1424 ret = if_prefix_add_ipv6 (ifp, ifc);
1425
1426 if (ret < 0)
1427 {
1428 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001429 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001430 return CMD_WARNING;
1431 }
1432
Christian Frankef7f740f2013-01-24 14:04:48 +00001433 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001434 /* The address will be advertised to zebra clients when the notification
1435 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001436 }
1437
1438 return CMD_SUCCESS;
1439}
1440
paula1ac18c2005-06-28 17:17:12 +00001441static int
hasso39db97e2004-10-12 20:50:58 +00001442ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1443 const char *addr_str, const char *peer_str,
1444 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001445{
1446 struct prefix_ipv6 cp;
1447 struct connected *ifc;
1448 int ret;
1449
1450 /* Convert to prefix structure. */
1451 ret = str2prefix_ipv6 (addr_str, &cp);
1452 if (ret <= 0)
1453 {
1454 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1455 return CMD_WARNING;
1456 }
1457
1458 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001459 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001460 if (! ifc)
1461 {
1462 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1463 return CMD_WARNING;
1464 }
1465
1466 /* This is not configured address. */
1467 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1468 return CMD_WARNING;
1469
Christian Franke676e1a02013-01-24 14:04:45 +00001470 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1471
paul718e3742002-12-13 20:15:29 +00001472 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001473 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001474 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1475 {
1476 listnode_delete (ifp->connected, ifc);
1477 connected_free (ifc);
1478 return CMD_WARNING;
1479 }
1480
1481 /* This is real route. */
1482 ret = if_prefix_delete_ipv6 (ifp, ifc);
1483 if (ret < 0)
1484 {
1485 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001486 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001487 return CMD_WARNING;
1488 }
1489
Christian Frankef7f740f2013-01-24 14:04:48 +00001490 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001491 /* This information will be propagated to the zclients when the
1492 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001493 return CMD_SUCCESS;
1494}
1495
1496DEFUN (ipv6_address,
1497 ipv6_address_cmd,
1498 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001499 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001500 "Set the IP address of an interface\n"
1501 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1502{
1503 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1504}
1505
1506DEFUN (no_ipv6_address,
1507 no_ipv6_address_cmd,
1508 "no ipv6 address X:X::X:X/M",
1509 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001510 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001511 "Set the IP address of an interface\n"
1512 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1513{
1514 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1515}
1516#endif /* HAVE_IPV6 */
1517
paula1ac18c2005-06-28 17:17:12 +00001518static int
paul718e3742002-12-13 20:15:29 +00001519if_config_write (struct vty *vty)
1520{
hasso52dc7ee2004-09-23 19:18:23 +00001521 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001522 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001523
paul1eb8ef22005-04-07 07:30:20 +00001524 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001525 {
1526 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001527 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001528 struct connected *ifc;
1529 struct prefix *p;
1530
paul718e3742002-12-13 20:15:29 +00001531 if_data = ifp->info;
1532
1533 vty_out (vty, "interface %s%s", ifp->name,
1534 VTY_NEWLINE);
1535
1536 if (ifp->desc)
1537 vty_out (vty, " description %s%s", ifp->desc,
1538 VTY_NEWLINE);
1539
1540 /* Assign bandwidth here to avoid unnecessary interface flap
1541 while processing config script */
1542 if (ifp->bandwidth != 0)
1543 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1544
paul2e3b2e42002-12-13 21:03:13 +00001545 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1546 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1547
paul1eb8ef22005-04-07 07:30:20 +00001548 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001549 {
paul718e3742002-12-13 20:15:29 +00001550 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1551 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001552 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001553 p = ifc->address;
1554 vty_out (vty, " ip%s address %s/%d",
1555 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001556 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001557 p->prefixlen);
1558
paul718e3742002-12-13 20:15:29 +00001559 if (ifc->label)
1560 vty_out (vty, " label %s", ifc->label);
1561
1562 vty_out (vty, "%s", VTY_NEWLINE);
1563 }
1564 }
1565
1566 if (if_data)
1567 {
1568 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1569 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1570
1571 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1572 vty_out (vty, " %smulticast%s",
1573 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1574 VTY_NEWLINE);
1575 }
1576
1577#ifdef RTADV
1578 rtadv_config_write (vty, ifp);
1579#endif /* RTADV */
1580
hassoca776982004-06-12 14:33:05 +00001581#ifdef HAVE_IRDP
1582 irdp_config_write (vty, ifp);
1583#endif /* IRDP */
1584
paul718e3742002-12-13 20:15:29 +00001585 vty_out (vty, "!%s", VTY_NEWLINE);
1586 }
1587 return 0;
1588}
1589
1590/* Allocate and initialize interface vector. */
1591void
paula1ac18c2005-06-28 17:17:12 +00001592zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001593{
1594 /* Initialize interface and new hook. */
1595 if_init ();
1596 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1597 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1598
1599 /* Install configuration write function. */
1600 install_node (&interface_node, if_config_write);
1601
1602 install_element (VIEW_NODE, &show_interface_cmd);
1603 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001604 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001605 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001606 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001607 install_default (INTERFACE_NODE);
1608 install_element (INTERFACE_NODE, &interface_desc_cmd);
1609 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1610 install_element (INTERFACE_NODE, &multicast_cmd);
1611 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001612 install_element (INTERFACE_NODE, &linkdetect_cmd);
1613 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001614 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1615 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1616 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1617 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1618 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1619 install_element (INTERFACE_NODE, &ip_address_cmd);
1620 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1621#ifdef HAVE_IPV6
1622 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1623 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1624#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001625#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001626 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001627 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001628#endif /* HAVE_NETLINK */
1629}