blob: 7e1d3dd868317fe41d3ae0573cc45dd460466109 [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;
Christian Frankebfac8dc2013-01-24 14:04:50 +000059 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
paul718e3742002-12-13 20:15:29 +000060
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
Christian Frankebfac8dc2013-01-24 14:04:50 +0000381 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
382 {
383 if (IS_ZEBRA_DEBUG_KERNEL)
384 zlog_debug ("interface %s index %d is shutdown. Won't wake it up.",
385 ifp->name, ifp->ifindex);
386 return;
387 }
388
paul718e3742002-12-13 20:15:29 +0000389 if_addr_wakeup (ifp);
390
391 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000392 zlog_debug ("interface %s index %d becomes active.",
393 ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000394 }
395 else
396 {
397 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000398 zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000399 }
400}
401
paul6eb88272005-07-29 14:36:00 +0000402/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000403void
404if_delete_update (struct interface *ifp)
405{
paul718e3742002-12-13 20:15:29 +0000406 struct connected *ifc;
407 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000408 struct route_node *rn;
409 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000410
411 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000412
413 if (if_is_up(ifp))
414 {
415 zlog_err ("interface %s index %d is still up while being deleted.",
416 ifp->name, ifp->ifindex);
417 return;
418 }
419
420 /* Mark interface as inactive */
421 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
422
423 if (IS_ZEBRA_DEBUG_KERNEL)
ajsb6178002004-12-07 21:12:56 +0000424 zlog_debug ("interface %s index %d is now inactive.",
paul718e3742002-12-13 20:15:29 +0000425 ifp->name, ifp->ifindex);
426
427 /* Delete connected routes from the kernel. */
428 if (ifp->connected)
429 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000430 struct listnode *node;
431 struct listnode *last = NULL;
432
hassoeef1fe12004-10-03 18:46:08 +0000433 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000434 {
paul1eb8ef22005-04-07 07:30:20 +0000435 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000436 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000437
Paul Jakmabeb56332006-05-11 13:28:05 +0000438 if (p->family == AF_INET
439 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000440 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000441 struct listnode *anode;
442 struct listnode *next;
443 struct listnode *first;
444 struct list *addr_list;
445
hassoeef1fe12004-10-03 18:46:08 +0000446 route_unlock_node (rn);
447 addr_list = (struct list *) rn->info;
448
449 /* Remove addresses, secondaries first. */
450 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000451 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000452 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000453 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000454 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000455 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000456 first = NULL;
457 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000458 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000459
Paul Jakmad9a18f12007-04-10 19:30:20 +0000460 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000461 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000462 connected_down_ipv4 (ifp, ifc);
463
Christian Franke02b48052013-01-24 14:04:49 +0000464 /* XXX: We have to send notifications here explicitly, because we destroy
465 * the ifc before receiving the notification about the address being deleted.
466 */
hassoeef1fe12004-10-03 18:46:08 +0000467 zebra_interface_address_delete_update (ifp, ifc);
468
469 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000470 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000471
472 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000473 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000474 route_unlock_node (rn);
475
476 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000477 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
478 {
479 listnode_delete (ifp->connected, ifc);
480 connected_free (ifc);
481 }
482 else
483 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000484 }
485
486 /* Free chain list and respective route node. */
487 list_delete (addr_list);
488 rn->info = NULL;
489 route_unlock_node (rn);
490 }
paul718e3742002-12-13 20:15:29 +0000491#ifdef HAVE_IPV6
492 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000493 {
494 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000495
hassoeef1fe12004-10-03 18:46:08 +0000496 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000497
hassoeef1fe12004-10-03 18:46:08 +0000498 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000499 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000500
501 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
502 last = node;
503 else
504 {
505 listnode_delete (ifp->connected, ifc);
506 connected_free (ifc);
507 }
paul718e3742002-12-13 20:15:29 +0000508 }
hassoeef1fe12004-10-03 18:46:08 +0000509#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200510 else
511 {
512 last = node;
513 }
paul718e3742002-12-13 20:15:29 +0000514 }
515 }
516 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000517
518 /* Update ifindex after distributing the delete message. This is in
519 case any client needs to have the old value of ifindex available
520 while processing the deletion. Each client daemon is responsible
521 for setting ifindex to IFINDEX_INTERNAL after processing the
522 interface deletion message. */
523 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000524}
525
526/* Interface is up. */
527void
528if_up (struct interface *ifp)
529{
hasso52dc7ee2004-09-23 19:18:23 +0000530 struct listnode *node;
531 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000532 struct connected *ifc;
533 struct prefix *p;
534
535 /* Notify the protocol daemons. */
536 zebra_interface_up_update (ifp);
537
538 /* Install connected routes to the kernel. */
539 if (ifp->connected)
540 {
paul1eb8ef22005-04-07 07:30:20 +0000541 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000542 {
paul718e3742002-12-13 20:15:29 +0000543 p = ifc->address;
544
545 if (p->family == AF_INET)
546 connected_up_ipv4 (ifp, ifc);
547#ifdef HAVE_IPV6
548 else if (p->family == AF_INET6)
549 connected_up_ipv6 (ifp, ifc);
550#endif /* HAVE_IPV6 */
551 }
552 }
553
554 /* Examine all static routes. */
555 rib_update ();
556}
557
558/* Interface goes down. We have to manage different behavior of based
559 OS. */
560void
561if_down (struct interface *ifp)
562{
hasso52dc7ee2004-09-23 19:18:23 +0000563 struct listnode *node;
564 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000565 struct connected *ifc;
566 struct prefix *p;
567
568 /* Notify to the protocol daemons. */
569 zebra_interface_down_update (ifp);
570
571 /* Delete connected routes from the kernel. */
572 if (ifp->connected)
573 {
paul1eb8ef22005-04-07 07:30:20 +0000574 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000575 {
paul718e3742002-12-13 20:15:29 +0000576 p = ifc->address;
577
578 if (p->family == AF_INET)
579 connected_down_ipv4 (ifp, ifc);
580#ifdef HAVE_IPV6
581 else if (p->family == AF_INET6)
582 connected_down_ipv6 (ifp, ifc);
583#endif /* HAVE_IPV6 */
584 }
585 }
586
587 /* Examine all static routes which direct to the interface. */
588 rib_update ();
589}
590
591void
592if_refresh (struct interface *ifp)
593{
paul5c78b3d2006-01-25 04:31:40 +0000594 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000595}
596
paul718e3742002-12-13 20:15:29 +0000597/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000598static int
paul718e3742002-12-13 20:15:29 +0000599prefix_vty_out (struct vty *vty, struct prefix *p)
600{
601 char str[INET6_ADDRSTRLEN];
602
603 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
604 vty_out (vty, "%s", str);
605 return strlen (str);
606}
607
608/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000609static void
paul718e3742002-12-13 20:15:29 +0000610connected_dump_vty (struct vty *vty, struct connected *connected)
611{
612 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000613
614 /* Print interface address. */
615 p = connected->address;
616 vty_out (vty, " %s ", prefix_family_str (p));
617 prefix_vty_out (vty, p);
618 vty_out (vty, "/%d", p->prefixlen);
619
620 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000621 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000622 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000623 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
624 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000625 }
626
627 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
628 vty_out (vty, " secondary");
629
630 if (connected->label)
631 vty_out (vty, " %s", connected->label);
632
633 vty_out (vty, "%s", VTY_NEWLINE);
634}
635
636#ifdef RTADV
637/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000638static void
paul718e3742002-12-13 20:15:29 +0000639nd_dump_vty (struct vty *vty, struct interface *ifp)
640{
641 struct zebra_if *zif;
642 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000643 int interval;
paul718e3742002-12-13 20:15:29 +0000644
645 zif = (struct zebra_if *) ifp->info;
646 rtadv = &zif->rtadv;
647
648 if (rtadv->AdvSendAdvertisements)
649 {
650 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
651 rtadv->AdvReachableTime, VTY_NEWLINE);
652 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
653 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000654 interval = rtadv->MaxRtrAdvInterval;
655 if (interval % 1000)
656 vty_out (vty, " ND router advertisements are sent every "
657 "%d milliseconds%s", interval,
658 VTY_NEWLINE);
659 else
660 vty_out (vty, " ND router advertisements are sent every "
661 "%d seconds%s", interval / 1000,
662 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400663 if (rtadv->AdvDefaultLifetime != -1)
664 vty_out (vty, " ND router advertisements live for %d seconds%s",
665 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
666 else
667 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
668 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000669 vty_out (vty, " ND router advertisement default router preference is "
670 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
671 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000672 if (rtadv->AdvManagedFlag)
673 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
674 VTY_NEWLINE);
675 else
676 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
677 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000678 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400679 {
vincent7cee1bb2005-03-25 13:08:53 +0000680 vty_out (vty, " ND router advertisements with "
681 "Home Agent flag bit set.%s",
682 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400683 if (rtadv->HomeAgentLifetime != -1)
684 vty_out (vty, " Home Agent lifetime is %u seconds%s",
685 rtadv->HomeAgentLifetime, VTY_NEWLINE);
686 else
687 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
688 VTY_NEWLINE);
689 vty_out (vty, " Home Agent preference is %u%s",
690 rtadv->HomeAgentPreference, VTY_NEWLINE);
691 }
vincent7cee1bb2005-03-25 13:08:53 +0000692 if (rtadv->AdvIntervalOption)
693 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
694 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000695 }
696}
697#endif /* RTADV */
698
699/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000700static void
paul718e3742002-12-13 20:15:29 +0000701if_dump_vty (struct vty *vty, struct interface *ifp)
702{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000703#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000704 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000705#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000706 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000707 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000708 struct route_node *rn;
709 struct zebra_if *zebra_if;
710
711 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000712
paul2e3b2e42002-12-13 21:03:13 +0000713 vty_out (vty, "Interface %s is ", ifp->name);
714 if (if_is_up(ifp)) {
715 vty_out (vty, "up, line protocol ");
716
717 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
718 if (if_is_running(ifp))
719 vty_out (vty, "is up%s", VTY_NEWLINE);
720 else
721 vty_out (vty, "is down%s", VTY_NEWLINE);
722 } else {
723 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
724 }
725 } else {
726 vty_out (vty, "down%s", VTY_NEWLINE);
727 }
728
paul718e3742002-12-13 20:15:29 +0000729 if (ifp->desc)
730 vty_out (vty, " Description: %s%s", ifp->desc,
731 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000732 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000733 {
ajsd2fc8892005-04-02 18:38:43 +0000734 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000735 return;
736 }
737 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
738 {
739 vty_out(vty, " index %d inactive interface%s",
740 ifp->ifindex,
741 VTY_NEWLINE);
742 return;
743 }
744
745 vty_out (vty, " index %d metric %d mtu %d ",
746 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000747#ifdef HAVE_IPV6
748 if (ifp->mtu6 != ifp->mtu)
749 vty_out (vty, "mtu6 %d ", ifp->mtu6);
750#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000751 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
752 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000753
paul718e3742002-12-13 20:15:29 +0000754 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000755#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000756 sdl = &ifp->sdl;
757 if (sdl != NULL && sdl->sdl_alen != 0)
758 {
759 int i;
760 u_char *ptr;
761
762 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000763 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
764 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000765 vty_out (vty, "%s", VTY_NEWLINE);
766 }
767#else
768 if (ifp->hw_addr_len != 0)
769 {
770 int i;
771
772 vty_out (vty, " HWaddr: ");
773 for (i = 0; i < ifp->hw_addr_len; i++)
774 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
775 vty_out (vty, "%s", VTY_NEWLINE);
776 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000777#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000778
779 /* Bandwidth in kbps */
780 if (ifp->bandwidth != 0)
781 {
782 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
783 vty_out(vty, "%s", VTY_NEWLINE);
784 }
785
hassoeef1fe12004-10-03 18:46:08 +0000786 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000787 {
hassoeef1fe12004-10-03 18:46:08 +0000788 if (! rn->info)
789 continue;
790
paul1eb8ef22005-04-07 07:30:20 +0000791 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
792 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000793 }
794
paul1eb8ef22005-04-07 07:30:20 +0000795 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000796 {
hasso39db97e2004-10-12 20:50:58 +0000797 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
798 (connected->address->family == AF_INET6))
799 connected_dump_vty (vty, connected);
800 }
801
paul718e3742002-12-13 20:15:29 +0000802#ifdef RTADV
803 nd_dump_vty (vty, ifp);
804#endif /* RTADV */
805
806#ifdef HAVE_PROC_NET_DEV
807 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000808 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
809 "%lu dropped%s",
810 ifp->stats.rx_packets, ifp->stats.rx_multicast,
811 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000812
hasso6f2c27a2005-01-18 13:44:35 +0000813 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000814 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000815 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
816 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000817 ifp->stats.rx_frame_errors, VTY_NEWLINE);
818
819 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000820 ifp->stats.rx_missed_errors, VTY_NEWLINE);
821
hasso6f2c27a2005-01-18 13:44:35 +0000822 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000823 ifp->stats.tx_packets, ifp->stats.tx_bytes,
824 ifp->stats.tx_dropped, VTY_NEWLINE);
825
hasso6f2c27a2005-01-18 13:44:35 +0000826 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
827 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000828 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
829 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000830 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000831
hasso6f2c27a2005-01-18 13:44:35 +0000832 vty_out (vty, " %lu window, %lu collisions%s",
833 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000834#endif /* HAVE_PROC_NET_DEV */
835
836#ifdef HAVE_NET_RT_IFLIST
837#if defined (__bsdi__) || defined (__NetBSD__)
838 /* Statistics print out using sysctl (). */
839 vty_out (vty, " input packets %qu, bytes %qu, dropped %qu,"
840 " multicast packets %qu%s",
841 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
842 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
843 VTY_NEWLINE);
844
845 vty_out (vty, " input errors %qu%s",
846 ifp->stats.ifi_ierrors, VTY_NEWLINE);
847
848 vty_out (vty, " output packets %qu, bytes %qu, multicast packets %qu%s",
849 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
850 ifp->stats.ifi_omcasts, VTY_NEWLINE);
851
852 vty_out (vty, " output errors %qu%s",
853 ifp->stats.ifi_oerrors, VTY_NEWLINE);
854
855 vty_out (vty, " collisions %qu%s",
856 ifp->stats.ifi_collisions, VTY_NEWLINE);
857#else
858 /* Statistics print out using sysctl (). */
859 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
860 " multicast packets %lu%s",
861 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
862 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
863 VTY_NEWLINE);
864
865 vty_out (vty, " input errors %lu%s",
866 ifp->stats.ifi_ierrors, VTY_NEWLINE);
867
868 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
869 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
870 ifp->stats.ifi_omcasts, VTY_NEWLINE);
871
872 vty_out (vty, " output errors %lu%s",
873 ifp->stats.ifi_oerrors, VTY_NEWLINE);
874
875 vty_out (vty, " collisions %lu%s",
876 ifp->stats.ifi_collisions, VTY_NEWLINE);
877#endif /* __bsdi__ || __NetBSD__ */
878#endif /* HAVE_NET_RT_IFLIST */
879}
880
paul718e3742002-12-13 20:15:29 +0000881/* Wrapper hook point for zebra daemon so that ifindex can be set
882 * DEFUN macro not used as extract.pl HAS to ignore this
883 * See also interface_cmd in lib/if.c
884 */
885DEFUN_NOSH (zebra_interface,
886 zebra_interface_cmd,
887 "interface IFNAME",
888 "Select an interface to configure\n"
889 "Interface's name\n")
890{
891 int ret;
892 struct interface * ifp;
893
894 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000895 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
896 return ret;
paul718e3742002-12-13 20:15:29 +0000897
898 ifp = vty->index;
899
ajsd2fc8892005-04-02 18:38:43 +0000900 if (ifp->ifindex == IFINDEX_INTERNAL)
901 /* Is this really necessary? Shouldn't status be initialized to 0
902 in that case? */
903 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000904
905 return ret;
906}
907
paul718e3742002-12-13 20:15:29 +0000908struct cmd_node interface_node =
909{
910 INTERFACE_NODE,
911 "%s(config-if)# ",
912 1
913};
914
915/* Show all or specified interface to vty. */
916DEFUN (show_interface, show_interface_cmd,
917 "show interface [IFNAME]",
918 SHOW_STR
919 "Interface status and configuration\n"
920 "Inteface name\n")
921{
hasso52dc7ee2004-09-23 19:18:23 +0000922 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000923 struct interface *ifp;
924
925#ifdef HAVE_PROC_NET_DEV
926 /* If system has interface statistics via proc file system, update
927 statistics. */
928 ifstat_update_proc ();
929#endif /* HAVE_PROC_NET_DEV */
930#ifdef HAVE_NET_RT_IFLIST
931 ifstat_update_sysctl ();
932#endif /* HAVE_NET_RT_IFLIST */
933
934 /* Specified interface print. */
935 if (argc != 0)
936 {
937 ifp = if_lookup_by_name (argv[0]);
938 if (ifp == NULL)
939 {
940 vty_out (vty, "%% Can't find interface %s%s", argv[0],
941 VTY_NEWLINE);
942 return CMD_WARNING;
943 }
944 if_dump_vty (vty, ifp);
945 return CMD_SUCCESS;
946 }
947
948 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000949 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
950 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000951
952 return CMD_SUCCESS;
953}
954
hassoed9bb6d2005-03-13 19:17:21 +0000955DEFUN (show_interface_desc,
956 show_interface_desc_cmd,
957 "show interface description",
958 SHOW_STR
959 "Interface status and configuration\n"
960 "Interface description\n")
961{
962 struct listnode *node;
963 struct interface *ifp;
964
965 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000966 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000967 {
968 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000969
970 len = vty_out (vty, "%s", ifp->name);
971 vty_out (vty, "%*s", (16 - len), " ");
972
973 if (if_is_up(ifp))
974 {
975 vty_out (vty, "up ");
976 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
977 {
978 if (if_is_running(ifp))
979 vty_out (vty, "up ");
980 else
981 vty_out (vty, "down ");
982 }
983 else
984 {
985 vty_out (vty, "unknown ");
986 }
987 }
988 else
989 {
990 vty_out (vty, "down down ");
991 }
992
993 if (ifp->desc)
994 vty_out (vty, "%s", ifp->desc);
995 vty_out (vty, "%s", VTY_NEWLINE);
996 }
997 return CMD_SUCCESS;
998}
999
paul718e3742002-12-13 20:15:29 +00001000DEFUN (multicast,
1001 multicast_cmd,
1002 "multicast",
1003 "Set multicast flag to interface\n")
1004{
1005 int ret;
1006 struct interface *ifp;
1007 struct zebra_if *if_data;
1008
1009 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001010 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001011 {
paul48b33aa2002-12-13 20:52:52 +00001012 ret = if_set_flags (ifp, IFF_MULTICAST);
1013 if (ret < 0)
1014 {
1015 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1016 return CMD_WARNING;
1017 }
1018 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001019 }
paul718e3742002-12-13 20:15:29 +00001020 if_data = ifp->info;
1021 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001022
paul718e3742002-12-13 20:15:29 +00001023 return CMD_SUCCESS;
1024}
1025
1026DEFUN (no_multicast,
1027 no_multicast_cmd,
1028 "no multicast",
1029 NO_STR
1030 "Unset multicast flag to interface\n")
1031{
1032 int ret;
1033 struct interface *ifp;
1034 struct zebra_if *if_data;
1035
1036 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001037 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001038 {
paul48b33aa2002-12-13 20:52:52 +00001039 ret = if_unset_flags (ifp, IFF_MULTICAST);
1040 if (ret < 0)
1041 {
1042 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1043 return CMD_WARNING;
1044 }
1045 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001046 }
paul718e3742002-12-13 20:15:29 +00001047 if_data = ifp->info;
1048 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1049
1050 return CMD_SUCCESS;
1051}
1052
paul2e3b2e42002-12-13 21:03:13 +00001053DEFUN (linkdetect,
1054 linkdetect_cmd,
1055 "link-detect",
1056 "Enable link detection on interface\n")
1057{
paul2e3b2e42002-12-13 21:03:13 +00001058 struct interface *ifp;
1059 int if_was_operative;
1060
1061 ifp = (struct interface *) vty->index;
1062 if_was_operative = if_is_operative(ifp);
1063 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1064
1065 /* When linkdetection is enabled, if might come down */
1066 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1067
1068 /* FIXME: Will defer status change forwarding if interface
1069 does not come down! */
1070
1071 return CMD_SUCCESS;
1072}
1073
1074
1075DEFUN (no_linkdetect,
1076 no_linkdetect_cmd,
1077 "no link-detect",
1078 NO_STR
1079 "Disable link detection on interface\n")
1080{
paul2e3b2e42002-12-13 21:03:13 +00001081 struct interface *ifp;
1082 int if_was_operative;
1083
1084 ifp = (struct interface *) vty->index;
1085 if_was_operative = if_is_operative(ifp);
1086 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1087
1088 /* Interface may come up after disabling link detection */
1089 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1090
1091 /* FIXME: see linkdetect_cmd */
1092
1093 return CMD_SUCCESS;
1094}
1095
paul718e3742002-12-13 20:15:29 +00001096DEFUN (shutdown_if,
1097 shutdown_if_cmd,
1098 "shutdown",
1099 "Shutdown the selected interface\n")
1100{
1101 int ret;
1102 struct interface *ifp;
1103 struct zebra_if *if_data;
1104
1105 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001106 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001107 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001108 ret = if_unset_flags (ifp, IFF_UP);
1109 if (ret < 0)
1110 {
1111 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1112 return CMD_WARNING;
1113 }
1114 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001115 }
paul718e3742002-12-13 20:15:29 +00001116 if_data = ifp->info;
1117 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1118
1119 return CMD_SUCCESS;
1120}
1121
1122DEFUN (no_shutdown_if,
1123 no_shutdown_if_cmd,
1124 "no shutdown",
1125 NO_STR
1126 "Shutdown the selected interface\n")
1127{
1128 int ret;
1129 struct interface *ifp;
1130 struct zebra_if *if_data;
1131
1132 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001133
1134 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001135 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001136 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1137 if (ret < 0)
1138 {
1139 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1140 return CMD_WARNING;
1141 }
1142 if_refresh (ifp);
1143
1144 /* Some addresses (in particular, IPv6 addresses on Linux) get
1145 * removed when the interface goes down. They need to be readded.
1146 */
1147 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001148 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001149
paul718e3742002-12-13 20:15:29 +00001150 if_data = ifp->info;
1151 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1152
1153 return CMD_SUCCESS;
1154}
1155
1156DEFUN (bandwidth_if,
1157 bandwidth_if_cmd,
1158 "bandwidth <1-10000000>",
1159 "Set bandwidth informational parameter\n"
1160 "Bandwidth in kilobits\n")
1161{
1162 struct interface *ifp;
1163 unsigned int bandwidth;
1164
1165 ifp = (struct interface *) vty->index;
1166 bandwidth = strtol(argv[0], NULL, 10);
1167
1168 /* bandwidth range is <1-10000000> */
1169 if (bandwidth < 1 || bandwidth > 10000000)
1170 {
1171 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1172 return CMD_WARNING;
1173 }
1174
1175 ifp->bandwidth = bandwidth;
1176
1177 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001178 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001179 zebra_interface_up_update (ifp);
1180
1181 return CMD_SUCCESS;
1182}
1183
1184DEFUN (no_bandwidth_if,
1185 no_bandwidth_if_cmd,
1186 "no bandwidth",
1187 NO_STR
1188 "Set bandwidth informational parameter\n")
1189{
1190 struct interface *ifp;
1191
1192 ifp = (struct interface *) vty->index;
1193
1194 ifp->bandwidth = 0;
1195
1196 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001197 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001198 zebra_interface_up_update (ifp);
1199
1200 return CMD_SUCCESS;
1201}
1202
1203ALIAS (no_bandwidth_if,
1204 no_bandwidth_if_val_cmd,
1205 "no bandwidth <1-10000000>",
1206 NO_STR
1207 "Set bandwidth informational parameter\n"
1208 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001209
paula1ac18c2005-06-28 17:17:12 +00001210static int
hasso39db97e2004-10-12 20:50:58 +00001211ip_address_install (struct vty *vty, struct interface *ifp,
1212 const char *addr_str, const char *peer_str,
1213 const char *label)
paul718e3742002-12-13 20:15:29 +00001214{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001215 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001216 struct prefix_ipv4 cp;
1217 struct connected *ifc;
1218 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001219 int ret;
1220
Christian Frankebfac8dc2013-01-24 14:04:50 +00001221 if_data = ifp->info;
1222
paul718e3742002-12-13 20:15:29 +00001223 ret = str2prefix_ipv4 (addr_str, &cp);
1224 if (ret <= 0)
1225 {
1226 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1227 return CMD_WARNING;
1228 }
1229
paulca162182005-09-12 16:58:52 +00001230 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001231 if (! ifc)
1232 {
1233 ifc = connected_new ();
1234 ifc->ifp = ifp;
1235
1236 /* Address. */
1237 p = prefix_ipv4_new ();
1238 *p = cp;
1239 ifc->address = (struct prefix *) p;
1240
1241 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001242 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001243 {
1244 p = prefix_ipv4_new ();
1245 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001246 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001247 ifc->destination = (struct prefix *) p;
1248 }
1249
paul718e3742002-12-13 20:15:29 +00001250 /* Label. */
1251 if (label)
paul0752ef02005-11-03 12:35:21 +00001252 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001253
1254 /* Add to linked list. */
1255 listnode_add (ifp->connected, ifc);
1256 }
1257
1258 /* This address is configured from zebra. */
1259 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1260 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1261
1262 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001263 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001264 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1265 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001266 {
1267 /* Some system need to up the interface to set IP address. */
1268 if (! if_is_up (ifp))
1269 {
1270 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1271 if_refresh (ifp);
1272 }
1273
1274 ret = if_set_prefix (ifp, ifc);
1275 if (ret < 0)
1276 {
1277 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001278 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001279 return CMD_WARNING;
1280 }
1281
Christian Frankef7f740f2013-01-24 14:04:48 +00001282 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001283 /* The address will be advertised to zebra clients when the notification
1284 * from the kernel has been received.
1285 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001286 }
1287
1288 return CMD_SUCCESS;
1289}
1290
paula1ac18c2005-06-28 17:17:12 +00001291static int
hasso39db97e2004-10-12 20:50:58 +00001292ip_address_uninstall (struct vty *vty, struct interface *ifp,
1293 const char *addr_str, const char *peer_str,
1294 const char *label)
paul718e3742002-12-13 20:15:29 +00001295{
1296 struct prefix_ipv4 cp;
1297 struct connected *ifc;
1298 int ret;
1299
1300 /* Convert to prefix structure. */
1301 ret = str2prefix_ipv4 (addr_str, &cp);
1302 if (ret <= 0)
1303 {
1304 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1305 return CMD_WARNING;
1306 }
1307
1308 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001309 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001310 if (! ifc)
1311 {
1312 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1313 return CMD_WARNING;
1314 }
1315
1316 /* This is not configured address. */
1317 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1318 return CMD_WARNING;
1319
Paul Jakma74ecdc92006-06-15 18:10:47 +00001320 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1321
paul718e3742002-12-13 20:15:29 +00001322 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001323 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001324 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1325 {
1326 listnode_delete (ifp->connected, ifc);
1327 connected_free (ifc);
1328 return CMD_WARNING;
1329 }
1330
1331 /* This is real route. */
1332 ret = if_unset_prefix (ifp, ifc);
1333 if (ret < 0)
1334 {
1335 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001336 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001337 return CMD_WARNING;
1338 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001339 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001340 /* we will receive a kernel notification about this route being removed.
1341 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001342 return CMD_SUCCESS;
1343}
1344
1345DEFUN (ip_address,
1346 ip_address_cmd,
1347 "ip address A.B.C.D/M",
1348 "Interface Internet Protocol config commands\n"
1349 "Set the IP address of an interface\n"
1350 "IP address (e.g. 10.0.0.1/8)\n")
1351{
hassoeef1fe12004-10-03 18:46:08 +00001352 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001353}
1354
1355DEFUN (no_ip_address,
1356 no_ip_address_cmd,
1357 "no ip address A.B.C.D/M",
1358 NO_STR
1359 "Interface Internet Protocol config commands\n"
1360 "Set the IP address of an interface\n"
1361 "IP Address (e.g. 10.0.0.1/8)")
1362{
hassoeef1fe12004-10-03 18:46:08 +00001363 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001364}
1365
1366#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001367DEFUN (ip_address_label,
1368 ip_address_label_cmd,
1369 "ip address A.B.C.D/M label LINE",
1370 "Interface Internet Protocol config commands\n"
1371 "Set the IP address of an interface\n"
1372 "IP address (e.g. 10.0.0.1/8)\n"
1373 "Label of this address\n"
1374 "Label\n")
1375{
hassoeef1fe12004-10-03 18:46:08 +00001376 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001377}
1378
1379DEFUN (no_ip_address_label,
1380 no_ip_address_label_cmd,
1381 "no ip address A.B.C.D/M label LINE",
1382 NO_STR
1383 "Interface Internet Protocol config commands\n"
1384 "Set the IP address of an interface\n"
1385 "IP address (e.g. 10.0.0.1/8)\n"
1386 "Label of this address\n"
1387 "Label\n")
1388{
hassoeef1fe12004-10-03 18:46:08 +00001389 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001390}
1391#endif /* HAVE_NETLINK */
1392
1393#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001394static int
hasso39db97e2004-10-12 20:50:58 +00001395ipv6_address_install (struct vty *vty, struct interface *ifp,
1396 const char *addr_str, const char *peer_str,
1397 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001398{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001399 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001400 struct prefix_ipv6 cp;
1401 struct connected *ifc;
1402 struct prefix_ipv6 *p;
1403 int ret;
1404
Christian Frankebfac8dc2013-01-24 14:04:50 +00001405 if_data = ifp->info;
1406
paul718e3742002-12-13 20:15:29 +00001407 ret = str2prefix_ipv6 (addr_str, &cp);
1408 if (ret <= 0)
1409 {
1410 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1411 return CMD_WARNING;
1412 }
1413
paulca162182005-09-12 16:58:52 +00001414 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001415 if (! ifc)
1416 {
1417 ifc = connected_new ();
1418 ifc->ifp = ifp;
1419
1420 /* Address. */
1421 p = prefix_ipv6_new ();
1422 *p = cp;
1423 ifc->address = (struct prefix *) p;
1424
1425 /* Secondary. */
1426 if (secondary)
1427 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1428
1429 /* Label. */
1430 if (label)
paul0752ef02005-11-03 12:35:21 +00001431 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001432
1433 /* Add to linked list. */
1434 listnode_add (ifp->connected, ifc);
1435 }
1436
1437 /* This address is configured from zebra. */
1438 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1439 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1440
1441 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001442 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001443 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1444 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001445 {
1446 /* Some system need to up the interface to set IP address. */
1447 if (! if_is_up (ifp))
1448 {
1449 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1450 if_refresh (ifp);
1451 }
1452
1453 ret = if_prefix_add_ipv6 (ifp, ifc);
1454
1455 if (ret < 0)
1456 {
1457 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001458 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001459 return CMD_WARNING;
1460 }
1461
Christian Frankef7f740f2013-01-24 14:04:48 +00001462 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001463 /* The address will be advertised to zebra clients when the notification
1464 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001465 }
1466
1467 return CMD_SUCCESS;
1468}
1469
paula1ac18c2005-06-28 17:17:12 +00001470static int
hasso39db97e2004-10-12 20:50:58 +00001471ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1472 const char *addr_str, const char *peer_str,
1473 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001474{
1475 struct prefix_ipv6 cp;
1476 struct connected *ifc;
1477 int ret;
1478
1479 /* Convert to prefix structure. */
1480 ret = str2prefix_ipv6 (addr_str, &cp);
1481 if (ret <= 0)
1482 {
1483 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1484 return CMD_WARNING;
1485 }
1486
1487 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001488 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001489 if (! ifc)
1490 {
1491 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1492 return CMD_WARNING;
1493 }
1494
1495 /* This is not configured address. */
1496 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1497 return CMD_WARNING;
1498
Christian Franke676e1a02013-01-24 14:04:45 +00001499 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1500
paul718e3742002-12-13 20:15:29 +00001501 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001502 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001503 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1504 {
1505 listnode_delete (ifp->connected, ifc);
1506 connected_free (ifc);
1507 return CMD_WARNING;
1508 }
1509
1510 /* This is real route. */
1511 ret = if_prefix_delete_ipv6 (ifp, ifc);
1512 if (ret < 0)
1513 {
1514 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001515 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001516 return CMD_WARNING;
1517 }
1518
Christian Frankef7f740f2013-01-24 14:04:48 +00001519 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001520 /* This information will be propagated to the zclients when the
1521 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001522 return CMD_SUCCESS;
1523}
1524
1525DEFUN (ipv6_address,
1526 ipv6_address_cmd,
1527 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001528 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001529 "Set the IP address of an interface\n"
1530 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1531{
1532 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1533}
1534
1535DEFUN (no_ipv6_address,
1536 no_ipv6_address_cmd,
1537 "no ipv6 address X:X::X:X/M",
1538 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001539 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001540 "Set the IP address of an interface\n"
1541 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1542{
1543 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1544}
1545#endif /* HAVE_IPV6 */
1546
paula1ac18c2005-06-28 17:17:12 +00001547static int
paul718e3742002-12-13 20:15:29 +00001548if_config_write (struct vty *vty)
1549{
hasso52dc7ee2004-09-23 19:18:23 +00001550 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001551 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001552
paul1eb8ef22005-04-07 07:30:20 +00001553 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001554 {
1555 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001556 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001557 struct connected *ifc;
1558 struct prefix *p;
1559
paul718e3742002-12-13 20:15:29 +00001560 if_data = ifp->info;
1561
1562 vty_out (vty, "interface %s%s", ifp->name,
1563 VTY_NEWLINE);
1564
Christian Frankebfac8dc2013-01-24 14:04:50 +00001565 if (if_data)
1566 {
1567 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1568 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1569 }
1570
paul718e3742002-12-13 20:15:29 +00001571 if (ifp->desc)
1572 vty_out (vty, " description %s%s", ifp->desc,
1573 VTY_NEWLINE);
1574
1575 /* Assign bandwidth here to avoid unnecessary interface flap
1576 while processing config script */
1577 if (ifp->bandwidth != 0)
1578 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1579
paul2e3b2e42002-12-13 21:03:13 +00001580 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1581 vty_out(vty, " link-detect%s", VTY_NEWLINE);
1582
paul1eb8ef22005-04-07 07:30:20 +00001583 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001584 {
paul718e3742002-12-13 20:15:29 +00001585 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1586 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001587 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001588 p = ifc->address;
1589 vty_out (vty, " ip%s address %s/%d",
1590 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001591 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001592 p->prefixlen);
1593
paul718e3742002-12-13 20:15:29 +00001594 if (ifc->label)
1595 vty_out (vty, " label %s", ifc->label);
1596
1597 vty_out (vty, "%s", VTY_NEWLINE);
1598 }
1599 }
1600
1601 if (if_data)
1602 {
paul718e3742002-12-13 20:15:29 +00001603 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1604 vty_out (vty, " %smulticast%s",
1605 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1606 VTY_NEWLINE);
1607 }
1608
1609#ifdef RTADV
1610 rtadv_config_write (vty, ifp);
1611#endif /* RTADV */
1612
hassoca776982004-06-12 14:33:05 +00001613#ifdef HAVE_IRDP
1614 irdp_config_write (vty, ifp);
1615#endif /* IRDP */
1616
paul718e3742002-12-13 20:15:29 +00001617 vty_out (vty, "!%s", VTY_NEWLINE);
1618 }
1619 return 0;
1620}
1621
1622/* Allocate and initialize interface vector. */
1623void
paula1ac18c2005-06-28 17:17:12 +00001624zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001625{
1626 /* Initialize interface and new hook. */
1627 if_init ();
1628 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1629 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1630
1631 /* Install configuration write function. */
1632 install_node (&interface_node, if_config_write);
1633
1634 install_element (VIEW_NODE, &show_interface_cmd);
1635 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001636 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001637 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001638 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001639 install_default (INTERFACE_NODE);
1640 install_element (INTERFACE_NODE, &interface_desc_cmd);
1641 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1642 install_element (INTERFACE_NODE, &multicast_cmd);
1643 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001644 install_element (INTERFACE_NODE, &linkdetect_cmd);
1645 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001646 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1647 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1648 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1649 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1650 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1651 install_element (INTERFACE_NODE, &ip_address_cmd);
1652 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1653#ifdef HAVE_IPV6
1654 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1655 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1656#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001657#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001658 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001659 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001660#endif /* HAVE_NETLINK */
1661}