blob: 527893be1fcfd80c858ba2142898c8f90ab4a7f7 [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"
Feng Lu471ea392015-05-22 11:40:00 +020035#include "vrf.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "zebra/interface.h"
38#include "zebra/rtadv.h"
39#include "zebra/rib.h"
40#include "zebra/zserv.h"
41#include "zebra/redistribute.h"
42#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000043#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000044
Chris Caputob60668d2009-05-03 04:40:57 +000045#ifdef RTADV
46/* Order is intentional. Matches RFC4191. This array is also used for
47 command matching, so only modify with care. */
48const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
49#endif /* RTADV */
paul718e3742002-12-13 20:15:29 +000050
51/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000052static int
paul718e3742002-12-13 20:15:29 +000053if_zebra_new_hook (struct interface *ifp)
54{
55 struct zebra_if *zebra_if;
56
Stephen Hemminger393deb92008-08-18 14:13:29 -070057 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +000058
59 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
Christian Frankebfac8dc2013-01-24 14:04:50 +000060 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
paul718e3742002-12-13 20:15:29 +000061
62#ifdef RTADV
63 {
64 /* Set default router advertise values. */
65 struct rtadvconf *rtadv;
66
67 rtadv = &zebra_if->rtadv;
68
69 rtadv->AdvSendAdvertisements = 0;
70 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
71 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
72 rtadv->AdvIntervalTimer = 0;
73 rtadv->AdvManagedFlag = 0;
74 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +000075 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +000076 rtadv->AdvLinkMTU = 0;
77 rtadv->AdvReachableTime = 0;
78 rtadv->AdvRetransTimer = 0;
79 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040080 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +000081 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +040082 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +000083 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +000084 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +000085
86 rtadv->AdvPrefixList = list_new ();
87 }
88#endif /* RTADV */
89
hassoeef1fe12004-10-03 18:46:08 +000090 /* Initialize installed address chains tree. */
91 zebra_if->ipv4_subnets = route_table_init ();
92
paul718e3742002-12-13 20:15:29 +000093 ifp->info = zebra_if;
94 return 0;
95}
96
97/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +000098static int
paul718e3742002-12-13 20:15:29 +000099if_zebra_delete_hook (struct interface *ifp)
100{
hassoeef1fe12004-10-03 18:46:08 +0000101 struct zebra_if *zebra_if;
102
paul718e3742002-12-13 20:15:29 +0000103 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000104 {
105 zebra_if = ifp->info;
106
107 /* Free installed address chains tree. */
108 if (zebra_if->ipv4_subnets)
109 route_table_finish (zebra_if->ipv4_subnets);
110
111 XFREE (MTYPE_TMP, zebra_if);
112 }
113
114 return 0;
115}
116
117/* Tie an interface address to its derived subnet list of addresses. */
118int
119if_subnet_add (struct interface *ifp, struct connected *ifc)
120{
121 struct route_node *rn;
122 struct zebra_if *zebra_if;
123 struct prefix cp;
124 struct list *addr_list;
125
126 assert (ifp && ifp->info && ifc);
127 zebra_if = ifp->info;
128
129 /* Get address derived subnet node and associated address list, while marking
130 address secondary attribute appropriately. */
131 cp = *ifc->address;
132 apply_mask (&cp);
133 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
134
135 if ((addr_list = rn->info))
136 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
137 else
138 {
139 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
140 rn->info = addr_list = list_new ();
141 route_lock_node (rn);
142 }
143
144 /* Tie address at the tail of address list. */
145 listnode_add (addr_list, ifc);
146
147 /* Return list element count. */
148 return (addr_list->count);
149}
150
151/* Untie an interface address from its derived subnet list of addresses. */
152int
153if_subnet_delete (struct interface *ifp, struct connected *ifc)
154{
155 struct route_node *rn;
156 struct zebra_if *zebra_if;
157 struct list *addr_list;
158
159 assert (ifp && ifp->info && ifc);
160 zebra_if = ifp->info;
161
162 /* Get address derived subnet node. */
163 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
164 if (! (rn && rn->info))
Christian Franke9db047f2013-01-24 14:04:44 +0000165 {
166 zlog_warn("Trying to remove an address from an unknown subnet."
167 " (please report this bug)");
168 return -1;
169 }
hassoeef1fe12004-10-03 18:46:08 +0000170 route_unlock_node (rn);
171
172 /* Untie address from subnet's address list. */
173 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000174
175 /* Deleting an address that is not registered is a bug.
176 * In any case, we shouldn't decrement the lock counter if the address
177 * is unknown. */
178 if (!listnode_lookup(addr_list, ifc))
179 {
180 zlog_warn("Trying to remove an address from a subnet where it is not"
181 " currently registered. (please report this bug)");
182 return -1;
183 }
184
hassoeef1fe12004-10-03 18:46:08 +0000185 listnode_delete (addr_list, ifc);
186 route_unlock_node (rn);
187
188 /* Return list element count, if not empty. */
189 if (addr_list->count)
190 {
191 /* If deleted address is primary, mark subsequent one as such and distribute. */
192 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
193 {
paul1eb8ef22005-04-07 07:30:20 +0000194 ifc = listgetdata (listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000195 zebra_interface_address_delete_update (ifp, ifc);
196 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
Christian Franke02b48052013-01-24 14:04:49 +0000197 /* XXX: Linux kernel removes all the secondary addresses when the primary
198 * address is removed. We could try to work around that, though this is
199 * non-trivial. */
hassoeef1fe12004-10-03 18:46:08 +0000200 zebra_interface_address_add_update (ifp, ifc);
201 }
202
203 return addr_list->count;
204 }
205
206 /* Otherwise, free list and route node. */
207 list_free (addr_list);
208 rn->info = NULL;
209 route_unlock_node (rn);
210
paul718e3742002-12-13 20:15:29 +0000211 return 0;
212}
213
paul5c78b3d2006-01-25 04:31:40 +0000214/* if_flags_mangle: A place for hacks that require mangling
215 * or tweaking the interface flags.
216 *
217 * ******************** Solaris flags hacks **************************
218 *
219 * Solaris IFF_UP flag reflects only the primary interface as the
220 * routing socket only sends IFINFO for the primary interface. Hence
221 * ~IFF_UP does not per se imply all the logical interfaces are also
222 * down - which we only know of as addresses. Instead we must determine
223 * whether the interface really is up or not according to how many
224 * addresses are still attached. (Solaris always sends RTM_DELADDR if
225 * an interface, logical or not, goes ~IFF_UP).
226 *
227 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
228 * are addresses left in struct connected, not just the actual underlying
229 * IFF_UP flag.
230 *
231 * We must hence remember the real state of IFF_UP, which we do in
232 * struct zebra_if.primary_state.
233 *
234 * Setting IFF_UP within zebra to administratively shutdown the
235 * interface will affect only the primary interface/address on Solaris.
236 ************************End Solaris flags hacks ***********************
237 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100238static void
paul5c78b3d2006-01-25 04:31:40 +0000239if_flags_mangle (struct interface *ifp, uint64_t *newflags)
240{
241#ifdef SUNOS_5
242 struct zebra_if *zif = ifp->info;
243
244 zif->primary_state = *newflags & (IFF_UP & 0xff);
245
246 if (CHECK_FLAG (zif->primary_state, IFF_UP)
247 || listcount(ifp->connected) > 0)
248 SET_FLAG (*newflags, IFF_UP);
249 else
250 UNSET_FLAG (*newflags, IFF_UP);
251#endif /* SUNOS_5 */
252}
253
254/* Update the flags field of the ifp with the new flag set provided.
255 * Take whatever actions are required for any changes in flags we care
256 * about.
257 *
258 * newflags should be the raw value, as obtained from the OS.
259 */
260void
261if_flags_update (struct interface *ifp, uint64_t newflags)
262{
263 if_flags_mangle (ifp, &newflags);
264
265 if (if_is_operative (ifp))
266 {
267 /* operative -> inoperative? */
268 ifp->flags = newflags;
269 if (!if_is_operative (ifp))
270 if_down (ifp);
271 }
272 else
273 {
274 /* inoperative -> operative? */
275 ifp->flags = newflags;
276 if (if_is_operative (ifp))
277 if_up (ifp);
278 }
279}
280
paul718e3742002-12-13 20:15:29 +0000281/* Wake up configured address if it is not in current kernel
282 address. */
paula1ac18c2005-06-28 17:17:12 +0000283static void
paul718e3742002-12-13 20:15:29 +0000284if_addr_wakeup (struct interface *ifp)
285{
paul1eb8ef22005-04-07 07:30:20 +0000286 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000287 struct connected *ifc;
288 struct prefix *p;
289 int ret;
290
paul1eb8ef22005-04-07 07:30:20 +0000291 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000292 {
paul718e3742002-12-13 20:15:29 +0000293 p = ifc->address;
294
295 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000296 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000297 {
298 /* Address check. */
299 if (p->family == AF_INET)
300 {
301 if (! if_is_up (ifp))
302 {
Christian Franke02b48052013-01-24 14:04:49 +0000303 /* Assume zebra is configured like following:
304 *
305 * interface gre0
306 * ip addr 192.0.2.1/24
307 * !
308 *
309 * As soon as zebra becomes first aware that gre0 exists in the
310 * kernel, it will set gre0 up and configure its addresses.
311 *
312 * (This may happen at startup when the interface already exists
313 * or during runtime when the interface is added to the kernel)
314 *
315 * XXX: IRDP code is calling here via if_add_update - this seems
316 * somewhat weird.
317 * XXX: RUNNING is not a settable flag on any system
318 * I (paulj) am aware of.
319 */
paul718e3742002-12-13 20:15:29 +0000320 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
321 if_refresh (ifp);
322 }
323
324 ret = if_set_prefix (ifp, ifc);
325 if (ret < 0)
326 {
327 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000328 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000329 continue;
330 }
hassoeef1fe12004-10-03 18:46:08 +0000331
Christian Frankef7f740f2013-01-24 14:04:48 +0000332 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000333 /* The address will be advertised to zebra clients when the notification
334 * from the kernel has been received.
335 * It will also be added to the interface's subnet list then. */
paul718e3742002-12-13 20:15:29 +0000336 }
337#ifdef HAVE_IPV6
338 if (p->family == AF_INET6)
339 {
340 if (! if_is_up (ifp))
341 {
Christian Franke02b48052013-01-24 14:04:49 +0000342 /* See long comment above */
paul718e3742002-12-13 20:15:29 +0000343 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
344 if_refresh (ifp);
345 }
346
347 ret = if_prefix_add_ipv6 (ifp, ifc);
348 if (ret < 0)
349 {
350 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000351 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000352 continue;
353 }
Christian Franke02b48052013-01-24 14:04:49 +0000354
Christian Frankef7f740f2013-01-24 14:04:48 +0000355 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000356 /* The address will be advertised to zebra clients when the notification
357 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +0000358 }
359#endif /* HAVE_IPV6 */
360 }
361 }
362}
363
364/* Handle interface addition */
365void
366if_add_update (struct interface *ifp)
367{
paul48b33aa2002-12-13 20:52:52 +0000368 struct zebra_if *if_data;
369
370 if_data = ifp->info;
371 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
372 if_set_flags (ifp, IFF_MULTICAST);
373 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
374 if_unset_flags (ifp, IFF_MULTICAST);
375
paul718e3742002-12-13 20:15:29 +0000376 zebra_interface_add_update (ifp);
377
378 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
379 {
380 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
381
Christian Frankebfac8dc2013-01-24 14:04:50 +0000382 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
383 {
384 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200385 zlog_debug ("interface %s vrf %u index %d is shutdown. "
386 "Won't wake it up.",
387 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000388 return;
389 }
390
paul718e3742002-12-13 20:15:29 +0000391 if_addr_wakeup (ifp);
392
393 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200394 zlog_debug ("interface %s vrf %u index %d becomes active.",
395 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000396 }
397 else
398 {
399 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200400 zlog_debug ("interface %s vrf %u index %d is added.",
401 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000402 }
403}
404
paul6eb88272005-07-29 14:36:00 +0000405/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000406void
407if_delete_update (struct interface *ifp)
408{
paul718e3742002-12-13 20:15:29 +0000409 struct connected *ifc;
410 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000411 struct route_node *rn;
412 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000413
414 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000415
416 if (if_is_up(ifp))
417 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200418 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
419 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000420 return;
421 }
422
423 /* Mark interface as inactive */
424 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
425
426 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200427 zlog_debug ("interface %s vrf %u index %d is now inactive.",
428 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000429
430 /* Delete connected routes from the kernel. */
431 if (ifp->connected)
432 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000433 struct listnode *node;
434 struct listnode *last = NULL;
435
hassoeef1fe12004-10-03 18:46:08 +0000436 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000437 {
paul1eb8ef22005-04-07 07:30:20 +0000438 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000439 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000440
Paul Jakmabeb56332006-05-11 13:28:05 +0000441 if (p->family == AF_INET
442 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000443 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000444 struct listnode *anode;
445 struct listnode *next;
446 struct listnode *first;
447 struct list *addr_list;
448
hassoeef1fe12004-10-03 18:46:08 +0000449 route_unlock_node (rn);
450 addr_list = (struct list *) rn->info;
451
452 /* Remove addresses, secondaries first. */
453 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000454 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000455 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000456 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000457 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000458 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000459 first = NULL;
460 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000461 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000462
Paul Jakmad9a18f12007-04-10 19:30:20 +0000463 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000464 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000465 connected_down_ipv4 (ifp, ifc);
466
Christian Franke02b48052013-01-24 14:04:49 +0000467 /* XXX: We have to send notifications here explicitly, because we destroy
468 * the ifc before receiving the notification about the address being deleted.
469 */
hassoeef1fe12004-10-03 18:46:08 +0000470 zebra_interface_address_delete_update (ifp, ifc);
471
472 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000473 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000474
475 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000476 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000477 route_unlock_node (rn);
478
479 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000480 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
481 {
482 listnode_delete (ifp->connected, ifc);
483 connected_free (ifc);
484 }
485 else
486 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000487 }
488
489 /* Free chain list and respective route node. */
490 list_delete (addr_list);
491 rn->info = NULL;
492 route_unlock_node (rn);
493 }
paul718e3742002-12-13 20:15:29 +0000494#ifdef HAVE_IPV6
495 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000496 {
497 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000498
hassoeef1fe12004-10-03 18:46:08 +0000499 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000500
hassoeef1fe12004-10-03 18:46:08 +0000501 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000502 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000503
504 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
505 last = node;
506 else
507 {
508 listnode_delete (ifp->connected, ifc);
509 connected_free (ifc);
510 }
paul718e3742002-12-13 20:15:29 +0000511 }
hassoeef1fe12004-10-03 18:46:08 +0000512#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200513 else
514 {
515 last = node;
516 }
paul718e3742002-12-13 20:15:29 +0000517 }
518 }
519 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000520
521 /* Update ifindex after distributing the delete message. This is in
522 case any client needs to have the old value of ifindex available
523 while processing the deletion. Each client daemon is responsible
524 for setting ifindex to IFINDEX_INTERNAL after processing the
525 interface deletion message. */
526 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000527}
528
529/* Interface is up. */
530void
531if_up (struct interface *ifp)
532{
hasso52dc7ee2004-09-23 19:18:23 +0000533 struct listnode *node;
534 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000535 struct connected *ifc;
536 struct prefix *p;
537
538 /* Notify the protocol daemons. */
539 zebra_interface_up_update (ifp);
540
541 /* Install connected routes to the kernel. */
542 if (ifp->connected)
543 {
paul1eb8ef22005-04-07 07:30:20 +0000544 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000545 {
paul718e3742002-12-13 20:15:29 +0000546 p = ifc->address;
547
548 if (p->family == AF_INET)
549 connected_up_ipv4 (ifp, ifc);
550#ifdef HAVE_IPV6
551 else if (p->family == AF_INET6)
552 connected_up_ipv6 (ifp, ifc);
553#endif /* HAVE_IPV6 */
554 }
555 }
556
557 /* Examine all static routes. */
558 rib_update ();
559}
560
561/* Interface goes down. We have to manage different behavior of based
562 OS. */
563void
564if_down (struct interface *ifp)
565{
hasso52dc7ee2004-09-23 19:18:23 +0000566 struct listnode *node;
567 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000568 struct connected *ifc;
569 struct prefix *p;
570
571 /* Notify to the protocol daemons. */
572 zebra_interface_down_update (ifp);
573
574 /* Delete connected routes from the kernel. */
575 if (ifp->connected)
576 {
paul1eb8ef22005-04-07 07:30:20 +0000577 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000578 {
paul718e3742002-12-13 20:15:29 +0000579 p = ifc->address;
580
581 if (p->family == AF_INET)
582 connected_down_ipv4 (ifp, ifc);
583#ifdef HAVE_IPV6
584 else if (p->family == AF_INET6)
585 connected_down_ipv6 (ifp, ifc);
586#endif /* HAVE_IPV6 */
587 }
588 }
589
590 /* Examine all static routes which direct to the interface. */
591 rib_update ();
592}
593
594void
595if_refresh (struct interface *ifp)
596{
paul5c78b3d2006-01-25 04:31:40 +0000597 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000598}
599
paul718e3742002-12-13 20:15:29 +0000600/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000601static int
paul718e3742002-12-13 20:15:29 +0000602prefix_vty_out (struct vty *vty, struct prefix *p)
603{
604 char str[INET6_ADDRSTRLEN];
605
606 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
607 vty_out (vty, "%s", str);
608 return strlen (str);
609}
610
611/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000612static void
paul718e3742002-12-13 20:15:29 +0000613connected_dump_vty (struct vty *vty, struct connected *connected)
614{
615 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000616
617 /* Print interface address. */
618 p = connected->address;
619 vty_out (vty, " %s ", prefix_family_str (p));
620 prefix_vty_out (vty, p);
621 vty_out (vty, "/%d", p->prefixlen);
622
623 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000624 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000625 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000626 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
627 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000628 }
629
630 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
631 vty_out (vty, " secondary");
632
633 if (connected->label)
634 vty_out (vty, " %s", connected->label);
635
636 vty_out (vty, "%s", VTY_NEWLINE);
637}
638
639#ifdef RTADV
640/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000641static void
paul718e3742002-12-13 20:15:29 +0000642nd_dump_vty (struct vty *vty, struct interface *ifp)
643{
644 struct zebra_if *zif;
645 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000646 int interval;
paul718e3742002-12-13 20:15:29 +0000647
648 zif = (struct zebra_if *) ifp->info;
649 rtadv = &zif->rtadv;
650
651 if (rtadv->AdvSendAdvertisements)
652 {
653 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
654 rtadv->AdvReachableTime, VTY_NEWLINE);
655 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
656 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000657 interval = rtadv->MaxRtrAdvInterval;
658 if (interval % 1000)
659 vty_out (vty, " ND router advertisements are sent every "
660 "%d milliseconds%s", interval,
661 VTY_NEWLINE);
662 else
663 vty_out (vty, " ND router advertisements are sent every "
664 "%d seconds%s", interval / 1000,
665 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400666 if (rtadv->AdvDefaultLifetime != -1)
667 vty_out (vty, " ND router advertisements live for %d seconds%s",
668 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
669 else
670 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
671 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000672 vty_out (vty, " ND router advertisement default router preference is "
673 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
674 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000675 if (rtadv->AdvManagedFlag)
676 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
677 VTY_NEWLINE);
678 else
679 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
680 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000681 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400682 {
vincent7cee1bb2005-03-25 13:08:53 +0000683 vty_out (vty, " ND router advertisements with "
684 "Home Agent flag bit set.%s",
685 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400686 if (rtadv->HomeAgentLifetime != -1)
687 vty_out (vty, " Home Agent lifetime is %u seconds%s",
688 rtadv->HomeAgentLifetime, VTY_NEWLINE);
689 else
690 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
691 VTY_NEWLINE);
692 vty_out (vty, " Home Agent preference is %u%s",
693 rtadv->HomeAgentPreference, VTY_NEWLINE);
694 }
vincent7cee1bb2005-03-25 13:08:53 +0000695 if (rtadv->AdvIntervalOption)
696 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
697 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000698 }
699}
700#endif /* RTADV */
701
702/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000703static void
paul718e3742002-12-13 20:15:29 +0000704if_dump_vty (struct vty *vty, struct interface *ifp)
705{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000706#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000707 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000708#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000709 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000710 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000711 struct route_node *rn;
712 struct zebra_if *zebra_if;
713
714 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000715
paul2e3b2e42002-12-13 21:03:13 +0000716 vty_out (vty, "Interface %s is ", ifp->name);
717 if (if_is_up(ifp)) {
718 vty_out (vty, "up, line protocol ");
719
720 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
721 if (if_is_running(ifp))
722 vty_out (vty, "is up%s", VTY_NEWLINE);
723 else
724 vty_out (vty, "is down%s", VTY_NEWLINE);
725 } else {
726 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
727 }
728 } else {
729 vty_out (vty, "down%s", VTY_NEWLINE);
730 }
731
Feng Lu2fc97f62015-05-22 11:39:57 +0200732 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
733
paul718e3742002-12-13 20:15:29 +0000734 if (ifp->desc)
735 vty_out (vty, " Description: %s%s", ifp->desc,
736 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000737 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000738 {
ajsd2fc8892005-04-02 18:38:43 +0000739 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000740 return;
741 }
742 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
743 {
744 vty_out(vty, " index %d inactive interface%s",
745 ifp->ifindex,
746 VTY_NEWLINE);
747 return;
748 }
749
750 vty_out (vty, " index %d metric %d mtu %d ",
751 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000752#ifdef HAVE_IPV6
753 if (ifp->mtu6 != ifp->mtu)
754 vty_out (vty, "mtu6 %d ", ifp->mtu6);
755#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000756 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
757 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000758
paul718e3742002-12-13 20:15:29 +0000759 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000760#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000761 sdl = &ifp->sdl;
762 if (sdl != NULL && sdl->sdl_alen != 0)
763 {
764 int i;
765 u_char *ptr;
766
767 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000768 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
769 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000770 vty_out (vty, "%s", VTY_NEWLINE);
771 }
772#else
773 if (ifp->hw_addr_len != 0)
774 {
775 int i;
776
777 vty_out (vty, " HWaddr: ");
778 for (i = 0; i < ifp->hw_addr_len; i++)
779 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
780 vty_out (vty, "%s", VTY_NEWLINE);
781 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000782#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000783
784 /* Bandwidth in kbps */
785 if (ifp->bandwidth != 0)
786 {
787 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
788 vty_out(vty, "%s", VTY_NEWLINE);
789 }
790
hassoeef1fe12004-10-03 18:46:08 +0000791 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000792 {
hassoeef1fe12004-10-03 18:46:08 +0000793 if (! rn->info)
794 continue;
795
paul1eb8ef22005-04-07 07:30:20 +0000796 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
797 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000798 }
799
paul1eb8ef22005-04-07 07:30:20 +0000800 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000801 {
hasso39db97e2004-10-12 20:50:58 +0000802 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
803 (connected->address->family == AF_INET6))
804 connected_dump_vty (vty, connected);
805 }
806
paul718e3742002-12-13 20:15:29 +0000807#ifdef RTADV
808 nd_dump_vty (vty, ifp);
809#endif /* RTADV */
810
811#ifdef HAVE_PROC_NET_DEV
812 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000813 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
814 "%lu dropped%s",
815 ifp->stats.rx_packets, ifp->stats.rx_multicast,
816 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000817
hasso6f2c27a2005-01-18 13:44:35 +0000818 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000819 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000820 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
821 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000822 ifp->stats.rx_frame_errors, VTY_NEWLINE);
823
824 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000825 ifp->stats.rx_missed_errors, VTY_NEWLINE);
826
hasso6f2c27a2005-01-18 13:44:35 +0000827 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000828 ifp->stats.tx_packets, ifp->stats.tx_bytes,
829 ifp->stats.tx_dropped, VTY_NEWLINE);
830
hasso6f2c27a2005-01-18 13:44:35 +0000831 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
832 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000833 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
834 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000835 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000836
hasso6f2c27a2005-01-18 13:44:35 +0000837 vty_out (vty, " %lu window, %lu collisions%s",
838 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000839#endif /* HAVE_PROC_NET_DEV */
840
841#ifdef HAVE_NET_RT_IFLIST
842#if defined (__bsdi__) || defined (__NetBSD__)
843 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200844 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
845 " multicast packets %llu%s",
846 (unsigned long long)ifp->stats.ifi_ipackets,
847 (unsigned long long)ifp->stats.ifi_ibytes,
848 (unsigned long long)ifp->stats.ifi_iqdrops,
849 (unsigned long long)ifp->stats.ifi_imcasts,
850 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000851
David Lamparter193e78f2015-04-21 10:42:30 +0200852 vty_out (vty, " input errors %llu%s",
853 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000854
David Lamparter193e78f2015-04-21 10:42:30 +0200855 vty_out (vty, " output packets %llu, bytes %llu,"
856 " multicast packets %llu%s",
857 (unsigned long long)ifp->stats.ifi_opackets,
858 (unsigned long long)ifp->stats.ifi_obytes,
859 (unsigned long long)ifp->stats.ifi_omcasts,
860 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000861
David Lamparter193e78f2015-04-21 10:42:30 +0200862 vty_out (vty, " output errors %llu%s",
863 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000864
David Lamparter193e78f2015-04-21 10:42:30 +0200865 vty_out (vty, " collisions %llu%s",
866 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000867#else
868 /* Statistics print out using sysctl (). */
869 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
870 " multicast packets %lu%s",
871 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
872 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
873 VTY_NEWLINE);
874
875 vty_out (vty, " input errors %lu%s",
876 ifp->stats.ifi_ierrors, VTY_NEWLINE);
877
878 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
879 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
880 ifp->stats.ifi_omcasts, VTY_NEWLINE);
881
882 vty_out (vty, " output errors %lu%s",
883 ifp->stats.ifi_oerrors, VTY_NEWLINE);
884
885 vty_out (vty, " collisions %lu%s",
886 ifp->stats.ifi_collisions, VTY_NEWLINE);
887#endif /* __bsdi__ || __NetBSD__ */
888#endif /* HAVE_NET_RT_IFLIST */
889}
890
paul718e3742002-12-13 20:15:29 +0000891/* Wrapper hook point for zebra daemon so that ifindex can be set
892 * DEFUN macro not used as extract.pl HAS to ignore this
893 * See also interface_cmd in lib/if.c
894 */
895DEFUN_NOSH (zebra_interface,
896 zebra_interface_cmd,
897 "interface IFNAME",
898 "Select an interface to configure\n"
899 "Interface's name\n")
900{
901 int ret;
902 struct interface * ifp;
903
904 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000905 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
906 return ret;
paul718e3742002-12-13 20:15:29 +0000907
908 ifp = vty->index;
909
ajsd2fc8892005-04-02 18:38:43 +0000910 if (ifp->ifindex == IFINDEX_INTERNAL)
911 /* Is this really necessary? Shouldn't status be initialized to 0
912 in that case? */
913 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000914
915 return ret;
916}
917
Feng Lu471ea392015-05-22 11:40:00 +0200918ALIAS (zebra_interface,
919 zebra_interface_vrf_cmd,
920 "interface IFNAME " VRF_CMD_STR,
921 "Select an interface to configure\n"
922 "Interface's name\n"
923 VRF_CMD_HELP_STR)
924
paul718e3742002-12-13 20:15:29 +0000925struct cmd_node interface_node =
926{
927 INTERFACE_NODE,
928 "%s(config-if)# ",
929 1
930};
931
932/* Show all or specified interface to vty. */
933DEFUN (show_interface, show_interface_cmd,
934 "show interface [IFNAME]",
935 SHOW_STR
936 "Interface status and configuration\n"
937 "Inteface name\n")
938{
hasso52dc7ee2004-09-23 19:18:23 +0000939 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000940 struct interface *ifp;
941
942#ifdef HAVE_PROC_NET_DEV
943 /* If system has interface statistics via proc file system, update
944 statistics. */
945 ifstat_update_proc ();
946#endif /* HAVE_PROC_NET_DEV */
947#ifdef HAVE_NET_RT_IFLIST
948 ifstat_update_sysctl ();
949#endif /* HAVE_NET_RT_IFLIST */
950
951 /* Specified interface print. */
952 if (argc != 0)
953 {
954 ifp = if_lookup_by_name (argv[0]);
955 if (ifp == NULL)
956 {
957 vty_out (vty, "%% Can't find interface %s%s", argv[0],
958 VTY_NEWLINE);
959 return CMD_WARNING;
960 }
961 if_dump_vty (vty, ifp);
962 return CMD_SUCCESS;
963 }
964
965 /* All interface print. */
paul1eb8ef22005-04-07 07:30:20 +0000966 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
967 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000968
969 return CMD_SUCCESS;
970}
971
hassoed9bb6d2005-03-13 19:17:21 +0000972DEFUN (show_interface_desc,
973 show_interface_desc_cmd,
974 "show interface description",
975 SHOW_STR
976 "Interface status and configuration\n"
977 "Interface description\n")
978{
979 struct listnode *node;
980 struct interface *ifp;
981
982 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000983 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +0000984 {
985 int len;
hassoed9bb6d2005-03-13 19:17:21 +0000986
987 len = vty_out (vty, "%s", ifp->name);
988 vty_out (vty, "%*s", (16 - len), " ");
989
990 if (if_is_up(ifp))
991 {
992 vty_out (vty, "up ");
993 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
994 {
995 if (if_is_running(ifp))
996 vty_out (vty, "up ");
997 else
998 vty_out (vty, "down ");
999 }
1000 else
1001 {
1002 vty_out (vty, "unknown ");
1003 }
1004 }
1005 else
1006 {
1007 vty_out (vty, "down down ");
1008 }
1009
1010 if (ifp->desc)
1011 vty_out (vty, "%s", ifp->desc);
1012 vty_out (vty, "%s", VTY_NEWLINE);
1013 }
1014 return CMD_SUCCESS;
1015}
1016
paul718e3742002-12-13 20:15:29 +00001017DEFUN (multicast,
1018 multicast_cmd,
1019 "multicast",
1020 "Set multicast flag to interface\n")
1021{
1022 int ret;
1023 struct interface *ifp;
1024 struct zebra_if *if_data;
1025
1026 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001027 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001028 {
paul48b33aa2002-12-13 20:52:52 +00001029 ret = if_set_flags (ifp, IFF_MULTICAST);
1030 if (ret < 0)
1031 {
1032 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1033 return CMD_WARNING;
1034 }
1035 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001036 }
paul718e3742002-12-13 20:15:29 +00001037 if_data = ifp->info;
1038 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001039
paul718e3742002-12-13 20:15:29 +00001040 return CMD_SUCCESS;
1041}
1042
1043DEFUN (no_multicast,
1044 no_multicast_cmd,
1045 "no multicast",
1046 NO_STR
1047 "Unset multicast flag to interface\n")
1048{
1049 int ret;
1050 struct interface *ifp;
1051 struct zebra_if *if_data;
1052
1053 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001054 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001055 {
paul48b33aa2002-12-13 20:52:52 +00001056 ret = if_unset_flags (ifp, IFF_MULTICAST);
1057 if (ret < 0)
1058 {
1059 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1060 return CMD_WARNING;
1061 }
1062 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001063 }
paul718e3742002-12-13 20:15:29 +00001064 if_data = ifp->info;
1065 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1066
1067 return CMD_SUCCESS;
1068}
1069
paul2e3b2e42002-12-13 21:03:13 +00001070DEFUN (linkdetect,
1071 linkdetect_cmd,
1072 "link-detect",
1073 "Enable link detection on interface\n")
1074{
paul2e3b2e42002-12-13 21:03:13 +00001075 struct interface *ifp;
1076 int if_was_operative;
1077
1078 ifp = (struct interface *) vty->index;
1079 if_was_operative = if_is_operative(ifp);
1080 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1081
1082 /* When linkdetection is enabled, if might come down */
1083 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1084
1085 /* FIXME: Will defer status change forwarding if interface
1086 does not come down! */
1087
1088 return CMD_SUCCESS;
1089}
1090
1091
1092DEFUN (no_linkdetect,
1093 no_linkdetect_cmd,
1094 "no link-detect",
1095 NO_STR
1096 "Disable link detection on interface\n")
1097{
paul2e3b2e42002-12-13 21:03:13 +00001098 struct interface *ifp;
1099 int if_was_operative;
1100
1101 ifp = (struct interface *) vty->index;
1102 if_was_operative = if_is_operative(ifp);
1103 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1104
1105 /* Interface may come up after disabling link detection */
1106 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1107
1108 /* FIXME: see linkdetect_cmd */
1109
1110 return CMD_SUCCESS;
1111}
1112
paul718e3742002-12-13 20:15:29 +00001113DEFUN (shutdown_if,
1114 shutdown_if_cmd,
1115 "shutdown",
1116 "Shutdown the selected interface\n")
1117{
1118 int ret;
1119 struct interface *ifp;
1120 struct zebra_if *if_data;
1121
1122 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001123 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001124 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001125 ret = if_unset_flags (ifp, IFF_UP);
1126 if (ret < 0)
1127 {
1128 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1129 return CMD_WARNING;
1130 }
1131 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001132 }
paul718e3742002-12-13 20:15:29 +00001133 if_data = ifp->info;
1134 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1135
1136 return CMD_SUCCESS;
1137}
1138
1139DEFUN (no_shutdown_if,
1140 no_shutdown_if_cmd,
1141 "no shutdown",
1142 NO_STR
1143 "Shutdown the selected interface\n")
1144{
1145 int ret;
1146 struct interface *ifp;
1147 struct zebra_if *if_data;
1148
1149 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001150
1151 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001152 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001153 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1154 if (ret < 0)
1155 {
1156 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1157 return CMD_WARNING;
1158 }
1159 if_refresh (ifp);
1160
1161 /* Some addresses (in particular, IPv6 addresses on Linux) get
1162 * removed when the interface goes down. They need to be readded.
1163 */
1164 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001165 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001166
paul718e3742002-12-13 20:15:29 +00001167 if_data = ifp->info;
1168 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1169
1170 return CMD_SUCCESS;
1171}
1172
1173DEFUN (bandwidth_if,
1174 bandwidth_if_cmd,
1175 "bandwidth <1-10000000>",
1176 "Set bandwidth informational parameter\n"
1177 "Bandwidth in kilobits\n")
1178{
1179 struct interface *ifp;
1180 unsigned int bandwidth;
1181
1182 ifp = (struct interface *) vty->index;
1183 bandwidth = strtol(argv[0], NULL, 10);
1184
1185 /* bandwidth range is <1-10000000> */
1186 if (bandwidth < 1 || bandwidth > 10000000)
1187 {
1188 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1189 return CMD_WARNING;
1190 }
1191
1192 ifp->bandwidth = bandwidth;
1193
1194 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001195 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001196 zebra_interface_up_update (ifp);
1197
1198 return CMD_SUCCESS;
1199}
1200
1201DEFUN (no_bandwidth_if,
1202 no_bandwidth_if_cmd,
1203 "no bandwidth",
1204 NO_STR
1205 "Set bandwidth informational parameter\n")
1206{
1207 struct interface *ifp;
1208
1209 ifp = (struct interface *) vty->index;
1210
1211 ifp->bandwidth = 0;
1212
1213 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001214 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001215 zebra_interface_up_update (ifp);
1216
1217 return CMD_SUCCESS;
1218}
1219
1220ALIAS (no_bandwidth_if,
1221 no_bandwidth_if_val_cmd,
1222 "no bandwidth <1-10000000>",
1223 NO_STR
1224 "Set bandwidth informational parameter\n"
1225 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001226
paula1ac18c2005-06-28 17:17:12 +00001227static int
hasso39db97e2004-10-12 20:50:58 +00001228ip_address_install (struct vty *vty, struct interface *ifp,
1229 const char *addr_str, const char *peer_str,
1230 const char *label)
paul718e3742002-12-13 20:15:29 +00001231{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001232 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001233 struct prefix_ipv4 cp;
1234 struct connected *ifc;
1235 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001236 int ret;
1237
Christian Frankebfac8dc2013-01-24 14:04:50 +00001238 if_data = ifp->info;
1239
paul718e3742002-12-13 20:15:29 +00001240 ret = str2prefix_ipv4 (addr_str, &cp);
1241 if (ret <= 0)
1242 {
1243 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1244 return CMD_WARNING;
1245 }
1246
paulca162182005-09-12 16:58:52 +00001247 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001248 if (! ifc)
1249 {
1250 ifc = connected_new ();
1251 ifc->ifp = ifp;
1252
1253 /* Address. */
1254 p = prefix_ipv4_new ();
1255 *p = cp;
1256 ifc->address = (struct prefix *) p;
1257
1258 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001259 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001260 {
1261 p = prefix_ipv4_new ();
1262 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001263 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001264 ifc->destination = (struct prefix *) p;
1265 }
1266
paul718e3742002-12-13 20:15:29 +00001267 /* Label. */
1268 if (label)
paul0752ef02005-11-03 12:35:21 +00001269 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001270
1271 /* Add to linked list. */
1272 listnode_add (ifp->connected, ifc);
1273 }
1274
1275 /* This address is configured from zebra. */
1276 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1277 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1278
1279 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001280 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001281 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1282 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001283 {
1284 /* Some system need to up the interface to set IP address. */
1285 if (! if_is_up (ifp))
1286 {
1287 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1288 if_refresh (ifp);
1289 }
1290
1291 ret = if_set_prefix (ifp, ifc);
1292 if (ret < 0)
1293 {
1294 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001295 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001296 return CMD_WARNING;
1297 }
1298
Christian Frankef7f740f2013-01-24 14:04:48 +00001299 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001300 /* The address will be advertised to zebra clients when the notification
1301 * from the kernel has been received.
1302 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001303 }
1304
1305 return CMD_SUCCESS;
1306}
1307
paula1ac18c2005-06-28 17:17:12 +00001308static int
hasso39db97e2004-10-12 20:50:58 +00001309ip_address_uninstall (struct vty *vty, struct interface *ifp,
1310 const char *addr_str, const char *peer_str,
1311 const char *label)
paul718e3742002-12-13 20:15:29 +00001312{
1313 struct prefix_ipv4 cp;
1314 struct connected *ifc;
1315 int ret;
1316
1317 /* Convert to prefix structure. */
1318 ret = str2prefix_ipv4 (addr_str, &cp);
1319 if (ret <= 0)
1320 {
1321 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1322 return CMD_WARNING;
1323 }
1324
1325 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001326 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001327 if (! ifc)
1328 {
1329 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1330 return CMD_WARNING;
1331 }
1332
1333 /* This is not configured address. */
1334 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1335 return CMD_WARNING;
1336
Paul Jakma74ecdc92006-06-15 18:10:47 +00001337 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1338
paul718e3742002-12-13 20:15:29 +00001339 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001340 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001341 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1342 {
1343 listnode_delete (ifp->connected, ifc);
1344 connected_free (ifc);
1345 return CMD_WARNING;
1346 }
1347
1348 /* This is real route. */
1349 ret = if_unset_prefix (ifp, ifc);
1350 if (ret < 0)
1351 {
1352 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001353 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001354 return CMD_WARNING;
1355 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001356 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001357 /* we will receive a kernel notification about this route being removed.
1358 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001359 return CMD_SUCCESS;
1360}
1361
1362DEFUN (ip_address,
1363 ip_address_cmd,
1364 "ip address A.B.C.D/M",
1365 "Interface Internet Protocol config commands\n"
1366 "Set the IP address of an interface\n"
1367 "IP address (e.g. 10.0.0.1/8)\n")
1368{
hassoeef1fe12004-10-03 18:46:08 +00001369 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001370}
1371
1372DEFUN (no_ip_address,
1373 no_ip_address_cmd,
1374 "no ip address A.B.C.D/M",
1375 NO_STR
1376 "Interface Internet Protocol config commands\n"
1377 "Set the IP address of an interface\n"
1378 "IP Address (e.g. 10.0.0.1/8)")
1379{
hassoeef1fe12004-10-03 18:46:08 +00001380 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001381}
1382
1383#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001384DEFUN (ip_address_label,
1385 ip_address_label_cmd,
1386 "ip address A.B.C.D/M label LINE",
1387 "Interface Internet Protocol config commands\n"
1388 "Set the IP address of an interface\n"
1389 "IP address (e.g. 10.0.0.1/8)\n"
1390 "Label of this address\n"
1391 "Label\n")
1392{
hassoeef1fe12004-10-03 18:46:08 +00001393 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001394}
1395
1396DEFUN (no_ip_address_label,
1397 no_ip_address_label_cmd,
1398 "no ip address A.B.C.D/M label LINE",
1399 NO_STR
1400 "Interface Internet Protocol config commands\n"
1401 "Set the IP address of an interface\n"
1402 "IP address (e.g. 10.0.0.1/8)\n"
1403 "Label of this address\n"
1404 "Label\n")
1405{
hassoeef1fe12004-10-03 18:46:08 +00001406 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001407}
1408#endif /* HAVE_NETLINK */
1409
1410#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001411static int
hasso39db97e2004-10-12 20:50:58 +00001412ipv6_address_install (struct vty *vty, struct interface *ifp,
1413 const char *addr_str, const char *peer_str,
1414 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001415{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001416 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001417 struct prefix_ipv6 cp;
1418 struct connected *ifc;
1419 struct prefix_ipv6 *p;
1420 int ret;
1421
Christian Frankebfac8dc2013-01-24 14:04:50 +00001422 if_data = ifp->info;
1423
paul718e3742002-12-13 20:15:29 +00001424 ret = str2prefix_ipv6 (addr_str, &cp);
1425 if (ret <= 0)
1426 {
1427 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1428 return CMD_WARNING;
1429 }
1430
paulca162182005-09-12 16:58:52 +00001431 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001432 if (! ifc)
1433 {
1434 ifc = connected_new ();
1435 ifc->ifp = ifp;
1436
1437 /* Address. */
1438 p = prefix_ipv6_new ();
1439 *p = cp;
1440 ifc->address = (struct prefix *) p;
1441
1442 /* Secondary. */
1443 if (secondary)
1444 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1445
1446 /* Label. */
1447 if (label)
paul0752ef02005-11-03 12:35:21 +00001448 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001449
1450 /* Add to linked list. */
1451 listnode_add (ifp->connected, ifc);
1452 }
1453
1454 /* This address is configured from zebra. */
1455 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1456 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1457
1458 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001459 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001460 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1461 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001462 {
1463 /* Some system need to up the interface to set IP address. */
1464 if (! if_is_up (ifp))
1465 {
1466 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1467 if_refresh (ifp);
1468 }
1469
1470 ret = if_prefix_add_ipv6 (ifp, ifc);
1471
1472 if (ret < 0)
1473 {
1474 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001475 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001476 return CMD_WARNING;
1477 }
1478
Christian Frankef7f740f2013-01-24 14:04:48 +00001479 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001480 /* The address will be advertised to zebra clients when the notification
1481 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001482 }
1483
1484 return CMD_SUCCESS;
1485}
1486
paula1ac18c2005-06-28 17:17:12 +00001487static int
hasso39db97e2004-10-12 20:50:58 +00001488ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1489 const char *addr_str, const char *peer_str,
1490 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001491{
1492 struct prefix_ipv6 cp;
1493 struct connected *ifc;
1494 int ret;
1495
1496 /* Convert to prefix structure. */
1497 ret = str2prefix_ipv6 (addr_str, &cp);
1498 if (ret <= 0)
1499 {
1500 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1501 return CMD_WARNING;
1502 }
1503
1504 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001505 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001506 if (! ifc)
1507 {
1508 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1509 return CMD_WARNING;
1510 }
1511
1512 /* This is not configured address. */
1513 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1514 return CMD_WARNING;
1515
Christian Franke676e1a02013-01-24 14:04:45 +00001516 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1517
paul718e3742002-12-13 20:15:29 +00001518 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001519 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001520 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1521 {
1522 listnode_delete (ifp->connected, ifc);
1523 connected_free (ifc);
1524 return CMD_WARNING;
1525 }
1526
1527 /* This is real route. */
1528 ret = if_prefix_delete_ipv6 (ifp, ifc);
1529 if (ret < 0)
1530 {
1531 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001532 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001533 return CMD_WARNING;
1534 }
1535
Christian Frankef7f740f2013-01-24 14:04:48 +00001536 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001537 /* This information will be propagated to the zclients when the
1538 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001539 return CMD_SUCCESS;
1540}
1541
1542DEFUN (ipv6_address,
1543 ipv6_address_cmd,
1544 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001545 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001546 "Set the IP address of an interface\n"
1547 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1548{
1549 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1550}
1551
1552DEFUN (no_ipv6_address,
1553 no_ipv6_address_cmd,
1554 "no ipv6 address X:X::X:X/M",
1555 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001556 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001557 "Set the IP address of an interface\n"
1558 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1559{
1560 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1561}
1562#endif /* HAVE_IPV6 */
1563
paula1ac18c2005-06-28 17:17:12 +00001564static int
paul718e3742002-12-13 20:15:29 +00001565if_config_write (struct vty *vty)
1566{
hasso52dc7ee2004-09-23 19:18:23 +00001567 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001568 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02001569 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00001570
Feng Lu471ea392015-05-22 11:40:00 +02001571 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1572 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00001573 {
1574 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001575 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001576 struct connected *ifc;
1577 struct prefix *p;
1578
paul718e3742002-12-13 20:15:29 +00001579 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02001580
1581 if (ifp->vrf_id == VRF_DEFAULT)
1582 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1583 else
1584 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1585 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001586
Christian Frankebfac8dc2013-01-24 14:04:50 +00001587 if (if_data)
1588 {
1589 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1590 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1591 }
1592
paul718e3742002-12-13 20:15:29 +00001593 if (ifp->desc)
1594 vty_out (vty, " description %s%s", ifp->desc,
1595 VTY_NEWLINE);
1596
1597 /* Assign bandwidth here to avoid unnecessary interface flap
1598 while processing config script */
1599 if (ifp->bandwidth != 0)
1600 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1601
paul2e3b2e42002-12-13 21:03:13 +00001602 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1603 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001604 else
1605 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001606
paul1eb8ef22005-04-07 07:30:20 +00001607 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001608 {
paul718e3742002-12-13 20:15:29 +00001609 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1610 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001611 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001612 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001613 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001614 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001615 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001616
paul718e3742002-12-13 20:15:29 +00001617 if (ifc->label)
1618 vty_out (vty, " label %s", ifc->label);
1619
1620 vty_out (vty, "%s", VTY_NEWLINE);
1621 }
1622 }
1623
1624 if (if_data)
1625 {
paul718e3742002-12-13 20:15:29 +00001626 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1627 vty_out (vty, " %smulticast%s",
1628 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1629 VTY_NEWLINE);
1630 }
1631
1632#ifdef RTADV
1633 rtadv_config_write (vty, ifp);
1634#endif /* RTADV */
1635
hassoca776982004-06-12 14:33:05 +00001636#ifdef HAVE_IRDP
1637 irdp_config_write (vty, ifp);
1638#endif /* IRDP */
1639
paul718e3742002-12-13 20:15:29 +00001640 vty_out (vty, "!%s", VTY_NEWLINE);
1641 }
1642 return 0;
1643}
1644
1645/* Allocate and initialize interface vector. */
1646void
paula1ac18c2005-06-28 17:17:12 +00001647zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001648{
1649 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001650 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1651 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1652
1653 /* Install configuration write function. */
1654 install_node (&interface_node, if_config_write);
1655
1656 install_element (VIEW_NODE, &show_interface_cmd);
1657 install_element (ENABLE_NODE, &show_interface_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001658 install_element (ENABLE_NODE, &show_interface_desc_cmd);
paul718e3742002-12-13 20:15:29 +00001659 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001660 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00001661 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001662 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
paul718e3742002-12-13 20:15:29 +00001663 install_default (INTERFACE_NODE);
1664 install_element (INTERFACE_NODE, &interface_desc_cmd);
1665 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1666 install_element (INTERFACE_NODE, &multicast_cmd);
1667 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001668 install_element (INTERFACE_NODE, &linkdetect_cmd);
1669 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001670 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1671 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1672 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1673 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1674 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1675 install_element (INTERFACE_NODE, &ip_address_cmd);
1676 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1677#ifdef HAVE_IPV6
1678 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1679 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1680#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001681#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001682 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001683 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001684#endif /* HAVE_NETLINK */
1685}