blob: 54d8b10389fa19da96695cd30941869fb032a4c9 [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 (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200839 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
840 " multicast packets %llu%s",
841 (unsigned long long)ifp->stats.ifi_ipackets,
842 (unsigned long long)ifp->stats.ifi_ibytes,
843 (unsigned long long)ifp->stats.ifi_iqdrops,
844 (unsigned long long)ifp->stats.ifi_imcasts,
845 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000846
David Lamparter193e78f2015-04-21 10:42:30 +0200847 vty_out (vty, " input errors %llu%s",
848 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000849
David Lamparter193e78f2015-04-21 10:42:30 +0200850 vty_out (vty, " output packets %llu, bytes %llu,"
851 " multicast packets %llu%s",
852 (unsigned long long)ifp->stats.ifi_opackets,
853 (unsigned long long)ifp->stats.ifi_obytes,
854 (unsigned long long)ifp->stats.ifi_omcasts,
855 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000856
David Lamparter193e78f2015-04-21 10:42:30 +0200857 vty_out (vty, " output errors %llu%s",
858 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000859
David Lamparter193e78f2015-04-21 10:42:30 +0200860 vty_out (vty, " collisions %llu%s",
861 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000862#else
863 /* Statistics print out using sysctl (). */
864 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
865 " multicast packets %lu%s",
866 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
867 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
868 VTY_NEWLINE);
869
870 vty_out (vty, " input errors %lu%s",
871 ifp->stats.ifi_ierrors, VTY_NEWLINE);
872
873 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
874 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
875 ifp->stats.ifi_omcasts, VTY_NEWLINE);
876
877 vty_out (vty, " output errors %lu%s",
878 ifp->stats.ifi_oerrors, VTY_NEWLINE);
879
880 vty_out (vty, " collisions %lu%s",
881 ifp->stats.ifi_collisions, VTY_NEWLINE);
882#endif /* __bsdi__ || __NetBSD__ */
883#endif /* HAVE_NET_RT_IFLIST */
884}
885
paul718e3742002-12-13 20:15:29 +0000886/* Wrapper hook point for zebra daemon so that ifindex can be set
887 * DEFUN macro not used as extract.pl HAS to ignore this
888 * See also interface_cmd in lib/if.c
889 */
890DEFUN_NOSH (zebra_interface,
891 zebra_interface_cmd,
892 "interface IFNAME",
893 "Select an interface to configure\n"
894 "Interface's name\n")
895{
896 int ret;
897 struct interface * ifp;
898
899 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000900 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
901 return ret;
paul718e3742002-12-13 20:15:29 +0000902
903 ifp = vty->index;
904
ajsd2fc8892005-04-02 18:38:43 +0000905 if (ifp->ifindex == IFINDEX_INTERNAL)
906 /* Is this really necessary? Shouldn't status be initialized to 0
907 in that case? */
908 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000909
910 return ret;
911}
912
paul718e3742002-12-13 20:15:29 +0000913struct cmd_node interface_node =
914{
915 INTERFACE_NODE,
916 "%s(config-if)# ",
917 1
918};
919
920/* Show all or specified interface to vty. */
921DEFUN (show_interface, show_interface_cmd,
922 "show interface [IFNAME]",
923 SHOW_STR
924 "Interface status and configuration\n"
925 "Inteface name\n")
926{
hasso52dc7ee2004-09-23 19:18:23 +0000927 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000928 struct interface *ifp;
929
930#ifdef HAVE_PROC_NET_DEV
931 /* If system has interface statistics via proc file system, update
932 statistics. */
933 ifstat_update_proc ();
934#endif /* HAVE_PROC_NET_DEV */
935#ifdef HAVE_NET_RT_IFLIST
936 ifstat_update_sysctl ();
937#endif /* HAVE_NET_RT_IFLIST */
938
939 /* Specified interface print. */
940 if (argc != 0)
941 {
942 ifp = if_lookup_by_name (argv[0]);
943 if (ifp == NULL)
944 {
945 vty_out (vty, "%% Can't find interface %s%s", argv[0],
946 VTY_NEWLINE);
947 return CMD_WARNING;
948 }
949 if_dump_vty (vty, ifp);
950 return CMD_SUCCESS;
951 }
952
953 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000954 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
955 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000956
957 return CMD_SUCCESS;
958}
959
hassoed9bb6d2005-03-13 19:17:21 +0000960DEFUN (show_interface_desc,
961 show_interface_desc_cmd,
962 "show interface description",
963 SHOW_STR
964 "Interface status and configuration\n"
965 "Interface description\n")
966{
967 struct listnode *node;
968 struct interface *ifp;
969
970 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000971 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000972 {
973 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000974
975 len = vty_out (vty, "%s", ifp->name);
976 vty_out (vty, "%*s", (16 - len), " ");
977
978 if (if_is_up(ifp))
979 {
980 vty_out (vty, "up ");
981 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
982 {
983 if (if_is_running(ifp))
984 vty_out (vty, "up ");
985 else
986 vty_out (vty, "down ");
987 }
988 else
989 {
990 vty_out (vty, "unknown ");
991 }
992 }
993 else
994 {
995 vty_out (vty, "down down ");
996 }
997
998 if (ifp->desc)
999 vty_out (vty, "%s", ifp->desc);
1000 vty_out (vty, "%s", VTY_NEWLINE);
1001 }
1002 return CMD_SUCCESS;
1003}
1004
paul718e3742002-12-13 20:15:29 +00001005DEFUN (multicast,
1006 multicast_cmd,
1007 "multicast",
1008 "Set multicast flag to interface\n")
1009{
1010 int ret;
1011 struct interface *ifp;
1012 struct zebra_if *if_data;
1013
1014 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001015 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001016 {
paul48b33aa2002-12-13 20:52:52 +00001017 ret = if_set_flags (ifp, IFF_MULTICAST);
1018 if (ret < 0)
1019 {
1020 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1021 return CMD_WARNING;
1022 }
1023 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001024 }
paul718e3742002-12-13 20:15:29 +00001025 if_data = ifp->info;
1026 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001027
paul718e3742002-12-13 20:15:29 +00001028 return CMD_SUCCESS;
1029}
1030
1031DEFUN (no_multicast,
1032 no_multicast_cmd,
1033 "no multicast",
1034 NO_STR
1035 "Unset multicast flag to interface\n")
1036{
1037 int ret;
1038 struct interface *ifp;
1039 struct zebra_if *if_data;
1040
1041 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001042 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001043 {
paul48b33aa2002-12-13 20:52:52 +00001044 ret = if_unset_flags (ifp, IFF_MULTICAST);
1045 if (ret < 0)
1046 {
1047 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1048 return CMD_WARNING;
1049 }
1050 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001051 }
paul718e3742002-12-13 20:15:29 +00001052 if_data = ifp->info;
1053 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1054
1055 return CMD_SUCCESS;
1056}
1057
paul2e3b2e42002-12-13 21:03:13 +00001058DEFUN (linkdetect,
1059 linkdetect_cmd,
1060 "link-detect",
1061 "Enable link detection on interface\n")
1062{
paul2e3b2e42002-12-13 21:03:13 +00001063 struct interface *ifp;
1064 int if_was_operative;
1065
1066 ifp = (struct interface *) vty->index;
1067 if_was_operative = if_is_operative(ifp);
1068 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1069
1070 /* When linkdetection is enabled, if might come down */
1071 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1072
1073 /* FIXME: Will defer status change forwarding if interface
1074 does not come down! */
1075
1076 return CMD_SUCCESS;
1077}
1078
1079
1080DEFUN (no_linkdetect,
1081 no_linkdetect_cmd,
1082 "no link-detect",
1083 NO_STR
1084 "Disable link detection on interface\n")
1085{
paul2e3b2e42002-12-13 21:03:13 +00001086 struct interface *ifp;
1087 int if_was_operative;
1088
1089 ifp = (struct interface *) vty->index;
1090 if_was_operative = if_is_operative(ifp);
1091 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1092
1093 /* Interface may come up after disabling link detection */
1094 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1095
1096 /* FIXME: see linkdetect_cmd */
1097
1098 return CMD_SUCCESS;
1099}
1100
paul718e3742002-12-13 20:15:29 +00001101DEFUN (shutdown_if,
1102 shutdown_if_cmd,
1103 "shutdown",
1104 "Shutdown the selected interface\n")
1105{
1106 int ret;
1107 struct interface *ifp;
1108 struct zebra_if *if_data;
1109
1110 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001111 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001112 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001113 ret = if_unset_flags (ifp, IFF_UP);
1114 if (ret < 0)
1115 {
1116 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1117 return CMD_WARNING;
1118 }
1119 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001120 }
paul718e3742002-12-13 20:15:29 +00001121 if_data = ifp->info;
1122 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1123
1124 return CMD_SUCCESS;
1125}
1126
1127DEFUN (no_shutdown_if,
1128 no_shutdown_if_cmd,
1129 "no shutdown",
1130 NO_STR
1131 "Shutdown the selected interface\n")
1132{
1133 int ret;
1134 struct interface *ifp;
1135 struct zebra_if *if_data;
1136
1137 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001138
1139 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001140 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001141 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1142 if (ret < 0)
1143 {
1144 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1145 return CMD_WARNING;
1146 }
1147 if_refresh (ifp);
1148
1149 /* Some addresses (in particular, IPv6 addresses on Linux) get
1150 * removed when the interface goes down. They need to be readded.
1151 */
1152 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001153 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001154
paul718e3742002-12-13 20:15:29 +00001155 if_data = ifp->info;
1156 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1157
1158 return CMD_SUCCESS;
1159}
1160
1161DEFUN (bandwidth_if,
1162 bandwidth_if_cmd,
1163 "bandwidth <1-10000000>",
1164 "Set bandwidth informational parameter\n"
1165 "Bandwidth in kilobits\n")
1166{
1167 struct interface *ifp;
1168 unsigned int bandwidth;
1169
1170 ifp = (struct interface *) vty->index;
1171 bandwidth = strtol(argv[0], NULL, 10);
1172
1173 /* bandwidth range is <1-10000000> */
1174 if (bandwidth < 1 || bandwidth > 10000000)
1175 {
1176 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1177 return CMD_WARNING;
1178 }
1179
1180 ifp->bandwidth = bandwidth;
1181
1182 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001183 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001184 zebra_interface_up_update (ifp);
1185
1186 return CMD_SUCCESS;
1187}
1188
1189DEFUN (no_bandwidth_if,
1190 no_bandwidth_if_cmd,
1191 "no bandwidth",
1192 NO_STR
1193 "Set bandwidth informational parameter\n")
1194{
1195 struct interface *ifp;
1196
1197 ifp = (struct interface *) vty->index;
1198
1199 ifp->bandwidth = 0;
1200
1201 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001202 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001203 zebra_interface_up_update (ifp);
1204
1205 return CMD_SUCCESS;
1206}
1207
1208ALIAS (no_bandwidth_if,
1209 no_bandwidth_if_val_cmd,
1210 "no bandwidth <1-10000000>",
1211 NO_STR
1212 "Set bandwidth informational parameter\n"
1213 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001214
paula1ac18c2005-06-28 17:17:12 +00001215static int
hasso39db97e2004-10-12 20:50:58 +00001216ip_address_install (struct vty *vty, struct interface *ifp,
1217 const char *addr_str, const char *peer_str,
1218 const char *label)
paul718e3742002-12-13 20:15:29 +00001219{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001220 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001221 struct prefix_ipv4 cp;
1222 struct connected *ifc;
1223 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001224 int ret;
1225
Christian Frankebfac8dc2013-01-24 14:04:50 +00001226 if_data = ifp->info;
1227
paul718e3742002-12-13 20:15:29 +00001228 ret = str2prefix_ipv4 (addr_str, &cp);
1229 if (ret <= 0)
1230 {
1231 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1232 return CMD_WARNING;
1233 }
1234
paulca162182005-09-12 16:58:52 +00001235 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001236 if (! ifc)
1237 {
1238 ifc = connected_new ();
1239 ifc->ifp = ifp;
1240
1241 /* Address. */
1242 p = prefix_ipv4_new ();
1243 *p = cp;
1244 ifc->address = (struct prefix *) p;
1245
1246 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001247 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001248 {
1249 p = prefix_ipv4_new ();
1250 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001251 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001252 ifc->destination = (struct prefix *) p;
1253 }
1254
paul718e3742002-12-13 20:15:29 +00001255 /* Label. */
1256 if (label)
paul0752ef02005-11-03 12:35:21 +00001257 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001258
1259 /* Add to linked list. */
1260 listnode_add (ifp->connected, ifc);
1261 }
1262
1263 /* This address is configured from zebra. */
1264 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1265 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1266
1267 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001268 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001269 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1270 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001271 {
1272 /* Some system need to up the interface to set IP address. */
1273 if (! if_is_up (ifp))
1274 {
1275 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1276 if_refresh (ifp);
1277 }
1278
1279 ret = if_set_prefix (ifp, ifc);
1280 if (ret < 0)
1281 {
1282 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001283 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001284 return CMD_WARNING;
1285 }
1286
Christian Frankef7f740f2013-01-24 14:04:48 +00001287 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001288 /* The address will be advertised to zebra clients when the notification
1289 * from the kernel has been received.
1290 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001291 }
1292
1293 return CMD_SUCCESS;
1294}
1295
paula1ac18c2005-06-28 17:17:12 +00001296static int
hasso39db97e2004-10-12 20:50:58 +00001297ip_address_uninstall (struct vty *vty, struct interface *ifp,
1298 const char *addr_str, const char *peer_str,
1299 const char *label)
paul718e3742002-12-13 20:15:29 +00001300{
1301 struct prefix_ipv4 cp;
1302 struct connected *ifc;
1303 int ret;
1304
1305 /* Convert to prefix structure. */
1306 ret = str2prefix_ipv4 (addr_str, &cp);
1307 if (ret <= 0)
1308 {
1309 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1310 return CMD_WARNING;
1311 }
1312
1313 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001314 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001315 if (! ifc)
1316 {
1317 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1318 return CMD_WARNING;
1319 }
1320
1321 /* This is not configured address. */
1322 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1323 return CMD_WARNING;
1324
Paul Jakma74ecdc92006-06-15 18:10:47 +00001325 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1326
paul718e3742002-12-13 20:15:29 +00001327 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001328 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001329 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1330 {
1331 listnode_delete (ifp->connected, ifc);
1332 connected_free (ifc);
1333 return CMD_WARNING;
1334 }
1335
1336 /* This is real route. */
1337 ret = if_unset_prefix (ifp, ifc);
1338 if (ret < 0)
1339 {
1340 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001341 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001342 return CMD_WARNING;
1343 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001344 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001345 /* we will receive a kernel notification about this route being removed.
1346 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001347 return CMD_SUCCESS;
1348}
1349
1350DEFUN (ip_address,
1351 ip_address_cmd,
1352 "ip address A.B.C.D/M",
1353 "Interface Internet Protocol config commands\n"
1354 "Set the IP address of an interface\n"
1355 "IP address (e.g. 10.0.0.1/8)\n")
1356{
hassoeef1fe12004-10-03 18:46:08 +00001357 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001358}
1359
1360DEFUN (no_ip_address,
1361 no_ip_address_cmd,
1362 "no ip address A.B.C.D/M",
1363 NO_STR
1364 "Interface Internet Protocol config commands\n"
1365 "Set the IP address of an interface\n"
1366 "IP Address (e.g. 10.0.0.1/8)")
1367{
hassoeef1fe12004-10-03 18:46:08 +00001368 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001369}
1370
1371#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001372DEFUN (ip_address_label,
1373 ip_address_label_cmd,
1374 "ip address A.B.C.D/M label LINE",
1375 "Interface Internet Protocol config commands\n"
1376 "Set the IP address of an interface\n"
1377 "IP address (e.g. 10.0.0.1/8)\n"
1378 "Label of this address\n"
1379 "Label\n")
1380{
hassoeef1fe12004-10-03 18:46:08 +00001381 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001382}
1383
1384DEFUN (no_ip_address_label,
1385 no_ip_address_label_cmd,
1386 "no ip address A.B.C.D/M label LINE",
1387 NO_STR
1388 "Interface Internet Protocol config commands\n"
1389 "Set the IP address of an interface\n"
1390 "IP address (e.g. 10.0.0.1/8)\n"
1391 "Label of this address\n"
1392 "Label\n")
1393{
hassoeef1fe12004-10-03 18:46:08 +00001394 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001395}
1396#endif /* HAVE_NETLINK */
1397
1398#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001399static int
hasso39db97e2004-10-12 20:50:58 +00001400ipv6_address_install (struct vty *vty, struct interface *ifp,
1401 const char *addr_str, const char *peer_str,
1402 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001403{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001404 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001405 struct prefix_ipv6 cp;
1406 struct connected *ifc;
1407 struct prefix_ipv6 *p;
1408 int ret;
1409
Christian Frankebfac8dc2013-01-24 14:04:50 +00001410 if_data = ifp->info;
1411
paul718e3742002-12-13 20:15:29 +00001412 ret = str2prefix_ipv6 (addr_str, &cp);
1413 if (ret <= 0)
1414 {
1415 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1416 return CMD_WARNING;
1417 }
1418
paulca162182005-09-12 16:58:52 +00001419 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001420 if (! ifc)
1421 {
1422 ifc = connected_new ();
1423 ifc->ifp = ifp;
1424
1425 /* Address. */
1426 p = prefix_ipv6_new ();
1427 *p = cp;
1428 ifc->address = (struct prefix *) p;
1429
1430 /* Secondary. */
1431 if (secondary)
1432 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1433
1434 /* Label. */
1435 if (label)
paul0752ef02005-11-03 12:35:21 +00001436 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001437
1438 /* Add to linked list. */
1439 listnode_add (ifp->connected, ifc);
1440 }
1441
1442 /* This address is configured from zebra. */
1443 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1444 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1445
1446 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001447 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001448 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1449 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001450 {
1451 /* Some system need to up the interface to set IP address. */
1452 if (! if_is_up (ifp))
1453 {
1454 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1455 if_refresh (ifp);
1456 }
1457
1458 ret = if_prefix_add_ipv6 (ifp, ifc);
1459
1460 if (ret < 0)
1461 {
1462 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001463 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001464 return CMD_WARNING;
1465 }
1466
Christian Frankef7f740f2013-01-24 14:04:48 +00001467 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001468 /* The address will be advertised to zebra clients when the notification
1469 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001470 }
1471
1472 return CMD_SUCCESS;
1473}
1474
paula1ac18c2005-06-28 17:17:12 +00001475static int
hasso39db97e2004-10-12 20:50:58 +00001476ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1477 const char *addr_str, const char *peer_str,
1478 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001479{
1480 struct prefix_ipv6 cp;
1481 struct connected *ifc;
1482 int ret;
1483
1484 /* Convert to prefix structure. */
1485 ret = str2prefix_ipv6 (addr_str, &cp);
1486 if (ret <= 0)
1487 {
1488 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1489 return CMD_WARNING;
1490 }
1491
1492 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001493 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001494 if (! ifc)
1495 {
1496 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1497 return CMD_WARNING;
1498 }
1499
1500 /* This is not configured address. */
1501 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1502 return CMD_WARNING;
1503
Christian Franke676e1a02013-01-24 14:04:45 +00001504 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1505
paul718e3742002-12-13 20:15:29 +00001506 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001507 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001508 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1509 {
1510 listnode_delete (ifp->connected, ifc);
1511 connected_free (ifc);
1512 return CMD_WARNING;
1513 }
1514
1515 /* This is real route. */
1516 ret = if_prefix_delete_ipv6 (ifp, ifc);
1517 if (ret < 0)
1518 {
1519 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001520 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001521 return CMD_WARNING;
1522 }
1523
Christian Frankef7f740f2013-01-24 14:04:48 +00001524 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001525 /* This information will be propagated to the zclients when the
1526 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001527 return CMD_SUCCESS;
1528}
1529
1530DEFUN (ipv6_address,
1531 ipv6_address_cmd,
1532 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001533 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001534 "Set the IP address of an interface\n"
1535 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1536{
1537 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1538}
1539
1540DEFUN (no_ipv6_address,
1541 no_ipv6_address_cmd,
1542 "no ipv6 address X:X::X:X/M",
1543 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001544 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001545 "Set the IP address of an interface\n"
1546 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1547{
1548 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1549}
1550#endif /* HAVE_IPV6 */
1551
paula1ac18c2005-06-28 17:17:12 +00001552static int
paul718e3742002-12-13 20:15:29 +00001553if_config_write (struct vty *vty)
1554{
hasso52dc7ee2004-09-23 19:18:23 +00001555 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001556 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001557
paul1eb8ef22005-04-07 07:30:20 +00001558 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001559 {
1560 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001561 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001562 struct connected *ifc;
1563 struct prefix *p;
1564
paul718e3742002-12-13 20:15:29 +00001565 if_data = ifp->info;
1566
1567 vty_out (vty, "interface %s%s", ifp->name,
1568 VTY_NEWLINE);
1569
Christian Frankebfac8dc2013-01-24 14:04:50 +00001570 if (if_data)
1571 {
1572 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1573 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1574 }
1575
paul718e3742002-12-13 20:15:29 +00001576 if (ifp->desc)
1577 vty_out (vty, " description %s%s", ifp->desc,
1578 VTY_NEWLINE);
1579
1580 /* Assign bandwidth here to avoid unnecessary interface flap
1581 while processing config script */
1582 if (ifp->bandwidth != 0)
1583 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1584
paul2e3b2e42002-12-13 21:03:13 +00001585 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1586 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001587 else
1588 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001589
paul1eb8ef22005-04-07 07:30:20 +00001590 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001591 {
paul718e3742002-12-13 20:15:29 +00001592 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1593 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001594 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001595 p = ifc->address;
1596 vty_out (vty, " ip%s address %s/%d",
1597 p->family == AF_INET ? "" : "v6",
Stephen Hemminger81cce012009-04-28 14:28:00 -07001598 inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
paul718e3742002-12-13 20:15:29 +00001599 p->prefixlen);
1600
paul718e3742002-12-13 20:15:29 +00001601 if (ifc->label)
1602 vty_out (vty, " label %s", ifc->label);
1603
1604 vty_out (vty, "%s", VTY_NEWLINE);
1605 }
1606 }
1607
1608 if (if_data)
1609 {
paul718e3742002-12-13 20:15:29 +00001610 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1611 vty_out (vty, " %smulticast%s",
1612 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1613 VTY_NEWLINE);
1614 }
1615
1616#ifdef RTADV
1617 rtadv_config_write (vty, ifp);
1618#endif /* RTADV */
1619
hassoca776982004-06-12 14:33:05 +00001620#ifdef HAVE_IRDP
1621 irdp_config_write (vty, ifp);
1622#endif /* IRDP */
1623
paul718e3742002-12-13 20:15:29 +00001624 vty_out (vty, "!%s", VTY_NEWLINE);
1625 }
1626 return 0;
1627}
1628
1629/* Allocate and initialize interface vector. */
1630void
paula1ac18c2005-06-28 17:17:12 +00001631zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001632{
1633 /* Initialize interface and new hook. */
1634 if_init ();
1635 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1636 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1637
1638 /* Install configuration write function. */
1639 install_node (&interface_node, if_config_write);
1640
1641 install_element (VIEW_NODE, &show_interface_cmd);
1642 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001643 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001644 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001645 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001646 install_default (INTERFACE_NODE);
1647 install_element (INTERFACE_NODE, &interface_desc_cmd);
1648 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1649 install_element (INTERFACE_NODE, &multicast_cmd);
1650 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001651 install_element (INTERFACE_NODE, &linkdetect_cmd);
1652 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001653 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1654 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1655 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1656 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1657 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1658 install_element (INTERFACE_NODE, &ip_address_cmd);
1659 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1660#ifdef HAVE_IPV6
1661 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1662 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1663#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001664#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001665 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001666 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001667#endif /* HAVE_NETLINK */
1668}