blob: 3063dad8174614ecb24456c92dde331757b3695f [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)
Feng Lu2fc97f62015-05-22 11:39:57 +0200384 zlog_debug ("interface %s vrf %u index %d is shutdown. "
385 "Won't wake it up.",
386 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000387 return;
388 }
389
paul718e3742002-12-13 20:15:29 +0000390 if_addr_wakeup (ifp);
391
392 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200393 zlog_debug ("interface %s vrf %u index %d becomes active.",
394 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000395 }
396 else
397 {
398 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200399 zlog_debug ("interface %s vrf %u index %d is added.",
400 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000401 }
402}
403
paul6eb88272005-07-29 14:36:00 +0000404/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000405void
406if_delete_update (struct interface *ifp)
407{
paul718e3742002-12-13 20:15:29 +0000408 struct connected *ifc;
409 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000410 struct route_node *rn;
411 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000412
413 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000414
415 if (if_is_up(ifp))
416 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200417 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
418 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000419 return;
420 }
421
422 /* Mark interface as inactive */
423 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
424
425 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200426 zlog_debug ("interface %s vrf %u index %d is now inactive.",
427 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000428
429 /* Delete connected routes from the kernel. */
430 if (ifp->connected)
431 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000432 struct listnode *node;
433 struct listnode *last = NULL;
434
hassoeef1fe12004-10-03 18:46:08 +0000435 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000436 {
paul1eb8ef22005-04-07 07:30:20 +0000437 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000438 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000439
Paul Jakmabeb56332006-05-11 13:28:05 +0000440 if (p->family == AF_INET
441 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000442 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000443 struct listnode *anode;
444 struct listnode *next;
445 struct listnode *first;
446 struct list *addr_list;
447
hassoeef1fe12004-10-03 18:46:08 +0000448 route_unlock_node (rn);
449 addr_list = (struct list *) rn->info;
450
451 /* Remove addresses, secondaries first. */
452 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000453 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000454 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000455 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000456 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000457 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000458 first = NULL;
459 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000460 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000461
Paul Jakmad9a18f12007-04-10 19:30:20 +0000462 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000463 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000464 connected_down_ipv4 (ifp, ifc);
465
Christian Franke02b48052013-01-24 14:04:49 +0000466 /* XXX: We have to send notifications here explicitly, because we destroy
467 * the ifc before receiving the notification about the address being deleted.
468 */
hassoeef1fe12004-10-03 18:46:08 +0000469 zebra_interface_address_delete_update (ifp, ifc);
470
471 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000472 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000473
474 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000475 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000476 route_unlock_node (rn);
477
478 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000479 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
480 {
481 listnode_delete (ifp->connected, ifc);
482 connected_free (ifc);
483 }
484 else
485 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000486 }
487
488 /* Free chain list and respective route node. */
489 list_delete (addr_list);
490 rn->info = NULL;
491 route_unlock_node (rn);
492 }
paul718e3742002-12-13 20:15:29 +0000493#ifdef HAVE_IPV6
494 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000495 {
496 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000497
hassoeef1fe12004-10-03 18:46:08 +0000498 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000499
hassoeef1fe12004-10-03 18:46:08 +0000500 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000501 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000502
503 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
504 last = node;
505 else
506 {
507 listnode_delete (ifp->connected, ifc);
508 connected_free (ifc);
509 }
paul718e3742002-12-13 20:15:29 +0000510 }
hassoeef1fe12004-10-03 18:46:08 +0000511#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200512 else
513 {
514 last = node;
515 }
paul718e3742002-12-13 20:15:29 +0000516 }
517 }
518 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000519
520 /* Update ifindex after distributing the delete message. This is in
521 case any client needs to have the old value of ifindex available
522 while processing the deletion. Each client daemon is responsible
523 for setting ifindex to IFINDEX_INTERNAL after processing the
524 interface deletion message. */
525 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000526}
527
528/* Interface is up. */
529void
530if_up (struct interface *ifp)
531{
hasso52dc7ee2004-09-23 19:18:23 +0000532 struct listnode *node;
533 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000534 struct connected *ifc;
535 struct prefix *p;
536
537 /* Notify the protocol daemons. */
538 zebra_interface_up_update (ifp);
539
540 /* Install connected routes to the kernel. */
541 if (ifp->connected)
542 {
paul1eb8ef22005-04-07 07:30:20 +0000543 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000544 {
paul718e3742002-12-13 20:15:29 +0000545 p = ifc->address;
546
547 if (p->family == AF_INET)
548 connected_up_ipv4 (ifp, ifc);
549#ifdef HAVE_IPV6
550 else if (p->family == AF_INET6)
551 connected_up_ipv6 (ifp, ifc);
552#endif /* HAVE_IPV6 */
553 }
554 }
555
556 /* Examine all static routes. */
557 rib_update ();
558}
559
560/* Interface goes down. We have to manage different behavior of based
561 OS. */
562void
563if_down (struct interface *ifp)
564{
hasso52dc7ee2004-09-23 19:18:23 +0000565 struct listnode *node;
566 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000567 struct connected *ifc;
568 struct prefix *p;
569
570 /* Notify to the protocol daemons. */
571 zebra_interface_down_update (ifp);
572
573 /* Delete connected routes from the kernel. */
574 if (ifp->connected)
575 {
paul1eb8ef22005-04-07 07:30:20 +0000576 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000577 {
paul718e3742002-12-13 20:15:29 +0000578 p = ifc->address;
579
580 if (p->family == AF_INET)
581 connected_down_ipv4 (ifp, ifc);
582#ifdef HAVE_IPV6
583 else if (p->family == AF_INET6)
584 connected_down_ipv6 (ifp, ifc);
585#endif /* HAVE_IPV6 */
586 }
587 }
588
589 /* Examine all static routes which direct to the interface. */
590 rib_update ();
591}
592
593void
594if_refresh (struct interface *ifp)
595{
paul5c78b3d2006-01-25 04:31:40 +0000596 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000597}
598
paul718e3742002-12-13 20:15:29 +0000599/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000600static int
paul718e3742002-12-13 20:15:29 +0000601prefix_vty_out (struct vty *vty, struct prefix *p)
602{
603 char str[INET6_ADDRSTRLEN];
604
605 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
606 vty_out (vty, "%s", str);
607 return strlen (str);
608}
609
610/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000611static void
paul718e3742002-12-13 20:15:29 +0000612connected_dump_vty (struct vty *vty, struct connected *connected)
613{
614 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000615
616 /* Print interface address. */
617 p = connected->address;
618 vty_out (vty, " %s ", prefix_family_str (p));
619 prefix_vty_out (vty, p);
620 vty_out (vty, "/%d", p->prefixlen);
621
622 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000623 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000624 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000625 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
626 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000627 }
628
629 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
630 vty_out (vty, " secondary");
631
632 if (connected->label)
633 vty_out (vty, " %s", connected->label);
634
635 vty_out (vty, "%s", VTY_NEWLINE);
636}
637
638#ifdef RTADV
639/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000640static void
paul718e3742002-12-13 20:15:29 +0000641nd_dump_vty (struct vty *vty, struct interface *ifp)
642{
643 struct zebra_if *zif;
644 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000645 int interval;
paul718e3742002-12-13 20:15:29 +0000646
647 zif = (struct zebra_if *) ifp->info;
648 rtadv = &zif->rtadv;
649
650 if (rtadv->AdvSendAdvertisements)
651 {
652 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
653 rtadv->AdvReachableTime, VTY_NEWLINE);
654 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
655 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000656 interval = rtadv->MaxRtrAdvInterval;
657 if (interval % 1000)
658 vty_out (vty, " ND router advertisements are sent every "
659 "%d milliseconds%s", interval,
660 VTY_NEWLINE);
661 else
662 vty_out (vty, " ND router advertisements are sent every "
663 "%d seconds%s", interval / 1000,
664 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400665 if (rtadv->AdvDefaultLifetime != -1)
666 vty_out (vty, " ND router advertisements live for %d seconds%s",
667 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
668 else
669 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
670 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000671 vty_out (vty, " ND router advertisement default router preference is "
672 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
673 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000674 if (rtadv->AdvManagedFlag)
675 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
676 VTY_NEWLINE);
677 else
678 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
679 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000680 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400681 {
vincent7cee1bb2005-03-25 13:08:53 +0000682 vty_out (vty, " ND router advertisements with "
683 "Home Agent flag bit set.%s",
684 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400685 if (rtadv->HomeAgentLifetime != -1)
686 vty_out (vty, " Home Agent lifetime is %u seconds%s",
687 rtadv->HomeAgentLifetime, VTY_NEWLINE);
688 else
689 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
690 VTY_NEWLINE);
691 vty_out (vty, " Home Agent preference is %u%s",
692 rtadv->HomeAgentPreference, VTY_NEWLINE);
693 }
vincent7cee1bb2005-03-25 13:08:53 +0000694 if (rtadv->AdvIntervalOption)
695 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
696 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000697 }
698}
699#endif /* RTADV */
700
701/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703if_dump_vty (struct vty *vty, struct interface *ifp)
704{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000705#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000706 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000707#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000708 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000709 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000710 struct route_node *rn;
711 struct zebra_if *zebra_if;
712
713 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000714
paul2e3b2e42002-12-13 21:03:13 +0000715 vty_out (vty, "Interface %s is ", ifp->name);
716 if (if_is_up(ifp)) {
717 vty_out (vty, "up, line protocol ");
718
719 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
720 if (if_is_running(ifp))
721 vty_out (vty, "is up%s", VTY_NEWLINE);
722 else
723 vty_out (vty, "is down%s", VTY_NEWLINE);
724 } else {
725 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
726 }
727 } else {
728 vty_out (vty, "down%s", VTY_NEWLINE);
729 }
730
Feng Lu2fc97f62015-05-22 11:39:57 +0200731 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
732
paul718e3742002-12-13 20:15:29 +0000733 if (ifp->desc)
734 vty_out (vty, " Description: %s%s", ifp->desc,
735 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000736 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000737 {
ajsd2fc8892005-04-02 18:38:43 +0000738 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000739 return;
740 }
741 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
742 {
743 vty_out(vty, " index %d inactive interface%s",
744 ifp->ifindex,
745 VTY_NEWLINE);
746 return;
747 }
748
749 vty_out (vty, " index %d metric %d mtu %d ",
750 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000751#ifdef HAVE_IPV6
752 if (ifp->mtu6 != ifp->mtu)
753 vty_out (vty, "mtu6 %d ", ifp->mtu6);
754#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000755 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
756 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000757
paul718e3742002-12-13 20:15:29 +0000758 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000759#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000760 sdl = &ifp->sdl;
761 if (sdl != NULL && sdl->sdl_alen != 0)
762 {
763 int i;
764 u_char *ptr;
765
766 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000767 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
768 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000769 vty_out (vty, "%s", VTY_NEWLINE);
770 }
771#else
772 if (ifp->hw_addr_len != 0)
773 {
774 int i;
775
776 vty_out (vty, " HWaddr: ");
777 for (i = 0; i < ifp->hw_addr_len; i++)
778 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
779 vty_out (vty, "%s", VTY_NEWLINE);
780 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000781#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000782
783 /* Bandwidth in kbps */
784 if (ifp->bandwidth != 0)
785 {
786 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
787 vty_out(vty, "%s", VTY_NEWLINE);
788 }
789
hassoeef1fe12004-10-03 18:46:08 +0000790 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000791 {
hassoeef1fe12004-10-03 18:46:08 +0000792 if (! rn->info)
793 continue;
794
paul1eb8ef22005-04-07 07:30:20 +0000795 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
796 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000797 }
798
paul1eb8ef22005-04-07 07:30:20 +0000799 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000800 {
hasso39db97e2004-10-12 20:50:58 +0000801 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
802 (connected->address->family == AF_INET6))
803 connected_dump_vty (vty, connected);
804 }
805
paul718e3742002-12-13 20:15:29 +0000806#ifdef RTADV
807 nd_dump_vty (vty, ifp);
808#endif /* RTADV */
809
810#ifdef HAVE_PROC_NET_DEV
811 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000812 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
813 "%lu dropped%s",
814 ifp->stats.rx_packets, ifp->stats.rx_multicast,
815 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000816
hasso6f2c27a2005-01-18 13:44:35 +0000817 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000818 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000819 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
820 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000821 ifp->stats.rx_frame_errors, VTY_NEWLINE);
822
823 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000824 ifp->stats.rx_missed_errors, VTY_NEWLINE);
825
hasso6f2c27a2005-01-18 13:44:35 +0000826 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000827 ifp->stats.tx_packets, ifp->stats.tx_bytes,
828 ifp->stats.tx_dropped, VTY_NEWLINE);
829
hasso6f2c27a2005-01-18 13:44:35 +0000830 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
831 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000832 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
833 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000834 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000835
hasso6f2c27a2005-01-18 13:44:35 +0000836 vty_out (vty, " %lu window, %lu collisions%s",
837 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000838#endif /* HAVE_PROC_NET_DEV */
839
840#ifdef HAVE_NET_RT_IFLIST
841#if defined (__bsdi__) || defined (__NetBSD__)
842 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200843 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
844 " multicast packets %llu%s",
845 (unsigned long long)ifp->stats.ifi_ipackets,
846 (unsigned long long)ifp->stats.ifi_ibytes,
847 (unsigned long long)ifp->stats.ifi_iqdrops,
848 (unsigned long long)ifp->stats.ifi_imcasts,
849 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000850
David Lamparter193e78f2015-04-21 10:42:30 +0200851 vty_out (vty, " input errors %llu%s",
852 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000853
David Lamparter193e78f2015-04-21 10:42:30 +0200854 vty_out (vty, " output packets %llu, bytes %llu,"
855 " multicast packets %llu%s",
856 (unsigned long long)ifp->stats.ifi_opackets,
857 (unsigned long long)ifp->stats.ifi_obytes,
858 (unsigned long long)ifp->stats.ifi_omcasts,
859 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000860
David Lamparter193e78f2015-04-21 10:42:30 +0200861 vty_out (vty, " output errors %llu%s",
862 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000863
David Lamparter193e78f2015-04-21 10:42:30 +0200864 vty_out (vty, " collisions %llu%s",
865 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000866#else
867 /* Statistics print out using sysctl (). */
868 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
869 " multicast packets %lu%s",
870 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
871 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
872 VTY_NEWLINE);
873
874 vty_out (vty, " input errors %lu%s",
875 ifp->stats.ifi_ierrors, VTY_NEWLINE);
876
877 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
878 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
879 ifp->stats.ifi_omcasts, VTY_NEWLINE);
880
881 vty_out (vty, " output errors %lu%s",
882 ifp->stats.ifi_oerrors, VTY_NEWLINE);
883
884 vty_out (vty, " collisions %lu%s",
885 ifp->stats.ifi_collisions, VTY_NEWLINE);
886#endif /* __bsdi__ || __NetBSD__ */
887#endif /* HAVE_NET_RT_IFLIST */
888}
889
paul718e3742002-12-13 20:15:29 +0000890/* Wrapper hook point for zebra daemon so that ifindex can be set
891 * DEFUN macro not used as extract.pl HAS to ignore this
892 * See also interface_cmd in lib/if.c
893 */
894DEFUN_NOSH (zebra_interface,
895 zebra_interface_cmd,
896 "interface IFNAME",
897 "Select an interface to configure\n"
898 "Interface's name\n")
899{
900 int ret;
901 struct interface * ifp;
902
903 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000904 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
905 return ret;
paul718e3742002-12-13 20:15:29 +0000906
907 ifp = vty->index;
908
ajsd2fc8892005-04-02 18:38:43 +0000909 if (ifp->ifindex == IFINDEX_INTERNAL)
910 /* Is this really necessary? Shouldn't status be initialized to 0
911 in that case? */
912 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000913
914 return ret;
915}
916
paul718e3742002-12-13 20:15:29 +0000917struct cmd_node interface_node =
918{
919 INTERFACE_NODE,
920 "%s(config-if)# ",
921 1
922};
923
924/* Show all or specified interface to vty. */
925DEFUN (show_interface, show_interface_cmd,
926 "show interface [IFNAME]",
927 SHOW_STR
928 "Interface status and configuration\n"
929 "Inteface name\n")
930{
hasso52dc7ee2004-09-23 19:18:23 +0000931 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000932 struct interface *ifp;
933
934#ifdef HAVE_PROC_NET_DEV
935 /* If system has interface statistics via proc file system, update
936 statistics. */
937 ifstat_update_proc ();
938#endif /* HAVE_PROC_NET_DEV */
939#ifdef HAVE_NET_RT_IFLIST
940 ifstat_update_sysctl ();
941#endif /* HAVE_NET_RT_IFLIST */
942
943 /* Specified interface print. */
944 if (argc != 0)
945 {
946 ifp = if_lookup_by_name (argv[0]);
947 if (ifp == NULL)
948 {
949 vty_out (vty, "%% Can't find interface %s%s", argv[0],
950 VTY_NEWLINE);
951 return CMD_WARNING;
952 }
953 if_dump_vty (vty, ifp);
954 return CMD_SUCCESS;
955 }
956
957 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000958 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
959 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000960
961 return CMD_SUCCESS;
962}
963
hassoed9bb6d2005-03-13 19:17:21 +0000964DEFUN (show_interface_desc,
965 show_interface_desc_cmd,
966 "show interface description",
967 SHOW_STR
968 "Interface status and configuration\n"
969 "Interface description\n")
970{
971 struct listnode *node;
972 struct interface *ifp;
973
974 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000975 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000976 {
977 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000978
979 len = vty_out (vty, "%s", ifp->name);
980 vty_out (vty, "%*s", (16 - len), " ");
981
982 if (if_is_up(ifp))
983 {
984 vty_out (vty, "up ");
985 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
986 {
987 if (if_is_running(ifp))
988 vty_out (vty, "up ");
989 else
990 vty_out (vty, "down ");
991 }
992 else
993 {
994 vty_out (vty, "unknown ");
995 }
996 }
997 else
998 {
999 vty_out (vty, "down down ");
1000 }
1001
1002 if (ifp->desc)
1003 vty_out (vty, "%s", ifp->desc);
1004 vty_out (vty, "%s", VTY_NEWLINE);
1005 }
1006 return CMD_SUCCESS;
1007}
1008
paul718e3742002-12-13 20:15:29 +00001009DEFUN (multicast,
1010 multicast_cmd,
1011 "multicast",
1012 "Set multicast flag to interface\n")
1013{
1014 int ret;
1015 struct interface *ifp;
1016 struct zebra_if *if_data;
1017
1018 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001019 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001020 {
paul48b33aa2002-12-13 20:52:52 +00001021 ret = if_set_flags (ifp, IFF_MULTICAST);
1022 if (ret < 0)
1023 {
1024 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1025 return CMD_WARNING;
1026 }
1027 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001028 }
paul718e3742002-12-13 20:15:29 +00001029 if_data = ifp->info;
1030 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001031
paul718e3742002-12-13 20:15:29 +00001032 return CMD_SUCCESS;
1033}
1034
1035DEFUN (no_multicast,
1036 no_multicast_cmd,
1037 "no multicast",
1038 NO_STR
1039 "Unset multicast flag to interface\n")
1040{
1041 int ret;
1042 struct interface *ifp;
1043 struct zebra_if *if_data;
1044
1045 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001046 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001047 {
paul48b33aa2002-12-13 20:52:52 +00001048 ret = if_unset_flags (ifp, IFF_MULTICAST);
1049 if (ret < 0)
1050 {
1051 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1052 return CMD_WARNING;
1053 }
1054 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001055 }
paul718e3742002-12-13 20:15:29 +00001056 if_data = ifp->info;
1057 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1058
1059 return CMD_SUCCESS;
1060}
1061
paul2e3b2e42002-12-13 21:03:13 +00001062DEFUN (linkdetect,
1063 linkdetect_cmd,
1064 "link-detect",
1065 "Enable link detection on interface\n")
1066{
paul2e3b2e42002-12-13 21:03:13 +00001067 struct interface *ifp;
1068 int if_was_operative;
1069
1070 ifp = (struct interface *) vty->index;
1071 if_was_operative = if_is_operative(ifp);
1072 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1073
1074 /* When linkdetection is enabled, if might come down */
1075 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1076
1077 /* FIXME: Will defer status change forwarding if interface
1078 does not come down! */
1079
1080 return CMD_SUCCESS;
1081}
1082
1083
1084DEFUN (no_linkdetect,
1085 no_linkdetect_cmd,
1086 "no link-detect",
1087 NO_STR
1088 "Disable link detection on interface\n")
1089{
paul2e3b2e42002-12-13 21:03:13 +00001090 struct interface *ifp;
1091 int if_was_operative;
1092
1093 ifp = (struct interface *) vty->index;
1094 if_was_operative = if_is_operative(ifp);
1095 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1096
1097 /* Interface may come up after disabling link detection */
1098 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1099
1100 /* FIXME: see linkdetect_cmd */
1101
1102 return CMD_SUCCESS;
1103}
1104
paul718e3742002-12-13 20:15:29 +00001105DEFUN (shutdown_if,
1106 shutdown_if_cmd,
1107 "shutdown",
1108 "Shutdown the selected interface\n")
1109{
1110 int ret;
1111 struct interface *ifp;
1112 struct zebra_if *if_data;
1113
1114 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001115 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001116 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001117 ret = if_unset_flags (ifp, IFF_UP);
1118 if (ret < 0)
1119 {
1120 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1121 return CMD_WARNING;
1122 }
1123 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001124 }
paul718e3742002-12-13 20:15:29 +00001125 if_data = ifp->info;
1126 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1127
1128 return CMD_SUCCESS;
1129}
1130
1131DEFUN (no_shutdown_if,
1132 no_shutdown_if_cmd,
1133 "no shutdown",
1134 NO_STR
1135 "Shutdown the selected interface\n")
1136{
1137 int ret;
1138 struct interface *ifp;
1139 struct zebra_if *if_data;
1140
1141 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001142
1143 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001144 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001145 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1146 if (ret < 0)
1147 {
1148 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1149 return CMD_WARNING;
1150 }
1151 if_refresh (ifp);
1152
1153 /* Some addresses (in particular, IPv6 addresses on Linux) get
1154 * removed when the interface goes down. They need to be readded.
1155 */
1156 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001157 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001158
paul718e3742002-12-13 20:15:29 +00001159 if_data = ifp->info;
1160 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1161
1162 return CMD_SUCCESS;
1163}
1164
1165DEFUN (bandwidth_if,
1166 bandwidth_if_cmd,
1167 "bandwidth <1-10000000>",
1168 "Set bandwidth informational parameter\n"
1169 "Bandwidth in kilobits\n")
1170{
1171 struct interface *ifp;
1172 unsigned int bandwidth;
1173
1174 ifp = (struct interface *) vty->index;
1175 bandwidth = strtol(argv[0], NULL, 10);
1176
1177 /* bandwidth range is <1-10000000> */
1178 if (bandwidth < 1 || bandwidth > 10000000)
1179 {
1180 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1181 return CMD_WARNING;
1182 }
1183
1184 ifp->bandwidth = bandwidth;
1185
1186 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001187 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001188 zebra_interface_up_update (ifp);
1189
1190 return CMD_SUCCESS;
1191}
1192
1193DEFUN (no_bandwidth_if,
1194 no_bandwidth_if_cmd,
1195 "no bandwidth",
1196 NO_STR
1197 "Set bandwidth informational parameter\n")
1198{
1199 struct interface *ifp;
1200
1201 ifp = (struct interface *) vty->index;
1202
1203 ifp->bandwidth = 0;
1204
1205 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001206 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001207 zebra_interface_up_update (ifp);
1208
1209 return CMD_SUCCESS;
1210}
1211
1212ALIAS (no_bandwidth_if,
1213 no_bandwidth_if_val_cmd,
1214 "no bandwidth <1-10000000>",
1215 NO_STR
1216 "Set bandwidth informational parameter\n"
1217 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001218
paula1ac18c2005-06-28 17:17:12 +00001219static int
hasso39db97e2004-10-12 20:50:58 +00001220ip_address_install (struct vty *vty, struct interface *ifp,
1221 const char *addr_str, const char *peer_str,
1222 const char *label)
paul718e3742002-12-13 20:15:29 +00001223{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001224 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001225 struct prefix_ipv4 cp;
1226 struct connected *ifc;
1227 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001228 int ret;
1229
Christian Frankebfac8dc2013-01-24 14:04:50 +00001230 if_data = ifp->info;
1231
paul718e3742002-12-13 20:15:29 +00001232 ret = str2prefix_ipv4 (addr_str, &cp);
1233 if (ret <= 0)
1234 {
1235 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1236 return CMD_WARNING;
1237 }
1238
paulca162182005-09-12 16:58:52 +00001239 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001240 if (! ifc)
1241 {
1242 ifc = connected_new ();
1243 ifc->ifp = ifp;
1244
1245 /* Address. */
1246 p = prefix_ipv4_new ();
1247 *p = cp;
1248 ifc->address = (struct prefix *) p;
1249
1250 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001251 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001252 {
1253 p = prefix_ipv4_new ();
1254 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001255 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001256 ifc->destination = (struct prefix *) p;
1257 }
1258
paul718e3742002-12-13 20:15:29 +00001259 /* Label. */
1260 if (label)
paul0752ef02005-11-03 12:35:21 +00001261 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001262
1263 /* Add to linked list. */
1264 listnode_add (ifp->connected, ifc);
1265 }
1266
1267 /* This address is configured from zebra. */
1268 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1269 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1270
1271 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001272 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001273 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1274 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001275 {
1276 /* Some system need to up the interface to set IP address. */
1277 if (! if_is_up (ifp))
1278 {
1279 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1280 if_refresh (ifp);
1281 }
1282
1283 ret = if_set_prefix (ifp, ifc);
1284 if (ret < 0)
1285 {
1286 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001287 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001288 return CMD_WARNING;
1289 }
1290
Christian Frankef7f740f2013-01-24 14:04:48 +00001291 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001292 /* The address will be advertised to zebra clients when the notification
1293 * from the kernel has been received.
1294 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001295 }
1296
1297 return CMD_SUCCESS;
1298}
1299
paula1ac18c2005-06-28 17:17:12 +00001300static int
hasso39db97e2004-10-12 20:50:58 +00001301ip_address_uninstall (struct vty *vty, struct interface *ifp,
1302 const char *addr_str, const char *peer_str,
1303 const char *label)
paul718e3742002-12-13 20:15:29 +00001304{
1305 struct prefix_ipv4 cp;
1306 struct connected *ifc;
1307 int ret;
1308
1309 /* Convert to prefix structure. */
1310 ret = str2prefix_ipv4 (addr_str, &cp);
1311 if (ret <= 0)
1312 {
1313 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1314 return CMD_WARNING;
1315 }
1316
1317 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001318 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001319 if (! ifc)
1320 {
1321 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1322 return CMD_WARNING;
1323 }
1324
1325 /* This is not configured address. */
1326 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1327 return CMD_WARNING;
1328
Paul Jakma74ecdc92006-06-15 18:10:47 +00001329 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1330
paul718e3742002-12-13 20:15:29 +00001331 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001332 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001333 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1334 {
1335 listnode_delete (ifp->connected, ifc);
1336 connected_free (ifc);
1337 return CMD_WARNING;
1338 }
1339
1340 /* This is real route. */
1341 ret = if_unset_prefix (ifp, ifc);
1342 if (ret < 0)
1343 {
1344 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001345 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001346 return CMD_WARNING;
1347 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001348 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001349 /* we will receive a kernel notification about this route being removed.
1350 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001351 return CMD_SUCCESS;
1352}
1353
1354DEFUN (ip_address,
1355 ip_address_cmd,
1356 "ip address A.B.C.D/M",
1357 "Interface Internet Protocol config commands\n"
1358 "Set the IP address of an interface\n"
1359 "IP address (e.g. 10.0.0.1/8)\n")
1360{
hassoeef1fe12004-10-03 18:46:08 +00001361 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001362}
1363
1364DEFUN (no_ip_address,
1365 no_ip_address_cmd,
1366 "no ip address A.B.C.D/M",
1367 NO_STR
1368 "Interface Internet Protocol config commands\n"
1369 "Set the IP address of an interface\n"
1370 "IP Address (e.g. 10.0.0.1/8)")
1371{
hassoeef1fe12004-10-03 18:46:08 +00001372 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001373}
1374
1375#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001376DEFUN (ip_address_label,
1377 ip_address_label_cmd,
1378 "ip address A.B.C.D/M label LINE",
1379 "Interface Internet Protocol config commands\n"
1380 "Set the IP address of an interface\n"
1381 "IP address (e.g. 10.0.0.1/8)\n"
1382 "Label of this address\n"
1383 "Label\n")
1384{
hassoeef1fe12004-10-03 18:46:08 +00001385 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001386}
1387
1388DEFUN (no_ip_address_label,
1389 no_ip_address_label_cmd,
1390 "no ip address A.B.C.D/M label LINE",
1391 NO_STR
1392 "Interface Internet Protocol config commands\n"
1393 "Set the IP address of an interface\n"
1394 "IP address (e.g. 10.0.0.1/8)\n"
1395 "Label of this address\n"
1396 "Label\n")
1397{
hassoeef1fe12004-10-03 18:46:08 +00001398 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001399}
1400#endif /* HAVE_NETLINK */
1401
1402#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001403static int
hasso39db97e2004-10-12 20:50:58 +00001404ipv6_address_install (struct vty *vty, struct interface *ifp,
1405 const char *addr_str, const char *peer_str,
1406 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001407{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001408 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001409 struct prefix_ipv6 cp;
1410 struct connected *ifc;
1411 struct prefix_ipv6 *p;
1412 int ret;
1413
Christian Frankebfac8dc2013-01-24 14:04:50 +00001414 if_data = ifp->info;
1415
paul718e3742002-12-13 20:15:29 +00001416 ret = str2prefix_ipv6 (addr_str, &cp);
1417 if (ret <= 0)
1418 {
1419 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1420 return CMD_WARNING;
1421 }
1422
paulca162182005-09-12 16:58:52 +00001423 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001424 if (! ifc)
1425 {
1426 ifc = connected_new ();
1427 ifc->ifp = ifp;
1428
1429 /* Address. */
1430 p = prefix_ipv6_new ();
1431 *p = cp;
1432 ifc->address = (struct prefix *) p;
1433
1434 /* Secondary. */
1435 if (secondary)
1436 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1437
1438 /* Label. */
1439 if (label)
paul0752ef02005-11-03 12:35:21 +00001440 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001441
1442 /* Add to linked list. */
1443 listnode_add (ifp->connected, ifc);
1444 }
1445
1446 /* This address is configured from zebra. */
1447 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1448 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1449
1450 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001451 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001452 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1453 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001454 {
1455 /* Some system need to up the interface to set IP address. */
1456 if (! if_is_up (ifp))
1457 {
1458 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1459 if_refresh (ifp);
1460 }
1461
1462 ret = if_prefix_add_ipv6 (ifp, ifc);
1463
1464 if (ret < 0)
1465 {
1466 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001467 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001468 return CMD_WARNING;
1469 }
1470
Christian Frankef7f740f2013-01-24 14:04:48 +00001471 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001472 /* The address will be advertised to zebra clients when the notification
1473 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001474 }
1475
1476 return CMD_SUCCESS;
1477}
1478
paula1ac18c2005-06-28 17:17:12 +00001479static int
hasso39db97e2004-10-12 20:50:58 +00001480ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1481 const char *addr_str, const char *peer_str,
1482 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001483{
1484 struct prefix_ipv6 cp;
1485 struct connected *ifc;
1486 int ret;
1487
1488 /* Convert to prefix structure. */
1489 ret = str2prefix_ipv6 (addr_str, &cp);
1490 if (ret <= 0)
1491 {
1492 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1493 return CMD_WARNING;
1494 }
1495
1496 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001497 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001498 if (! ifc)
1499 {
1500 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1501 return CMD_WARNING;
1502 }
1503
1504 /* This is not configured address. */
1505 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1506 return CMD_WARNING;
1507
Christian Franke676e1a02013-01-24 14:04:45 +00001508 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1509
paul718e3742002-12-13 20:15:29 +00001510 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001511 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001512 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1513 {
1514 listnode_delete (ifp->connected, ifc);
1515 connected_free (ifc);
1516 return CMD_WARNING;
1517 }
1518
1519 /* This is real route. */
1520 ret = if_prefix_delete_ipv6 (ifp, ifc);
1521 if (ret < 0)
1522 {
1523 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001524 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001525 return CMD_WARNING;
1526 }
1527
Christian Frankef7f740f2013-01-24 14:04:48 +00001528 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001529 /* This information will be propagated to the zclients when the
1530 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001531 return CMD_SUCCESS;
1532}
1533
1534DEFUN (ipv6_address,
1535 ipv6_address_cmd,
1536 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001537 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001538 "Set the IP address of an interface\n"
1539 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1540{
1541 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1542}
1543
1544DEFUN (no_ipv6_address,
1545 no_ipv6_address_cmd,
1546 "no ipv6 address X:X::X:X/M",
1547 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001548 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001549 "Set the IP address of an interface\n"
1550 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1551{
1552 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1553}
1554#endif /* HAVE_IPV6 */
1555
paula1ac18c2005-06-28 17:17:12 +00001556static int
paul718e3742002-12-13 20:15:29 +00001557if_config_write (struct vty *vty)
1558{
hasso52dc7ee2004-09-23 19:18:23 +00001559 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001560 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001561
paul1eb8ef22005-04-07 07:30:20 +00001562 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001563 {
1564 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001565 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001566 struct connected *ifc;
1567 struct prefix *p;
1568
paul718e3742002-12-13 20:15:29 +00001569 if_data = ifp->info;
1570
1571 vty_out (vty, "interface %s%s", ifp->name,
1572 VTY_NEWLINE);
1573
Christian Frankebfac8dc2013-01-24 14:04:50 +00001574 if (if_data)
1575 {
1576 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1577 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1578 }
1579
paul718e3742002-12-13 20:15:29 +00001580 if (ifp->desc)
1581 vty_out (vty, " description %s%s", ifp->desc,
1582 VTY_NEWLINE);
1583
1584 /* Assign bandwidth here to avoid unnecessary interface flap
1585 while processing config script */
1586 if (ifp->bandwidth != 0)
1587 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1588
paul2e3b2e42002-12-13 21:03:13 +00001589 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1590 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001591 else
1592 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001593
paul1eb8ef22005-04-07 07:30:20 +00001594 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001595 {
paul718e3742002-12-13 20:15:29 +00001596 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1597 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001598 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001599 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001600 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001601 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001602 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001603
paul718e3742002-12-13 20:15:29 +00001604 if (ifc->label)
1605 vty_out (vty, " label %s", ifc->label);
1606
1607 vty_out (vty, "%s", VTY_NEWLINE);
1608 }
1609 }
1610
1611 if (if_data)
1612 {
paul718e3742002-12-13 20:15:29 +00001613 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1614 vty_out (vty, " %smulticast%s",
1615 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1616 VTY_NEWLINE);
1617 }
1618
1619#ifdef RTADV
1620 rtadv_config_write (vty, ifp);
1621#endif /* RTADV */
1622
hassoca776982004-06-12 14:33:05 +00001623#ifdef HAVE_IRDP
1624 irdp_config_write (vty, ifp);
1625#endif /* IRDP */
1626
paul718e3742002-12-13 20:15:29 +00001627 vty_out (vty, "!%s", VTY_NEWLINE);
1628 }
1629 return 0;
1630}
1631
1632/* Allocate and initialize interface vector. */
1633void
paula1ac18c2005-06-28 17:17:12 +00001634zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001635{
1636 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001637 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1638 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1639
1640 /* Install configuration write function. */
1641 install_node (&interface_node, if_config_write);
1642
1643 install_element (VIEW_NODE, &show_interface_cmd);
1644 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001645 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001646 install_element (CONFIG_NODE, &zebra_interface_cmd);
paulbfc13532003-05-24 06:40:04 +00001647 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00001648 install_default (INTERFACE_NODE);
1649 install_element (INTERFACE_NODE, &interface_desc_cmd);
1650 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1651 install_element (INTERFACE_NODE, &multicast_cmd);
1652 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001653 install_element (INTERFACE_NODE, &linkdetect_cmd);
1654 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001655 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1656 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1657 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1658 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1659 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1660 install_element (INTERFACE_NODE, &ip_address_cmd);
1661 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1662#ifdef HAVE_IPV6
1663 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1664 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1665#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001666#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001667 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001668 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001669#endif /* HAVE_NETLINK */
1670}