blob: 22422594c7f417a639af88c43f197966a5eb1884 [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))
164 return -1;
165 route_unlock_node (rn);
166
167 /* Untie address from subnet's address list. */
168 addr_list = rn->info;
169 listnode_delete (addr_list, ifc);
170 route_unlock_node (rn);
171
172 /* Return list element count, if not empty. */
173 if (addr_list->count)
174 {
175 /* If deleted address is primary, mark subsequent one as such and distribute. */
176 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
177 {
paul1eb8ef22005-04-07 07:30:20 +0000178 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000179 zebra_interface_address_delete_update (ifp, ifc);
180 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
181 zebra_interface_address_add_update (ifp, ifc);
182 }
183
184 return addr_list->count;
185 }
186
187 /* Otherwise, free list and route node. */
188 list_free (addr_list);
189 rn->info = NULL;
190 route_unlock_node (rn);
191
paul718e3742002-12-13 20:15:29 +0000192 return 0;
193}
194
paul5c78b3d2006-01-25 04:31:40 +0000195/* if_flags_mangle: A place for hacks that require mangling
196 * or tweaking the interface flags.
197 *
198 * ******************** Solaris flags hacks **************************
199 *
200 * Solaris IFF_UP flag reflects only the primary interface as the
201 * routing socket only sends IFINFO for the primary interface. Hence
202 * ~IFF_UP does not per se imply all the logical interfaces are also
203 * down - which we only know of as addresses. Instead we must determine
204 * whether the interface really is up or not according to how many
205 * addresses are still attached. (Solaris always sends RTM_DELADDR if
206 * an interface, logical or not, goes ~IFF_UP).
207 *
208 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
209 * are addresses left in struct connected, not just the actual underlying
210 * IFF_UP flag.
211 *
212 * We must hence remember the real state of IFF_UP, which we do in
213 * struct zebra_if.primary_state.
214 *
215 * Setting IFF_UP within zebra to administratively shutdown the
216 * interface will affect only the primary interface/address on Solaris.
217 ************************End Solaris flags hacks ***********************
218 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100219static void
paul5c78b3d2006-01-25 04:31:40 +0000220if_flags_mangle (struct interface *ifp, uint64_t *newflags)
221{
222#ifdef SUNOS_5
223 struct zebra_if *zif = ifp->info;
224
225 zif->primary_state = *newflags & (IFF_UP & 0xff);
226
227 if (CHECK_FLAG (zif->primary_state, IFF_UP)
228 || listcount(ifp->connected) > 0)
229 SET_FLAG (*newflags, IFF_UP);
230 else
231 UNSET_FLAG (*newflags, IFF_UP);
232#endif /* SUNOS_5 */
233}
234
235/* Update the flags field of the ifp with the new flag set provided.
236 * Take whatever actions are required for any changes in flags we care
237 * about.
238 *
239 * newflags should be the raw value, as obtained from the OS.
240 */
241void
242if_flags_update (struct interface *ifp, uint64_t newflags)
243{
244 if_flags_mangle (ifp, &newflags);
245
246 if (if_is_operative (ifp))
247 {
248 /* operative -> inoperative? */
249 ifp->flags = newflags;
250 if (!if_is_operative (ifp))
251 if_down (ifp);
252 }
253 else
254 {
255 /* inoperative -> operative? */
256 ifp->flags = newflags;
257 if (if_is_operative (ifp))
258 if_up (ifp);
259 }
260}
261
paul718e3742002-12-13 20:15:29 +0000262/* Wake up configured address if it is not in current kernel
263 address. */
paula1ac18c2005-06-28 17:17:12 +0000264static void
paul718e3742002-12-13 20:15:29 +0000265if_addr_wakeup (struct interface *ifp)
266{
paul1eb8ef22005-04-07 07:30:20 +0000267 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000268 struct connected *ifc;
269 struct prefix *p;
270 int ret;
271
paul1eb8ef22005-04-07 07:30:20 +0000272 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000273 {
paul718e3742002-12-13 20:15:29 +0000274 p = ifc->address;
275
276 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
277 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
278 {
279 /* Address check. */
280 if (p->family == AF_INET)
281 {
282 if (! if_is_up (ifp))
283 {
paul0752ef02005-11-03 12:35:21 +0000284 /* XXX: WTF is it trying to set flags here?
285 * caller has just gotten a new interface, has been
286 * handed the flags already. This code has no business
287 * trying to override administrative status of the interface.
288 * The only call path to here which doesn't originate from
289 * kernel event is irdp - what on earth is it trying to do?
290 *
291 * further RUNNING is not a settable flag on any system
292 * I (paulj) am aware of.
293 */
paul718e3742002-12-13 20:15:29 +0000294 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
295 if_refresh (ifp);
296 }
297
298 ret = if_set_prefix (ifp, ifc);
299 if (ret < 0)
300 {
301 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000302 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000303 continue;
304 }
hassoeef1fe12004-10-03 18:46:08 +0000305
306 /* Add to subnet chain list. */
307 if_subnet_add (ifp, ifc);
308
paul718e3742002-12-13 20:15:29 +0000309 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
310
311 zebra_interface_address_add_update (ifp, ifc);
312
paul2e3b2e42002-12-13 21:03:13 +0000313 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000314 connected_up_ipv4 (ifp, ifc);
315 }
316#ifdef HAVE_IPV6
317 if (p->family == AF_INET6)
318 {
319 if (! if_is_up (ifp))
320 {
paul0752ef02005-11-03 12:35:21 +0000321 /* XXX: See long comment above */
paul718e3742002-12-13 20:15:29 +0000322 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
323 if_refresh (ifp);
324 }
325
326 ret = if_prefix_add_ipv6 (ifp, ifc);
327 if (ret < 0)
328 {
329 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000330 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000331 continue;
332 }
333 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
334
335 zebra_interface_address_add_update (ifp, ifc);
336
paul2e3b2e42002-12-13 21:03:13 +0000337 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +0000338 connected_up_ipv6 (ifp, ifc);
339 }
340#endif /* HAVE_IPV6 */
341 }
342 }
343}
344
345/* Handle interface addition */
346void
347if_add_update (struct interface *ifp)
348{
paul48b33aa2002-12-13 20:52:52 +0000349 struct zebra_if *if_data;
350
351 if_data = ifp->info;
352 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
353 if_set_flags (ifp, IFF_MULTICAST);
354 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
355 if_unset_flags (ifp, IFF_MULTICAST);
356
paul718e3742002-12-13 20:15:29 +0000357 zebra_interface_add_update (ifp);
358
359 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
360 {
361 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
362
363 if_addr_wakeup (ifp);
364
365 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000366 zlog_debug ("interface %s index %d becomes active.",
367 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000368 }
369 else
370 {
371 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000372 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000373 }
374}
375
paul6eb88272005-07-29 14:36:00 +0000376/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000377void
378if_delete_update (struct interface *ifp)
379{
paul718e3742002-12-13 20:15:29 +0000380 struct connected *ifc;
381 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000382 struct route_node *rn;
383 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000384
385 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000386
387 if (if_is_up(ifp))
388 {
389 zlog_err ("interface %s index %d is still up while being deleted.",
390 ifp->name, ifp->ifindex);
391 return;
392 }
393
394 /* Mark interface as inactive */
395 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
396
397 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000398 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000399 ifp->name, ifp->ifindex);
400
401 /* Delete connected routes from the kernel. */
402 if (ifp->connected)
403 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000404 struct listnode *node;
405 struct listnode *last = NULL;
406
hassoeef1fe12004-10-03 18:46:08 +0000407 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000408 {
paul1eb8ef22005-04-07 07:30:20 +0000409 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000410 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000411
Paul Jakmabeb56332006-05-11 13:28:05 +0000412 if (p->family == AF_INET
413 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000414 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000415 struct listnode *anode;
416 struct listnode *next;
417 struct listnode *first;
418 struct list *addr_list;
419
hassoeef1fe12004-10-03 18:46:08 +0000420 route_unlock_node (rn);
421 addr_list = (struct list *) rn->info;
422
423 /* Remove addresses, secondaries first. */
424 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000425 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000426 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000427 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000428 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000429 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000430 first = NULL;
431 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000432 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000433
Paul Jakmad9a18f12007-04-10 19:30:20 +0000434 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000435 p = ifc->address;
436
437 connected_down_ipv4 (ifp, ifc);
438
439 zebra_interface_address_delete_update (ifp, ifc);
440
441 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
442
443 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000444 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000445 route_unlock_node (rn);
446
447 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000448 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
449 {
450 listnode_delete (ifp->connected, ifc);
451 connected_free (ifc);
452 }
453 else
454 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000455 }
456
457 /* Free chain list and respective route node. */
458 list_delete (addr_list);
459 rn->info = NULL;
460 route_unlock_node (rn);
461 }
paul718e3742002-12-13 20:15:29 +0000462#ifdef HAVE_IPV6
463 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000464 {
465 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000466
hassoeef1fe12004-10-03 18:46:08 +0000467 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000468
hassoeef1fe12004-10-03 18:46:08 +0000469 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
470
471 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
472 last = node;
473 else
474 {
475 listnode_delete (ifp->connected, ifc);
476 connected_free (ifc);
477 }
paul718e3742002-12-13 20:15:29 +0000478 }
hassoeef1fe12004-10-03 18:46:08 +0000479#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200480 else
481 {
482 last = node;
483 }
paul718e3742002-12-13 20:15:29 +0000484 }
485 }
486 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000487
488 /* Update ifindex after distributing the delete message. This is in
489 case any client needs to have the old value of ifindex available
490 while processing the deletion. Each client daemon is responsible
491 for setting ifindex to IFINDEX_INTERNAL after processing the
492 interface deletion message. */
493 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000494}
495
496/* Interface is up. */
497void
498if_up (struct interface *ifp)
499{
hasso52dc7ee2004-09-23 19:18:23 +0000500 struct listnode *node;
501 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000502 struct connected *ifc;
503 struct prefix *p;
504
505 /* Notify the protocol daemons. */
506 zebra_interface_up_update (ifp);
507
508 /* Install connected routes to the kernel. */
509 if (ifp->connected)
510 {
paul1eb8ef22005-04-07 07:30:20 +0000511 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000512 {
paul718e3742002-12-13 20:15:29 +0000513 p = ifc->address;
514
515 if (p->family == AF_INET)
516 connected_up_ipv4 (ifp, ifc);
517#ifdef HAVE_IPV6
518 else if (p->family == AF_INET6)
519 connected_up_ipv6 (ifp, ifc);
520#endif /* HAVE_IPV6 */
521 }
522 }
523
524 /* Examine all static routes. */
525 rib_update ();
526}
527
528/* Interface goes down. We have to manage different behavior of based
529 OS. */
530void
531if_down (struct interface *ifp)
532{
hasso52dc7ee2004-09-23 19:18:23 +0000533 struct listnode *node;
534 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000535 struct connected *ifc;
536 struct prefix *p;
537
538 /* Notify to the protocol daemons. */
539 zebra_interface_down_update (ifp);
540
541 /* Delete connected routes from the kernel. */
542 if (ifp->connected)
543 {
paul1eb8ef22005-04-07 07:30:20 +0000544 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000545 {
paul718e3742002-12-13 20:15:29 +0000546 p = ifc->address;
547
548 if (p->family == AF_INET)
549 connected_down_ipv4 (ifp, ifc);
550#ifdef HAVE_IPV6
551 else if (p->family == AF_INET6)
552 connected_down_ipv6 (ifp, ifc);
553#endif /* HAVE_IPV6 */
554 }
555 }
556
557 /* Examine all static routes which direct to the interface. */
558 rib_update ();
559}
560
561void
562if_refresh (struct interface *ifp)
563{
paul5c78b3d2006-01-25 04:31:40 +0000564 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000565}
566
paul718e3742002-12-13 20:15:29 +0000567/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000568static int
paul718e3742002-12-13 20:15:29 +0000569prefix_vty_out (struct vty *vty, struct prefix *p)
570{
571 char str[INET6_ADDRSTRLEN];
572
573 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
574 vty_out (vty, "%s", str);
575 return strlen (str);
576}
577
578/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000579static void
paul718e3742002-12-13 20:15:29 +0000580connected_dump_vty (struct vty *vty, struct connected *connected)
581{
582 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000583
584 /* Print interface address. */
585 p = connected->address;
586 vty_out (vty, " %s ", prefix_family_str (p));
587 prefix_vty_out (vty, p);
588 vty_out (vty, "/%d", p->prefixlen);
589
590 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000591 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000592 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000593 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
594 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000595 }
596
597 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
598 vty_out (vty, " secondary");
599
600 if (connected->label)
601 vty_out (vty, " %s", connected->label);
602
603 vty_out (vty, "%s", VTY_NEWLINE);
604}
605
606#ifdef RTADV
607/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000608static void
paul718e3742002-12-13 20:15:29 +0000609nd_dump_vty (struct vty *vty, struct interface *ifp)
610{
611 struct zebra_if *zif;
612 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000613 int interval;
paul718e3742002-12-13 20:15:29 +0000614
615 zif = (struct zebra_if *) ifp->info;
616 rtadv = &zif->rtadv;
617
618 if (rtadv->AdvSendAdvertisements)
619 {
620 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
621 rtadv->AdvReachableTime, VTY_NEWLINE);
622 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
623 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000624 interval = rtadv->MaxRtrAdvInterval;
625 if (interval % 1000)
626 vty_out (vty, " ND router advertisements are sent every "
627 "%d milliseconds%s", interval,
628 VTY_NEWLINE);
629 else
630 vty_out (vty, " ND router advertisements are sent every "
631 "%d seconds%s", interval / 1000,
632 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400633 if (rtadv->AdvDefaultLifetime != -1)
634 vty_out (vty, " ND router advertisements live for %d seconds%s",
635 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
636 else
637 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
638 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000639 vty_out (vty, " ND router advertisement default router preference is "
640 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
641 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000642 if (rtadv->AdvManagedFlag)
643 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
644 VTY_NEWLINE);
645 else
646 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
647 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000648 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400649 {
vincent7cee1bb2005-03-25 13:08:53 +0000650 vty_out (vty, " ND router advertisements with "
651 "Home Agent flag bit set.%s",
652 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400653 if (rtadv->HomeAgentLifetime != -1)
654 vty_out (vty, " Home Agent lifetime is %u seconds%s",
655 rtadv->HomeAgentLifetime, VTY_NEWLINE);
656 else
657 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
658 VTY_NEWLINE);
659 vty_out (vty, " Home Agent preference is %u%s",
660 rtadv->HomeAgentPreference, VTY_NEWLINE);
661 }
vincent7cee1bb2005-03-25 13:08:53 +0000662 if (rtadv->AdvIntervalOption)
663 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
664 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000665 }
666}
667#endif /* RTADV */
668
669/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000670static void
paul718e3742002-12-13 20:15:29 +0000671if_dump_vty (struct vty *vty, struct interface *ifp)
672{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000673#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000674 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000675#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000676 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000677 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000678 struct route_node *rn;
679 struct zebra_if *zebra_if;
680
681 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000682
paul2e3b2e42002-12-13 21:03:13 +0000683 vty_out (vty, "Interface %s is ", ifp->name);
684 if (if_is_up(ifp)) {
685 vty_out (vty, "up, line protocol ");
686
687 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
688 if (if_is_running(ifp))
689 vty_out (vty, "is up%s", VTY_NEWLINE);
690 else
691 vty_out (vty, "is down%s", VTY_NEWLINE);
692 } else {
693 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
694 }
695 } else {
696 vty_out (vty, "down%s", VTY_NEWLINE);
697 }
698
paul718e3742002-12-13 20:15:29 +0000699 if (ifp->desc)
700 vty_out (vty, " Description: %s%s", ifp->desc,
701 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000702 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000703 {
ajsd2fc8892005-04-02 18:38:43 +0000704 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000705 return;
706 }
707 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
708 {
709 vty_out(vty, " index %d inactive interface%s",
710 ifp->ifindex,
711 VTY_NEWLINE);
712 return;
713 }
714
715 vty_out (vty, " index %d metric %d mtu %d ",
716 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000717#ifdef HAVE_IPV6
718 if (ifp->mtu6 != ifp->mtu)
719 vty_out (vty, "mtu6 %d ", ifp->mtu6);
720#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000721 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
722 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000723
paul718e3742002-12-13 20:15:29 +0000724 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000725#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000726 sdl = &ifp->sdl;
727 if (sdl != NULL && sdl->sdl_alen != 0)
728 {
729 int i;
730 u_char *ptr;
731
732 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000733 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
734 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000735 vty_out (vty, "%s", VTY_NEWLINE);
736 }
737#else
738 if (ifp->hw_addr_len != 0)
739 {
740 int i;
741
742 vty_out (vty, " HWaddr: ");
743 for (i = 0; i < ifp->hw_addr_len; i++)
744 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
745 vty_out (vty, "%s", VTY_NEWLINE);
746 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000747#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000748
749 /* Bandwidth in kbps */
750 if (ifp->bandwidth != 0)
751 {
752 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
753 vty_out(vty, "%s", VTY_NEWLINE);
754 }
755
hassoeef1fe12004-10-03 18:46:08 +0000756 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000757 {
hassoeef1fe12004-10-03 18:46:08 +0000758 if (! rn->info)
759 continue;
760
paul1eb8ef22005-04-07 07:30:20 +0000761 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
762 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000763 }
764
paul1eb8ef22005-04-07 07:30:20 +0000765 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000766 {
hasso39db97e2004-10-12 20:50:58 +0000767 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
768 (connected->address->family == AF_INET6))
769 connected_dump_vty (vty, connected);
770 }
771
paul718e3742002-12-13 20:15:29 +0000772#ifdef RTADV
773 nd_dump_vty (vty, ifp);
774#endif /* RTADV */
775
776#ifdef HAVE_PROC_NET_DEV
777 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000778 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
779 "%lu dropped%s",
780 ifp->stats.rx_packets, ifp->stats.rx_multicast,
781 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000782
hasso6f2c27a2005-01-18 13:44:35 +0000783 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000784 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000785 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
786 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000787 ifp->stats.rx_frame_errors, VTY_NEWLINE);
788
789 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000790 ifp->stats.rx_missed_errors, VTY_NEWLINE);
791
hasso6f2c27a2005-01-18 13:44:35 +0000792 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000793 ifp->stats.tx_packets, ifp->stats.tx_bytes,
794 ifp->stats.tx_dropped, VTY_NEWLINE);
795
hasso6f2c27a2005-01-18 13:44:35 +0000796 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
797 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000798 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
799 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000800 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000801
hasso6f2c27a2005-01-18 13:44:35 +0000802 vty_out (vty, " %lu window, %lu collisions%s",
803 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000804#endif /* HAVE_PROC_NET_DEV */
805
806#ifdef HAVE_NET_RT_IFLIST
807#if defined (__bsdi__) || defined (__NetBSD__)
808 /* Statistics print out using sysctl (). */
809 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
810 " multicast packets %qu%s",
811 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
812 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
813 VTY_NEWLINE);
814
815 vty_out (vty, " input errors %qu%s",
816 ifp->stats.ifi_ierrors, VTY_NEWLINE);
817
818 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
819 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
820 ifp->stats.ifi_omcasts, VTY_NEWLINE);
821
822 vty_out (vty, " output errors %qu%s",
823 ifp->stats.ifi_oerrors, VTY_NEWLINE);
824
825 vty_out (vty, " collisions %qu%s",
826 ifp->stats.ifi_collisions, VTY_NEWLINE);
827#else
828 /* Statistics print out using sysctl (). */
829 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
830 " multicast packets %lu%s",
831 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
832 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
833 VTY_NEWLINE);
834
835 vty_out (vty, " input errors %lu%s",
836 ifp->stats.ifi_ierrors, VTY_NEWLINE);
837
838 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
839 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
840 ifp->stats.ifi_omcasts, VTY_NEWLINE);
841
842 vty_out (vty, " output errors %lu%s",
843 ifp->stats.ifi_oerrors, VTY_NEWLINE);
844
845 vty_out (vty, " collisions %lu%s",
846 ifp->stats.ifi_collisions, VTY_NEWLINE);
847#endif /* __bsdi__ || __NetBSD__ */
848#endif /* HAVE_NET_RT_IFLIST */
849}
850
paul718e3742002-12-13 20:15:29 +0000851/* Wrapper hook point for zebra daemon so that ifindex can be set
852 * DEFUN macro not used as extract.pl HAS to ignore this
853 * See also interface_cmd in lib/if.c
854 */
855DEFUN_NOSH (zebra_interface,
856 zebra_interface_cmd,
857 "interface IFNAME",
858 "Select an interface to configure\n"
859 "Interface's name\n")
860{
861 int ret;
862 struct interface * ifp;
863
864 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000865 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
866 return ret;
paul718e3742002-12-13 20:15:29 +0000867
868 ifp = vty->index;
869
ajsd2fc8892005-04-02 18:38:43 +0000870 if (ifp->ifindex == IFINDEX_INTERNAL)
871 /* Is this really necessary? Shouldn't status be initialized to 0
872 in that case? */
873 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000874
875 return ret;
876}
877
paul718e3742002-12-13 20:15:29 +0000878struct cmd_node interface_node =
879{
880 INTERFACE_NODE,
881 "%s(config-if)# ",
882 1
883};
884
885/* Show all or specified interface to vty. */
886DEFUN (show_interface, show_interface_cmd,
887 "show interface [IFNAME]",
888 SHOW_STR
889 "Interface status and configuration\n"
890 "Inteface name\n")
891{
hasso52dc7ee2004-09-23 19:18:23 +0000892 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000893 struct interface *ifp;
894
895#ifdef HAVE_PROC_NET_DEV
896 /* If system has interface statistics via proc file system, update
897 statistics. */
898 ifstat_update_proc ();
899#endif /* HAVE_PROC_NET_DEV */
900#ifdef HAVE_NET_RT_IFLIST
901 ifstat_update_sysctl ();
902#endif /* HAVE_NET_RT_IFLIST */
903
904 /* Specified interface print. */
905 if (argc != 0)
906 {
907 ifp = if_lookup_by_name (argv[0]);
908 if (ifp == NULL)
909 {
910 vty_out (vty, "%% Can't find interface %s%s", argv[0],
911 VTY_NEWLINE);
912 return CMD_WARNING;
913 }
914 if_dump_vty (vty, ifp);
915 return CMD_SUCCESS;
916 }
917
918 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000919 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
920 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000921
922 return CMD_SUCCESS;
923}
924
hassoed9bb6d2005-03-13 19:17:21 +0000925DEFUN (show_interface_desc,
926 show_interface_desc_cmd,
927 "show interface description",
928 SHOW_STR
929 "Interface status and configuration\n"
930 "Interface description\n")
931{
932 struct listnode *node;
933 struct interface *ifp;
934
935 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000936 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000937 {
938 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000939
940 len = vty_out (vty, "%s", ifp->name);
941 vty_out (vty, "%*s", (16 - len), " ");
942
943 if (if_is_up(ifp))
944 {
945 vty_out (vty, "up ");
946 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
947 {
948 if (if_is_running(ifp))
949 vty_out (vty, "up ");
950 else
951 vty_out (vty, "down ");
952 }
953 else
954 {
955 vty_out (vty, "unknown ");
956 }
957 }
958 else
959 {
960 vty_out (vty, "down down ");
961 }
962
963 if (ifp->desc)
964 vty_out (vty, "%s", ifp->desc);
965 vty_out (vty, "%s", VTY_NEWLINE);
966 }
967 return CMD_SUCCESS;
968}
969
paul718e3742002-12-13 20:15:29 +0000970DEFUN (multicast,
971 multicast_cmd,
972 "multicast",
973 "Set multicast flag to interface\n")
974{
975 int ret;
976 struct interface *ifp;
977 struct zebra_if *if_data;
978
979 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +0000980 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +0000981 {
paul48b33aa2002-12-13 20:52:52 +0000982 ret = if_set_flags (ifp, IFF_MULTICAST);
983 if (ret < 0)
984 {
985 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
986 return CMD_WARNING;
987 }
988 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +0000989 }
paul718e3742002-12-13 20:15:29 +0000990 if_data = ifp->info;
991 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +0000992
paul718e3742002-12-13 20:15:29 +0000993 return CMD_SUCCESS;
994}
995
996DEFUN (no_multicast,
997 no_multicast_cmd,
998 "no multicast",
999 NO_STR
1000 "Unset multicast flag to interface\n")
1001{
1002 int ret;
1003 struct interface *ifp;
1004 struct zebra_if *if_data;
1005
1006 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001007 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001008 {
paul48b33aa2002-12-13 20:52:52 +00001009 ret = if_unset_flags (ifp, IFF_MULTICAST);
1010 if (ret < 0)
1011 {
1012 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1013 return CMD_WARNING;
1014 }
1015 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001016 }
paul718e3742002-12-13 20:15:29 +00001017 if_data = ifp->info;
1018 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1019
1020 return CMD_SUCCESS;
1021}
1022
paul2e3b2e42002-12-13 21:03:13 +00001023DEFUN (linkdetect,
1024 linkdetect_cmd,
1025 "link-detect",
1026 "Enable link detection on interface\n")
1027{
paul2e3b2e42002-12-13 21:03:13 +00001028 struct interface *ifp;
1029 int if_was_operative;
1030
1031 ifp = (struct interface *) vty->index;
1032 if_was_operative = if_is_operative(ifp);
1033 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1034
1035 /* When linkdetection is enabled, if might come down */
1036 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1037
1038 /* FIXME: Will defer status change forwarding if interface
1039 does not come down! */
1040
1041 return CMD_SUCCESS;
1042}
1043
1044
1045DEFUN (no_linkdetect,
1046 no_linkdetect_cmd,
1047 "no link-detect",
1048 NO_STR
1049 "Disable link detection on interface\n")
1050{
paul2e3b2e42002-12-13 21:03:13 +00001051 struct interface *ifp;
1052 int if_was_operative;
1053
1054 ifp = (struct interface *) vty->index;
1055 if_was_operative = if_is_operative(ifp);
1056 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1057
1058 /* Interface may come up after disabling link detection */
1059 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1060
1061 /* FIXME: see linkdetect_cmd */
1062
1063 return CMD_SUCCESS;
1064}
1065
paul718e3742002-12-13 20:15:29 +00001066DEFUN (shutdown_if,
1067 shutdown_if_cmd,
1068 "shutdown",
1069 "Shutdown the selected interface\n")
1070{
1071 int ret;
1072 struct interface *ifp;
1073 struct zebra_if *if_data;
1074
1075 ifp = (struct interface *) vty->index;
1076 ret = if_unset_flags (ifp, IFF_UP);
1077 if (ret < 0)
1078 {
1079 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1080 return CMD_WARNING;
1081 }
1082 if_refresh (ifp);
1083 if_data = ifp->info;
1084 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1085
1086 return CMD_SUCCESS;
1087}
1088
1089DEFUN (no_shutdown_if,
1090 no_shutdown_if_cmd,
1091 "no shutdown",
1092 NO_STR
1093 "Shutdown the selected interface\n")
1094{
1095 int ret;
1096 struct interface *ifp;
1097 struct zebra_if *if_data;
1098
1099 ifp = (struct interface *) vty->index;
1100 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1101 if (ret < 0)
1102 {
1103 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1104 return CMD_WARNING;
1105 }
1106 if_refresh (ifp);
1107 if_data = ifp->info;
1108 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1109
1110 return CMD_SUCCESS;
1111}
1112
1113DEFUN (bandwidth_if,
1114 bandwidth_if_cmd,
1115 "bandwidth <1-10000000>",
1116 "Set bandwidth informational parameter\n"
1117 "Bandwidth in kilobits\n")
1118{
1119 struct interface *ifp;
1120 unsigned int bandwidth;
1121
1122 ifp = (struct interface *) vty->index;
1123 bandwidth = strtol(argv[0], NULL, 10);
1124
1125 /* bandwidth range is <1-10000000> */
1126 if (bandwidth < 1 || bandwidth > 10000000)
1127 {
1128 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1129 return CMD_WARNING;
1130 }
1131
1132 ifp->bandwidth = bandwidth;
1133
1134 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001135 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001136 zebra_interface_up_update (ifp);
1137
1138 return CMD_SUCCESS;
1139}
1140
1141DEFUN (no_bandwidth_if,
1142 no_bandwidth_if_cmd,
1143 "no bandwidth",
1144 NO_STR
1145 "Set bandwidth informational parameter\n")
1146{
1147 struct interface *ifp;
1148
1149 ifp = (struct interface *) vty->index;
1150
1151 ifp->bandwidth = 0;
1152
1153 /* force protocols to recalculate routes due to cost change */
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
1160ALIAS (no_bandwidth_if,
1161 no_bandwidth_if_val_cmd,
1162 "no bandwidth <1-10000000>",
1163 NO_STR
1164 "Set bandwidth informational parameter\n"
1165 "Bandwidth in kilobits\n")
1166
paula1ac18c2005-06-28 17:17:12 +00001167static int
hasso39db97e2004-10-12 20:50:58 +00001168ip_address_install (struct vty *vty, struct interface *ifp,
1169 const char *addr_str, const char *peer_str,
1170 const char *label)
paul718e3742002-12-13 20:15:29 +00001171{
1172 struct prefix_ipv4 cp;
1173 struct connected *ifc;
1174 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001175 int ret;
1176
1177 ret = str2prefix_ipv4 (addr_str, &cp);
1178 if (ret <= 0)
1179 {
1180 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1181 return CMD_WARNING;
1182 }
1183
paulca162182005-09-12 16:58:52 +00001184 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001185 if (! ifc)
1186 {
1187 ifc = connected_new ();
1188 ifc->ifp = ifp;
1189
1190 /* Address. */
1191 p = prefix_ipv4_new ();
1192 *p = cp;
1193 ifc->address = (struct prefix *) p;
1194
1195 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001196 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001197 {
1198 p = prefix_ipv4_new ();
1199 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001200 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001201 ifc->destination = (struct prefix *) p;
1202 }
1203
paul718e3742002-12-13 20:15:29 +00001204 /* Label. */
1205 if (label)
paul0752ef02005-11-03 12:35:21 +00001206 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001207
1208 /* Add to linked list. */
1209 listnode_add (ifp->connected, ifc);
1210 }
1211
1212 /* This address is configured from zebra. */
1213 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1214 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1215
1216 /* In case of this route need to install kernel. */
1217 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1218 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1219 {
1220 /* Some system need to up the interface to set IP address. */
1221 if (! if_is_up (ifp))
1222 {
1223 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1224 if_refresh (ifp);
1225 }
1226
1227 ret = if_set_prefix (ifp, ifc);
1228 if (ret < 0)
1229 {
1230 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001231 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001232 return CMD_WARNING;
1233 }
1234
hassoeef1fe12004-10-03 18:46:08 +00001235 /* Add to subnet chain list (while marking secondary attribute). */
1236 if_subnet_add (ifp, ifc);
1237
paul718e3742002-12-13 20:15:29 +00001238 /* IP address propery set. */
1239 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1240
1241 /* Update interface address information to protocol daemon. */
1242 zebra_interface_address_add_update (ifp, ifc);
1243
1244 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001245 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001246 connected_up_ipv4 (ifp, ifc);
1247 }
1248
1249 return CMD_SUCCESS;
1250}
1251
paula1ac18c2005-06-28 17:17:12 +00001252static int
hasso39db97e2004-10-12 20:50:58 +00001253ip_address_uninstall (struct vty *vty, struct interface *ifp,
1254 const char *addr_str, const char *peer_str,
1255 const char *label)
paul718e3742002-12-13 20:15:29 +00001256{
1257 struct prefix_ipv4 cp;
1258 struct connected *ifc;
1259 int ret;
1260
1261 /* Convert to prefix structure. */
1262 ret = str2prefix_ipv4 (addr_str, &cp);
1263 if (ret <= 0)
1264 {
1265 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1266 return CMD_WARNING;
1267 }
1268
1269 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001270 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001271 if (! ifc)
1272 {
1273 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1274 return CMD_WARNING;
1275 }
1276
1277 /* This is not configured address. */
1278 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1279 return CMD_WARNING;
1280
Paul Jakma74ecdc92006-06-15 18:10:47 +00001281 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1282
paul718e3742002-12-13 20:15:29 +00001283 /* This is not real address or interface is not active. */
1284 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1285 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1286 {
1287 listnode_delete (ifp->connected, ifc);
1288 connected_free (ifc);
1289 return CMD_WARNING;
1290 }
1291
1292 /* This is real route. */
1293 ret = if_unset_prefix (ifp, ifc);
1294 if (ret < 0)
1295 {
1296 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001297 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001298 return CMD_WARNING;
1299 }
1300
hassoeef1fe12004-10-03 18:46:08 +00001301#if 0
paul718e3742002-12-13 20:15:29 +00001302 /* Redistribute this information. */
1303 zebra_interface_address_delete_update (ifp, ifc);
1304
1305 /* Remove connected route. */
1306 connected_down_ipv4 (ifp, ifc);
1307
1308 /* Free address information. */
1309 listnode_delete (ifp->connected, ifc);
1310 connected_free (ifc);
hassoeef1fe12004-10-03 18:46:08 +00001311#endif
paul718e3742002-12-13 20:15:29 +00001312
1313 return CMD_SUCCESS;
1314}
1315
1316DEFUN (ip_address,
1317 ip_address_cmd,
1318 "ip address A.B.C.D/M",
1319 "Interface Internet Protocol config commands\n"
1320 "Set the IP address of an interface\n"
1321 "IP address (e.g. 10.0.0.1/8)\n")
1322{
hassoeef1fe12004-10-03 18:46:08 +00001323 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001324}
1325
1326DEFUN (no_ip_address,
1327 no_ip_address_cmd,
1328 "no ip address A.B.C.D/M",
1329 NO_STR
1330 "Interface Internet Protocol config commands\n"
1331 "Set the IP address of an interface\n"
1332 "IP Address (e.g. 10.0.0.1/8)")
1333{
hassoeef1fe12004-10-03 18:46:08 +00001334 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001335}
1336
1337#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001338DEFUN (ip_address_label,
1339 ip_address_label_cmd,
1340 "ip address A.B.C.D/M label LINE",
1341 "Interface Internet Protocol config commands\n"
1342 "Set the IP address of an interface\n"
1343 "IP address (e.g. 10.0.0.1/8)\n"
1344 "Label of this address\n"
1345 "Label\n")
1346{
hassoeef1fe12004-10-03 18:46:08 +00001347 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001348}
1349
1350DEFUN (no_ip_address_label,
1351 no_ip_address_label_cmd,
1352 "no ip address A.B.C.D/M label LINE",
1353 NO_STR
1354 "Interface Internet Protocol config commands\n"
1355 "Set the IP address of an interface\n"
1356 "IP address (e.g. 10.0.0.1/8)\n"
1357 "Label of this address\n"
1358 "Label\n")
1359{
hassoeef1fe12004-10-03 18:46:08 +00001360 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001361}
1362#endif /* HAVE_NETLINK */
1363
1364#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001365static int
hasso39db97e2004-10-12 20:50:58 +00001366ipv6_address_install (struct vty *vty, struct interface *ifp,
1367 const char *addr_str, const char *peer_str,
1368 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001369{
1370 struct prefix_ipv6 cp;
1371 struct connected *ifc;
1372 struct prefix_ipv6 *p;
1373 int ret;
1374
1375 ret = str2prefix_ipv6 (addr_str, &cp);
1376 if (ret <= 0)
1377 {
1378 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1379 return CMD_WARNING;
1380 }
1381
paulca162182005-09-12 16:58:52 +00001382 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001383 if (! ifc)
1384 {
1385 ifc = connected_new ();
1386 ifc->ifp = ifp;
1387
1388 /* Address. */
1389 p = prefix_ipv6_new ();
1390 *p = cp;
1391 ifc->address = (struct prefix *) p;
1392
1393 /* Secondary. */
1394 if (secondary)
1395 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1396
1397 /* Label. */
1398 if (label)
paul0752ef02005-11-03 12:35:21 +00001399 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001400
1401 /* Add to linked list. */
1402 listnode_add (ifp->connected, ifc);
1403 }
1404
1405 /* This address is configured from zebra. */
1406 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1407 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1408
1409 /* In case of this route need to install kernel. */
1410 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1411 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1412 {
1413 /* Some system need to up the interface to set IP address. */
1414 if (! if_is_up (ifp))
1415 {
1416 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1417 if_refresh (ifp);
1418 }
1419
1420 ret = if_prefix_add_ipv6 (ifp, ifc);
1421
1422 if (ret < 0)
1423 {
1424 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001425 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001426 return CMD_WARNING;
1427 }
1428
1429 /* IP address propery set. */
1430 SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
1431
1432 /* Update interface address information to protocol daemon. */
1433 zebra_interface_address_add_update (ifp, ifc);
1434
1435 /* If interface is up register connected route. */
paul2e3b2e42002-12-13 21:03:13 +00001436 if (if_is_operative(ifp))
paul718e3742002-12-13 20:15:29 +00001437 connected_up_ipv6 (ifp, ifc);
1438 }
1439
1440 return CMD_SUCCESS;
1441}
1442
paula1ac18c2005-06-28 17:17:12 +00001443static int
hasso39db97e2004-10-12 20:50:58 +00001444ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1445 const char *addr_str, const char *peer_str,
1446 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001447{
1448 struct prefix_ipv6 cp;
1449 struct connected *ifc;
1450 int ret;
1451
1452 /* Convert to prefix structure. */
1453 ret = str2prefix_ipv6 (addr_str, &cp);
1454 if (ret <= 0)
1455 {
1456 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1457 return CMD_WARNING;
1458 }
1459
1460 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001461 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001462 if (! ifc)
1463 {
1464 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1465 return CMD_WARNING;
1466 }
1467
1468 /* This is not configured address. */
1469 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1470 return CMD_WARNING;
1471
1472 /* This is not real address or interface is not active. */
1473 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)
1474 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1475 {
1476 listnode_delete (ifp->connected, ifc);
1477 connected_free (ifc);
1478 return CMD_WARNING;
1479 }
1480
1481 /* This is real route. */
1482 ret = if_prefix_delete_ipv6 (ifp, ifc);
1483 if (ret < 0)
1484 {
1485 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001486 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001487 return CMD_WARNING;
1488 }
1489
1490 /* Redistribute this information. */
1491 zebra_interface_address_delete_update (ifp, ifc);
1492
1493 /* Remove connected route. */
1494 connected_down_ipv6 (ifp, ifc);
1495
1496 /* Free address information. */
1497 listnode_delete (ifp->connected, ifc);
1498 connected_free (ifc);
1499
1500 return CMD_SUCCESS;
1501}
1502
1503DEFUN (ipv6_address,
1504 ipv6_address_cmd,
1505 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001506 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001507 "Set the IP address of an interface\n"
1508 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1509{
1510 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1511}
1512
1513DEFUN (no_ipv6_address,
1514 no_ipv6_address_cmd,
1515 "no ipv6 address X:X::X:X/M",
1516 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001517 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001518 "Set the IP address of an interface\n"
1519 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1520{
1521 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1522}
1523#endif /* HAVE_IPV6 */
1524
paula1ac18c2005-06-28 17:17:12 +00001525static int
paul718e3742002-12-13 20:15:29 +00001526if_config_write (struct vty *vty)
1527{
hasso52dc7ee2004-09-23 19:18:23 +00001528 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001529 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001530
paul1eb8ef22005-04-07 07:30:20 +00001531 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001532 {
1533 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001534 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001535 struct connected *ifc;
1536 struct prefix *p;
1537
paul718e3742002-12-13 20:15:29 +00001538 if_data = ifp->info;
1539
1540 vty_out (vty, "interface %s%s", ifp->name,
1541 VTY_NEWLINE);
1542
1543 if (ifp->desc)
1544 vty_out (vty, " description %s%s", ifp->desc,
1545 VTY_NEWLINE);
1546
1547 /* Assign bandwidth here to avoid unnecessary interface flap
1548 while processing config script */
1549 if (ifp->bandwidth != 0)
1550 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1551
paul2e3b2e42002-12-13 21:03:13 +00001552 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1553 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1554
paul1eb8ef22005-04-07 07:30:20 +00001555 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001556 {
paul718e3742002-12-13 20:15:29 +00001557 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1558 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001559 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001560 p = ifc->address;
1561 vty_out (vty, " ip%s address %s/%d",
1562 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001563 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001564 p->prefixlen);
1565
paul718e3742002-12-13 20:15:29 +00001566 if (ifc->label)
1567 vty_out (vty, " label %s", ifc->label);
1568
1569 vty_out (vty, "%s", VTY_NEWLINE);
1570 }
1571 }
1572
1573 if (if_data)
1574 {
1575 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1576 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1577
1578 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1579 vty_out (vty, " %smulticast%s",
1580 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1581 VTY_NEWLINE);
1582 }
1583
1584#ifdef RTADV
1585 rtadv_config_write (vty, ifp);
1586#endif /* RTADV */
1587
hassoca776982004-06-12 14:33:05 +00001588#ifdef HAVE_IRDP
1589 irdp_config_write (vty, ifp);
1590#endif /* IRDP */
1591
paul718e3742002-12-13 20:15:29 +00001592 vty_out (vty, "!%s", VTY_NEWLINE);
1593 }
1594 return 0;
1595}
1596
1597/* Allocate and initialize interface vector. */
1598void
paula1ac18c2005-06-28 17:17:12 +00001599zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001600{
1601 /* Initialize interface and new hook. */
1602 if_init ();
1603 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1604 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1605
1606 /* Install configuration write function. */
1607 install_node (&interface_node, if_config_write);
1608
1609 install_element (VIEW_NODE, &show_interface_cmd);
1610 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001611 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001612 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001613 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001614 install_default (INTERFACE_NODE);
1615 install_element (INTERFACE_NODE, &interface_desc_cmd);
1616 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1617 install_element (INTERFACE_NODE, &multicast_cmd);
1618 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001619 install_element (INTERFACE_NODE, &linkdetect_cmd);
1620 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001621 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1622 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1623 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1624 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1625 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1626 install_element (INTERFACE_NODE, &ip_address_cmd);
1627 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1628#ifdef HAVE_IPV6
1629 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1630 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1631#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001632#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001633 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001634 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001635#endif /* HAVE_NETLINK */
1636}