blob: b22186dfe67c0ff2c09907f7ee4d7d14f760f5bf [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
Donald Sharp64257732015-11-20 08:33:30 -050045#if defined (HAVE_RTADV)
Chris Caputob60668d2009-05-03 04:40:57 +000046/* 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 };
Donald Sharp64257732015-11-20 08:33:30 -050049#endif /* HAVE_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
Donald Sharp64257732015-11-20 08:33:30 -050062#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +000063 {
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 }
Donald Sharp64257732015-11-20 08:33:30 -050088#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +000089
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;
Morgan Stewartc8394ac2015-09-17 19:04:30 -0400371 assert(if_data);
372
paul48b33aa2002-12-13 20:52:52 +0000373 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
374 if_set_flags (ifp, IFF_MULTICAST);
375 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
376 if_unset_flags (ifp, IFF_MULTICAST);
377
paul718e3742002-12-13 20:15:29 +0000378 zebra_interface_add_update (ifp);
379
380 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
381 {
382 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
383
Christian Frankebfac8dc2013-01-24 14:04:50 +0000384 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
385 {
386 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200387 zlog_debug ("interface %s vrf %u index %d is shutdown. "
388 "Won't wake it up.",
389 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000390 return;
391 }
392
paul718e3742002-12-13 20:15:29 +0000393 if_addr_wakeup (ifp);
394
395 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200396 zlog_debug ("interface %s vrf %u index %d becomes active.",
397 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000398 }
399 else
400 {
401 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200402 zlog_debug ("interface %s vrf %u index %d is added.",
403 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000404 }
405}
406
paul6eb88272005-07-29 14:36:00 +0000407/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000408void
409if_delete_update (struct interface *ifp)
410{
paul718e3742002-12-13 20:15:29 +0000411 struct connected *ifc;
412 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000413 struct route_node *rn;
414 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000415
416 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000417
418 if (if_is_up(ifp))
419 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200420 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
421 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000422 return;
423 }
424
425 /* Mark interface as inactive */
426 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
427
428 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200429 zlog_debug ("interface %s vrf %u index %d is now inactive.",
430 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000431
432 /* Delete connected routes from the kernel. */
433 if (ifp->connected)
434 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000435 struct listnode *node;
436 struct listnode *last = NULL;
437
hassoeef1fe12004-10-03 18:46:08 +0000438 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000439 {
paul1eb8ef22005-04-07 07:30:20 +0000440 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000441 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000442
Paul Jakmabeb56332006-05-11 13:28:05 +0000443 if (p->family == AF_INET
444 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000445 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000446 struct listnode *anode;
447 struct listnode *next;
448 struct listnode *first;
449 struct list *addr_list;
450
hassoeef1fe12004-10-03 18:46:08 +0000451 route_unlock_node (rn);
452 addr_list = (struct list *) rn->info;
453
454 /* Remove addresses, secondaries first. */
455 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000456 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000457 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000458 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000459 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000460 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000461 first = NULL;
462 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000463 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000464
Paul Jakmad9a18f12007-04-10 19:30:20 +0000465 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000466 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000467 connected_down_ipv4 (ifp, ifc);
468
Christian Franke02b48052013-01-24 14:04:49 +0000469 /* XXX: We have to send notifications here explicitly, because we destroy
470 * the ifc before receiving the notification about the address being deleted.
471 */
hassoeef1fe12004-10-03 18:46:08 +0000472 zebra_interface_address_delete_update (ifp, ifc);
473
474 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000475 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000476
477 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000478 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000479 route_unlock_node (rn);
480
481 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000482 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
483 {
484 listnode_delete (ifp->connected, ifc);
485 connected_free (ifc);
486 }
487 else
488 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000489 }
490
491 /* Free chain list and respective route node. */
492 list_delete (addr_list);
493 rn->info = NULL;
494 route_unlock_node (rn);
495 }
paul718e3742002-12-13 20:15:29 +0000496#ifdef HAVE_IPV6
497 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000498 {
499 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000500
hassoeef1fe12004-10-03 18:46:08 +0000501 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000502
hassoeef1fe12004-10-03 18:46:08 +0000503 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000504 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000505
506 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
507 last = node;
508 else
509 {
510 listnode_delete (ifp->connected, ifc);
511 connected_free (ifc);
512 }
paul718e3742002-12-13 20:15:29 +0000513 }
hassoeef1fe12004-10-03 18:46:08 +0000514#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200515 else
516 {
517 last = node;
518 }
paul718e3742002-12-13 20:15:29 +0000519 }
520 }
521 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000522
523 /* Update ifindex after distributing the delete message. This is in
524 case any client needs to have the old value of ifindex available
525 while processing the deletion. Each client daemon is responsible
526 for setting ifindex to IFINDEX_INTERNAL after processing the
527 interface deletion message. */
528 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000529}
530
531/* Interface is up. */
532void
533if_up (struct interface *ifp)
534{
hasso52dc7ee2004-09-23 19:18:23 +0000535 struct listnode *node;
536 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000537 struct connected *ifc;
538 struct prefix *p;
539
540 /* Notify the protocol daemons. */
541 zebra_interface_up_update (ifp);
542
543 /* Install connected routes to the kernel. */
544 if (ifp->connected)
545 {
paul1eb8ef22005-04-07 07:30:20 +0000546 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000547 {
paul718e3742002-12-13 20:15:29 +0000548 p = ifc->address;
549
550 if (p->family == AF_INET)
551 connected_up_ipv4 (ifp, ifc);
552#ifdef HAVE_IPV6
553 else if (p->family == AF_INET6)
554 connected_up_ipv6 (ifp, ifc);
555#endif /* HAVE_IPV6 */
556 }
557 }
558
559 /* Examine all static routes. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200560 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000561}
562
563/* Interface goes down. We have to manage different behavior of based
564 OS. */
565void
566if_down (struct interface *ifp)
567{
hasso52dc7ee2004-09-23 19:18:23 +0000568 struct listnode *node;
569 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000570 struct connected *ifc;
571 struct prefix *p;
572
573 /* Notify to the protocol daemons. */
574 zebra_interface_down_update (ifp);
575
576 /* Delete connected routes from the kernel. */
577 if (ifp->connected)
578 {
paul1eb8ef22005-04-07 07:30:20 +0000579 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000580 {
paul718e3742002-12-13 20:15:29 +0000581 p = ifc->address;
582
583 if (p->family == AF_INET)
584 connected_down_ipv4 (ifp, ifc);
585#ifdef HAVE_IPV6
586 else if (p->family == AF_INET6)
587 connected_down_ipv6 (ifp, ifc);
588#endif /* HAVE_IPV6 */
589 }
590 }
591
592 /* Examine all static routes which direct to the interface. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200593 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000594}
595
596void
597if_refresh (struct interface *ifp)
598{
paul5c78b3d2006-01-25 04:31:40 +0000599 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000600}
601
paul718e3742002-12-13 20:15:29 +0000602/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000603static int
paul718e3742002-12-13 20:15:29 +0000604prefix_vty_out (struct vty *vty, struct prefix *p)
605{
606 char str[INET6_ADDRSTRLEN];
607
608 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
609 vty_out (vty, "%s", str);
610 return strlen (str);
611}
612
613/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000614static void
paul718e3742002-12-13 20:15:29 +0000615connected_dump_vty (struct vty *vty, struct connected *connected)
616{
617 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000618
619 /* Print interface address. */
620 p = connected->address;
621 vty_out (vty, " %s ", prefix_family_str (p));
622 prefix_vty_out (vty, p);
623 vty_out (vty, "/%d", p->prefixlen);
624
625 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000626 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000627 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000628 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
629 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000630 }
631
632 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
633 vty_out (vty, " secondary");
634
635 if (connected->label)
636 vty_out (vty, " %s", connected->label);
637
638 vty_out (vty, "%s", VTY_NEWLINE);
639}
640
Donald Sharp64257732015-11-20 08:33:30 -0500641#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000642/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000643static void
paul718e3742002-12-13 20:15:29 +0000644nd_dump_vty (struct vty *vty, struct interface *ifp)
645{
646 struct zebra_if *zif;
647 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000648 int interval;
paul718e3742002-12-13 20:15:29 +0000649
650 zif = (struct zebra_if *) ifp->info;
651 rtadv = &zif->rtadv;
652
653 if (rtadv->AdvSendAdvertisements)
654 {
655 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
656 rtadv->AdvReachableTime, VTY_NEWLINE);
657 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
658 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000659 interval = rtadv->MaxRtrAdvInterval;
660 if (interval % 1000)
661 vty_out (vty, " ND router advertisements are sent every "
662 "%d milliseconds%s", interval,
663 VTY_NEWLINE);
664 else
665 vty_out (vty, " ND router advertisements are sent every "
666 "%d seconds%s", interval / 1000,
667 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400668 if (rtadv->AdvDefaultLifetime != -1)
669 vty_out (vty, " ND router advertisements live for %d seconds%s",
670 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
671 else
672 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
673 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000674 vty_out (vty, " ND router advertisement default router preference is "
675 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
676 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000677 if (rtadv->AdvManagedFlag)
678 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
679 VTY_NEWLINE);
680 else
681 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
682 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000683 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400684 {
vincent7cee1bb2005-03-25 13:08:53 +0000685 vty_out (vty, " ND router advertisements with "
686 "Home Agent flag bit set.%s",
687 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400688 if (rtadv->HomeAgentLifetime != -1)
689 vty_out (vty, " Home Agent lifetime is %u seconds%s",
690 rtadv->HomeAgentLifetime, VTY_NEWLINE);
691 else
692 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
693 VTY_NEWLINE);
694 vty_out (vty, " Home Agent preference is %u%s",
695 rtadv->HomeAgentPreference, VTY_NEWLINE);
696 }
vincent7cee1bb2005-03-25 13:08:53 +0000697 if (rtadv->AdvIntervalOption)
698 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
699 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000700 }
701}
Donald Sharp64257732015-11-20 08:33:30 -0500702#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000703
704/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000705static void
paul718e3742002-12-13 20:15:29 +0000706if_dump_vty (struct vty *vty, struct interface *ifp)
707{
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. */
Timo Teräs954c7d62016-01-15 17:36:33 +0200759 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000760 if (ifp->hw_addr_len != 0)
761 {
762 int i;
763
764 vty_out (vty, " HWaddr: ");
765 for (i = 0; i < ifp->hw_addr_len; i++)
766 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
767 vty_out (vty, "%s", VTY_NEWLINE);
768 }
paul718e3742002-12-13 20:15:29 +0000769
770 /* Bandwidth in kbps */
771 if (ifp->bandwidth != 0)
772 {
773 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
774 vty_out(vty, "%s", VTY_NEWLINE);
775 }
776
hassoeef1fe12004-10-03 18:46:08 +0000777 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000778 {
hassoeef1fe12004-10-03 18:46:08 +0000779 if (! rn->info)
780 continue;
781
paul1eb8ef22005-04-07 07:30:20 +0000782 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
783 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000784 }
785
paul1eb8ef22005-04-07 07:30:20 +0000786 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000787 {
hasso39db97e2004-10-12 20:50:58 +0000788 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
789 (connected->address->family == AF_INET6))
790 connected_dump_vty (vty, connected);
791 }
792
Donald Sharp64257732015-11-20 08:33:30 -0500793#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000794 nd_dump_vty (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -0500795#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000796
797#ifdef HAVE_PROC_NET_DEV
798 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000799 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
800 "%lu dropped%s",
801 ifp->stats.rx_packets, ifp->stats.rx_multicast,
802 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000803
hasso6f2c27a2005-01-18 13:44:35 +0000804 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000805 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000806 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
807 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000808 ifp->stats.rx_frame_errors, VTY_NEWLINE);
809
810 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000811 ifp->stats.rx_missed_errors, VTY_NEWLINE);
812
hasso6f2c27a2005-01-18 13:44:35 +0000813 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000814 ifp->stats.tx_packets, ifp->stats.tx_bytes,
815 ifp->stats.tx_dropped, VTY_NEWLINE);
816
hasso6f2c27a2005-01-18 13:44:35 +0000817 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
818 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000819 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
820 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000821 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000822
hasso6f2c27a2005-01-18 13:44:35 +0000823 vty_out (vty, " %lu window, %lu collisions%s",
824 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000825#endif /* HAVE_PROC_NET_DEV */
826
827#ifdef HAVE_NET_RT_IFLIST
828#if defined (__bsdi__) || defined (__NetBSD__)
829 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200830 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
831 " multicast packets %llu%s",
832 (unsigned long long)ifp->stats.ifi_ipackets,
833 (unsigned long long)ifp->stats.ifi_ibytes,
834 (unsigned long long)ifp->stats.ifi_iqdrops,
835 (unsigned long long)ifp->stats.ifi_imcasts,
836 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000837
David Lamparter193e78f2015-04-21 10:42:30 +0200838 vty_out (vty, " input errors %llu%s",
839 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000840
David Lamparter193e78f2015-04-21 10:42:30 +0200841 vty_out (vty, " output packets %llu, bytes %llu,"
842 " multicast packets %llu%s",
843 (unsigned long long)ifp->stats.ifi_opackets,
844 (unsigned long long)ifp->stats.ifi_obytes,
845 (unsigned long long)ifp->stats.ifi_omcasts,
846 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000847
David Lamparter193e78f2015-04-21 10:42:30 +0200848 vty_out (vty, " output errors %llu%s",
849 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000850
David Lamparter193e78f2015-04-21 10:42:30 +0200851 vty_out (vty, " collisions %llu%s",
852 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000853#else
854 /* Statistics print out using sysctl (). */
855 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
856 " multicast packets %lu%s",
857 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
858 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
859 VTY_NEWLINE);
860
861 vty_out (vty, " input errors %lu%s",
862 ifp->stats.ifi_ierrors, VTY_NEWLINE);
863
864 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
865 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
866 ifp->stats.ifi_omcasts, VTY_NEWLINE);
867
868 vty_out (vty, " output errors %lu%s",
869 ifp->stats.ifi_oerrors, VTY_NEWLINE);
870
871 vty_out (vty, " collisions %lu%s",
872 ifp->stats.ifi_collisions, VTY_NEWLINE);
873#endif /* __bsdi__ || __NetBSD__ */
874#endif /* HAVE_NET_RT_IFLIST */
875}
876
paul718e3742002-12-13 20:15:29 +0000877/* Wrapper hook point for zebra daemon so that ifindex can be set
878 * DEFUN macro not used as extract.pl HAS to ignore this
879 * See also interface_cmd in lib/if.c
880 */
881DEFUN_NOSH (zebra_interface,
882 zebra_interface_cmd,
883 "interface IFNAME",
884 "Select an interface to configure\n"
885 "Interface's name\n")
886{
887 int ret;
888 struct interface * ifp;
889
890 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000891 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
892 return ret;
paul718e3742002-12-13 20:15:29 +0000893
894 ifp = vty->index;
895
ajsd2fc8892005-04-02 18:38:43 +0000896 if (ifp->ifindex == IFINDEX_INTERNAL)
897 /* Is this really necessary? Shouldn't status be initialized to 0
898 in that case? */
899 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000900
901 return ret;
902}
903
Feng Lu471ea392015-05-22 11:40:00 +0200904ALIAS (zebra_interface,
905 zebra_interface_vrf_cmd,
906 "interface IFNAME " VRF_CMD_STR,
907 "Select an interface to configure\n"
908 "Interface's name\n"
909 VRF_CMD_HELP_STR)
910
paul718e3742002-12-13 20:15:29 +0000911struct cmd_node interface_node =
912{
913 INTERFACE_NODE,
914 "%s(config-if)# ",
915 1
916};
917
Feng Lua2854772015-05-22 11:40:01 +0200918/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +0000919DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +0200920 "show interface",
paul718e3742002-12-13 20:15:29 +0000921 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +0200922 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +0000923{
hasso52dc7ee2004-09-23 19:18:23 +0000924 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000925 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +0200926 vrf_id_t vrf_id = VRF_DEFAULT;
927
paul718e3742002-12-13 20:15:29 +0000928#ifdef HAVE_PROC_NET_DEV
929 /* If system has interface statistics via proc file system, update
930 statistics. */
931 ifstat_update_proc ();
932#endif /* HAVE_PROC_NET_DEV */
933#ifdef HAVE_NET_RT_IFLIST
934 ifstat_update_sysctl ();
935#endif /* HAVE_NET_RT_IFLIST */
936
Feng Lua2854772015-05-22 11:40:01 +0200937 if (argc > 0)
938 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +0000939
940 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +0200941 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +0000942 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000943
944 return CMD_SUCCESS;
945}
946
Feng Lua2854772015-05-22 11:40:01 +0200947ALIAS (show_interface,
948 show_interface_vrf_cmd,
949 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +0000950 SHOW_STR
951 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +0200952 VRF_CMD_HELP_STR)
953
954/* Show all interfaces to vty. */
955DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
956 "show interface " VRF_ALL_CMD_STR,
957 SHOW_STR
958 "Interface status and configuration\n"
959 VRF_ALL_CMD_HELP_STR)
960{
961 struct listnode *node;
962 struct interface *ifp;
963 vrf_iter_t iter;
964
965#ifdef HAVE_PROC_NET_DEV
966 /* If system has interface statistics via proc file system, update
967 statistics. */
968 ifstat_update_proc ();
969#endif /* HAVE_PROC_NET_DEV */
970#ifdef HAVE_NET_RT_IFLIST
971 ifstat_update_sysctl ();
972#endif /* HAVE_NET_RT_IFLIST */
973
974 /* All interface print. */
975 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
976 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
977 if_dump_vty (vty, ifp);
978
979 return CMD_SUCCESS;
980}
981
982/* Show specified interface to vty. */
983DEFUN (show_interface_name, show_interface_name_cmd,
984 "show interface IFNAME",
985 SHOW_STR
986 "Interface status and configuration\n"
987 "Inteface name\n")
988{
989 struct interface *ifp;
990 vrf_id_t vrf_id = VRF_DEFAULT;
991
992#ifdef HAVE_PROC_NET_DEV
993 /* If system has interface statistics via proc file system, update
994 statistics. */
995 ifstat_update_proc ();
996#endif /* HAVE_PROC_NET_DEV */
997#ifdef HAVE_NET_RT_IFLIST
998 ifstat_update_sysctl ();
999#endif /* HAVE_NET_RT_IFLIST */
1000
1001 if (argc > 1)
1002 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1003
1004 /* Specified interface print. */
1005 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1006 if (ifp == NULL)
1007 {
1008 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1009 VTY_NEWLINE);
1010 return CMD_WARNING;
1011 }
1012 if_dump_vty (vty, ifp);
1013
1014 return CMD_SUCCESS;
1015}
1016
1017ALIAS (show_interface_name,
1018 show_interface_name_vrf_cmd,
1019 "show interface IFNAME " VRF_CMD_STR,
1020 SHOW_STR
1021 "Interface status and configuration\n"
1022 "Inteface name\n"
1023 VRF_CMD_HELP_STR)
1024
1025/* Show specified interface to vty. */
1026DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1027 "show interface IFNAME " VRF_ALL_CMD_STR,
1028 SHOW_STR
1029 "Interface status and configuration\n"
1030 "Inteface name\n"
1031 VRF_ALL_CMD_HELP_STR)
1032{
1033 struct interface *ifp;
1034 vrf_iter_t iter;
1035 int found = 0;
1036
1037#ifdef HAVE_PROC_NET_DEV
1038 /* If system has interface statistics via proc file system, update
1039 statistics. */
1040 ifstat_update_proc ();
1041#endif /* HAVE_PROC_NET_DEV */
1042#ifdef HAVE_NET_RT_IFLIST
1043 ifstat_update_sysctl ();
1044#endif /* HAVE_NET_RT_IFLIST */
1045
1046 /* All interface print. */
1047 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1048 {
1049 /* Specified interface print. */
1050 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1051 if (ifp)
1052 {
1053 if_dump_vty (vty, ifp);
1054 found++;
1055 }
1056 }
1057
1058 if (!found)
1059 {
1060 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1061 return CMD_WARNING;
1062 }
1063
1064 return CMD_SUCCESS;
1065}
1066
1067static void
1068if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001069{
1070 struct listnode *node;
1071 struct interface *ifp;
1072
1073 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001074 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001075 {
1076 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001077
1078 len = vty_out (vty, "%s", ifp->name);
1079 vty_out (vty, "%*s", (16 - len), " ");
1080
1081 if (if_is_up(ifp))
1082 {
1083 vty_out (vty, "up ");
1084 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1085 {
1086 if (if_is_running(ifp))
1087 vty_out (vty, "up ");
1088 else
1089 vty_out (vty, "down ");
1090 }
1091 else
1092 {
1093 vty_out (vty, "unknown ");
1094 }
1095 }
1096 else
1097 {
1098 vty_out (vty, "down down ");
1099 }
1100
1101 if (ifp->desc)
1102 vty_out (vty, "%s", ifp->desc);
1103 vty_out (vty, "%s", VTY_NEWLINE);
1104 }
Feng Lua2854772015-05-22 11:40:01 +02001105}
1106
1107DEFUN (show_interface_desc,
1108 show_interface_desc_cmd,
1109 "show interface description",
1110 SHOW_STR
1111 "Interface status and configuration\n"
1112 "Interface description\n")
1113{
1114 vrf_id_t vrf_id = VRF_DEFAULT;
1115
1116 if (argc > 0)
1117 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1118
1119 if_show_description (vty, vrf_id);
1120
1121 return CMD_SUCCESS;
1122}
1123
1124ALIAS (show_interface_desc,
1125 show_interface_desc_vrf_cmd,
1126 "show interface description " VRF_CMD_STR,
1127 SHOW_STR
1128 "Interface status and configuration\n"
1129 "Interface description\n"
1130 VRF_CMD_HELP_STR)
1131
1132DEFUN (show_interface_desc_vrf_all,
1133 show_interface_desc_vrf_all_cmd,
1134 "show interface description " VRF_ALL_CMD_STR,
1135 SHOW_STR
1136 "Interface status and configuration\n"
1137 "Interface description\n"
1138 VRF_ALL_CMD_HELP_STR)
1139{
1140 vrf_iter_t iter;
1141
1142 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1143 if (!list_isempty (vrf_iter2iflist (iter)))
1144 {
1145 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1146 vrf_iter2id (iter),
1147 VTY_NEWLINE, VTY_NEWLINE);
1148 if_show_description (vty, vrf_iter2id (iter));
1149 }
1150
hassoed9bb6d2005-03-13 19:17:21 +00001151 return CMD_SUCCESS;
1152}
1153
paul718e3742002-12-13 20:15:29 +00001154DEFUN (multicast,
1155 multicast_cmd,
1156 "multicast",
1157 "Set multicast flag to interface\n")
1158{
1159 int ret;
1160 struct interface *ifp;
1161 struct zebra_if *if_data;
1162
1163 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001164 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001165 {
paul48b33aa2002-12-13 20:52:52 +00001166 ret = if_set_flags (ifp, IFF_MULTICAST);
1167 if (ret < 0)
1168 {
1169 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1170 return CMD_WARNING;
1171 }
1172 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001173 }
paul718e3742002-12-13 20:15:29 +00001174 if_data = ifp->info;
1175 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001176
paul718e3742002-12-13 20:15:29 +00001177 return CMD_SUCCESS;
1178}
1179
1180DEFUN (no_multicast,
1181 no_multicast_cmd,
1182 "no multicast",
1183 NO_STR
1184 "Unset multicast flag to interface\n")
1185{
1186 int ret;
1187 struct interface *ifp;
1188 struct zebra_if *if_data;
1189
1190 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001191 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001192 {
paul48b33aa2002-12-13 20:52:52 +00001193 ret = if_unset_flags (ifp, IFF_MULTICAST);
1194 if (ret < 0)
1195 {
1196 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1197 return CMD_WARNING;
1198 }
1199 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001200 }
paul718e3742002-12-13 20:15:29 +00001201 if_data = ifp->info;
1202 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1203
1204 return CMD_SUCCESS;
1205}
1206
paul2e3b2e42002-12-13 21:03:13 +00001207DEFUN (linkdetect,
1208 linkdetect_cmd,
1209 "link-detect",
1210 "Enable link detection on interface\n")
1211{
paul2e3b2e42002-12-13 21:03:13 +00001212 struct interface *ifp;
1213 int if_was_operative;
1214
1215 ifp = (struct interface *) vty->index;
1216 if_was_operative = if_is_operative(ifp);
1217 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1218
1219 /* When linkdetection is enabled, if might come down */
1220 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1221
1222 /* FIXME: Will defer status change forwarding if interface
1223 does not come down! */
1224
1225 return CMD_SUCCESS;
1226}
1227
1228
1229DEFUN (no_linkdetect,
1230 no_linkdetect_cmd,
1231 "no link-detect",
1232 NO_STR
1233 "Disable link detection on interface\n")
1234{
paul2e3b2e42002-12-13 21:03:13 +00001235 struct interface *ifp;
1236 int if_was_operative;
1237
1238 ifp = (struct interface *) vty->index;
1239 if_was_operative = if_is_operative(ifp);
1240 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1241
1242 /* Interface may come up after disabling link detection */
1243 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1244
1245 /* FIXME: see linkdetect_cmd */
1246
1247 return CMD_SUCCESS;
1248}
1249
paul718e3742002-12-13 20:15:29 +00001250DEFUN (shutdown_if,
1251 shutdown_if_cmd,
1252 "shutdown",
1253 "Shutdown the selected interface\n")
1254{
1255 int ret;
1256 struct interface *ifp;
1257 struct zebra_if *if_data;
1258
1259 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001260 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001261 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001262 ret = if_unset_flags (ifp, IFF_UP);
1263 if (ret < 0)
1264 {
1265 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1266 return CMD_WARNING;
1267 }
1268 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001269 }
paul718e3742002-12-13 20:15:29 +00001270 if_data = ifp->info;
1271 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1272
1273 return CMD_SUCCESS;
1274}
1275
1276DEFUN (no_shutdown_if,
1277 no_shutdown_if_cmd,
1278 "no shutdown",
1279 NO_STR
1280 "Shutdown the selected interface\n")
1281{
1282 int ret;
1283 struct interface *ifp;
1284 struct zebra_if *if_data;
1285
1286 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001287
1288 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001289 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001290 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1291 if (ret < 0)
1292 {
1293 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1294 return CMD_WARNING;
1295 }
1296 if_refresh (ifp);
1297
1298 /* Some addresses (in particular, IPv6 addresses on Linux) get
1299 * removed when the interface goes down. They need to be readded.
1300 */
1301 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001302 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001303
paul718e3742002-12-13 20:15:29 +00001304 if_data = ifp->info;
1305 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1306
1307 return CMD_SUCCESS;
1308}
1309
1310DEFUN (bandwidth_if,
1311 bandwidth_if_cmd,
1312 "bandwidth <1-10000000>",
1313 "Set bandwidth informational parameter\n"
1314 "Bandwidth in kilobits\n")
1315{
1316 struct interface *ifp;
1317 unsigned int bandwidth;
1318
1319 ifp = (struct interface *) vty->index;
1320 bandwidth = strtol(argv[0], NULL, 10);
1321
1322 /* bandwidth range is <1-10000000> */
1323 if (bandwidth < 1 || bandwidth > 10000000)
1324 {
1325 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1326 return CMD_WARNING;
1327 }
1328
1329 ifp->bandwidth = bandwidth;
1330
1331 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001332 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001333 zebra_interface_up_update (ifp);
1334
1335 return CMD_SUCCESS;
1336}
1337
1338DEFUN (no_bandwidth_if,
1339 no_bandwidth_if_cmd,
1340 "no bandwidth",
1341 NO_STR
1342 "Set bandwidth informational parameter\n")
1343{
1344 struct interface *ifp;
1345
1346 ifp = (struct interface *) vty->index;
1347
1348 ifp->bandwidth = 0;
1349
1350 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001351 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001352 zebra_interface_up_update (ifp);
1353
1354 return CMD_SUCCESS;
1355}
1356
1357ALIAS (no_bandwidth_if,
1358 no_bandwidth_if_val_cmd,
1359 "no bandwidth <1-10000000>",
1360 NO_STR
1361 "Set bandwidth informational parameter\n"
1362 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001363
paula1ac18c2005-06-28 17:17:12 +00001364static int
hasso39db97e2004-10-12 20:50:58 +00001365ip_address_install (struct vty *vty, struct interface *ifp,
1366 const char *addr_str, const char *peer_str,
1367 const char *label)
paul718e3742002-12-13 20:15:29 +00001368{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001369 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001370 struct prefix_ipv4 cp;
1371 struct connected *ifc;
1372 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001373 int ret;
1374
Christian Frankebfac8dc2013-01-24 14:04:50 +00001375 if_data = ifp->info;
1376
paul718e3742002-12-13 20:15:29 +00001377 ret = str2prefix_ipv4 (addr_str, &cp);
1378 if (ret <= 0)
1379 {
1380 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
paulca162182005-09-12 16:58:52 +00001384 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001385 if (! ifc)
1386 {
1387 ifc = connected_new ();
1388 ifc->ifp = ifp;
1389
1390 /* Address. */
1391 p = prefix_ipv4_new ();
1392 *p = cp;
1393 ifc->address = (struct prefix *) p;
1394
1395 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001396 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001397 {
1398 p = prefix_ipv4_new ();
1399 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001400 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001401 ifc->destination = (struct prefix *) p;
1402 }
1403
paul718e3742002-12-13 20:15:29 +00001404 /* Label. */
1405 if (label)
paul0752ef02005-11-03 12:35:21 +00001406 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001407
1408 /* Add to linked list. */
1409 listnode_add (ifp->connected, ifc);
1410 }
1411
1412 /* This address is configured from zebra. */
1413 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1414 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1415
1416 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001417 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001418 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1419 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001420 {
1421 /* Some system need to up the interface to set IP address. */
1422 if (! if_is_up (ifp))
1423 {
1424 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1425 if_refresh (ifp);
1426 }
1427
1428 ret = if_set_prefix (ifp, ifc);
1429 if (ret < 0)
1430 {
1431 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001432 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001433 return CMD_WARNING;
1434 }
1435
Christian Frankef7f740f2013-01-24 14:04:48 +00001436 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001437 /* The address will be advertised to zebra clients when the notification
1438 * from the kernel has been received.
1439 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001440 }
1441
1442 return CMD_SUCCESS;
1443}
1444
paula1ac18c2005-06-28 17:17:12 +00001445static int
hasso39db97e2004-10-12 20:50:58 +00001446ip_address_uninstall (struct vty *vty, struct interface *ifp,
1447 const char *addr_str, const char *peer_str,
1448 const char *label)
paul718e3742002-12-13 20:15:29 +00001449{
1450 struct prefix_ipv4 cp;
1451 struct connected *ifc;
1452 int ret;
1453
1454 /* Convert to prefix structure. */
1455 ret = str2prefix_ipv4 (addr_str, &cp);
1456 if (ret <= 0)
1457 {
1458 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1459 return CMD_WARNING;
1460 }
1461
1462 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001463 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001464 if (! ifc)
1465 {
1466 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1467 return CMD_WARNING;
1468 }
1469
1470 /* This is not configured address. */
1471 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1472 return CMD_WARNING;
1473
Paul Jakma74ecdc92006-06-15 18:10:47 +00001474 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1475
paul718e3742002-12-13 20:15:29 +00001476 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001477 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001478 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1479 {
1480 listnode_delete (ifp->connected, ifc);
1481 connected_free (ifc);
1482 return CMD_WARNING;
1483 }
1484
1485 /* This is real route. */
1486 ret = if_unset_prefix (ifp, ifc);
1487 if (ret < 0)
1488 {
1489 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001490 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001491 return CMD_WARNING;
1492 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001493 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001494 /* we will receive a kernel notification about this route being removed.
1495 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001496 return CMD_SUCCESS;
1497}
1498
1499DEFUN (ip_address,
1500 ip_address_cmd,
1501 "ip address A.B.C.D/M",
1502 "Interface Internet Protocol config commands\n"
1503 "Set the IP address of an interface\n"
1504 "IP address (e.g. 10.0.0.1/8)\n")
1505{
hassoeef1fe12004-10-03 18:46:08 +00001506 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001507}
1508
1509DEFUN (no_ip_address,
1510 no_ip_address_cmd,
1511 "no ip address A.B.C.D/M",
1512 NO_STR
1513 "Interface Internet Protocol config commands\n"
1514 "Set the IP address of an interface\n"
1515 "IP Address (e.g. 10.0.0.1/8)")
1516{
hassoeef1fe12004-10-03 18:46:08 +00001517 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001518}
1519
1520#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001521DEFUN (ip_address_label,
1522 ip_address_label_cmd,
1523 "ip address A.B.C.D/M label LINE",
1524 "Interface Internet Protocol config commands\n"
1525 "Set the IP address of an interface\n"
1526 "IP address (e.g. 10.0.0.1/8)\n"
1527 "Label of this address\n"
1528 "Label\n")
1529{
hassoeef1fe12004-10-03 18:46:08 +00001530 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001531}
1532
1533DEFUN (no_ip_address_label,
1534 no_ip_address_label_cmd,
1535 "no ip address A.B.C.D/M label LINE",
1536 NO_STR
1537 "Interface Internet Protocol config commands\n"
1538 "Set the IP address of an interface\n"
1539 "IP address (e.g. 10.0.0.1/8)\n"
1540 "Label of this address\n"
1541 "Label\n")
1542{
hassoeef1fe12004-10-03 18:46:08 +00001543 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001544}
1545#endif /* HAVE_NETLINK */
1546
1547#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001548static int
hasso39db97e2004-10-12 20:50:58 +00001549ipv6_address_install (struct vty *vty, struct interface *ifp,
1550 const char *addr_str, const char *peer_str,
1551 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001552{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001553 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001554 struct prefix_ipv6 cp;
1555 struct connected *ifc;
1556 struct prefix_ipv6 *p;
1557 int ret;
1558
Christian Frankebfac8dc2013-01-24 14:04:50 +00001559 if_data = ifp->info;
1560
paul718e3742002-12-13 20:15:29 +00001561 ret = str2prefix_ipv6 (addr_str, &cp);
1562 if (ret <= 0)
1563 {
1564 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1565 return CMD_WARNING;
1566 }
1567
paulca162182005-09-12 16:58:52 +00001568 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001569 if (! ifc)
1570 {
1571 ifc = connected_new ();
1572 ifc->ifp = ifp;
1573
1574 /* Address. */
1575 p = prefix_ipv6_new ();
1576 *p = cp;
1577 ifc->address = (struct prefix *) p;
1578
1579 /* Secondary. */
1580 if (secondary)
1581 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1582
1583 /* Label. */
1584 if (label)
paul0752ef02005-11-03 12:35:21 +00001585 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001586
1587 /* Add to linked list. */
1588 listnode_add (ifp->connected, ifc);
1589 }
1590
1591 /* This address is configured from zebra. */
1592 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1593 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1594
1595 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001596 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001597 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1598 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001599 {
1600 /* Some system need to up the interface to set IP address. */
1601 if (! if_is_up (ifp))
1602 {
1603 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1604 if_refresh (ifp);
1605 }
1606
1607 ret = if_prefix_add_ipv6 (ifp, ifc);
1608
1609 if (ret < 0)
1610 {
1611 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001612 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001613 return CMD_WARNING;
1614 }
1615
Christian Frankef7f740f2013-01-24 14:04:48 +00001616 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001617 /* The address will be advertised to zebra clients when the notification
1618 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001619 }
1620
1621 return CMD_SUCCESS;
1622}
1623
paula1ac18c2005-06-28 17:17:12 +00001624static int
hasso39db97e2004-10-12 20:50:58 +00001625ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1626 const char *addr_str, const char *peer_str,
1627 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001628{
1629 struct prefix_ipv6 cp;
1630 struct connected *ifc;
1631 int ret;
1632
1633 /* Convert to prefix structure. */
1634 ret = str2prefix_ipv6 (addr_str, &cp);
1635 if (ret <= 0)
1636 {
1637 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1638 return CMD_WARNING;
1639 }
1640
1641 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001642 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001643 if (! ifc)
1644 {
1645 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1646 return CMD_WARNING;
1647 }
1648
1649 /* This is not configured address. */
1650 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1651 return CMD_WARNING;
1652
Christian Franke676e1a02013-01-24 14:04:45 +00001653 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1654
paul718e3742002-12-13 20:15:29 +00001655 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001656 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001657 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1658 {
1659 listnode_delete (ifp->connected, ifc);
1660 connected_free (ifc);
1661 return CMD_WARNING;
1662 }
1663
1664 /* This is real route. */
1665 ret = if_prefix_delete_ipv6 (ifp, ifc);
1666 if (ret < 0)
1667 {
1668 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001669 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001670 return CMD_WARNING;
1671 }
1672
Christian Frankef7f740f2013-01-24 14:04:48 +00001673 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001674 /* This information will be propagated to the zclients when the
1675 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001676 return CMD_SUCCESS;
1677}
1678
1679DEFUN (ipv6_address,
1680 ipv6_address_cmd,
1681 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001682 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001683 "Set the IP address of an interface\n"
1684 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1685{
1686 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1687}
1688
1689DEFUN (no_ipv6_address,
1690 no_ipv6_address_cmd,
1691 "no ipv6 address X:X::X:X/M",
1692 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001693 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001694 "Set the IP address of an interface\n"
1695 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1696{
1697 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1698}
1699#endif /* HAVE_IPV6 */
1700
paula1ac18c2005-06-28 17:17:12 +00001701static int
paul718e3742002-12-13 20:15:29 +00001702if_config_write (struct vty *vty)
1703{
hasso52dc7ee2004-09-23 19:18:23 +00001704 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001705 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02001706 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00001707
Feng Lu471ea392015-05-22 11:40:00 +02001708 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1709 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00001710 {
1711 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001712 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001713 struct connected *ifc;
1714 struct prefix *p;
1715
paul718e3742002-12-13 20:15:29 +00001716 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02001717
1718 if (ifp->vrf_id == VRF_DEFAULT)
1719 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1720 else
1721 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1722 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001723
Christian Frankebfac8dc2013-01-24 14:04:50 +00001724 if (if_data)
1725 {
1726 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1727 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1728 }
1729
paul718e3742002-12-13 20:15:29 +00001730 if (ifp->desc)
1731 vty_out (vty, " description %s%s", ifp->desc,
1732 VTY_NEWLINE);
1733
1734 /* Assign bandwidth here to avoid unnecessary interface flap
1735 while processing config script */
1736 if (ifp->bandwidth != 0)
1737 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1738
paul2e3b2e42002-12-13 21:03:13 +00001739 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1740 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001741 else
1742 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001743
paul1eb8ef22005-04-07 07:30:20 +00001744 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001745 {
paul718e3742002-12-13 20:15:29 +00001746 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1747 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001748 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001749 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001750 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001751 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001752 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001753
paul718e3742002-12-13 20:15:29 +00001754 if (ifc->label)
1755 vty_out (vty, " label %s", ifc->label);
1756
1757 vty_out (vty, "%s", VTY_NEWLINE);
1758 }
1759 }
1760
1761 if (if_data)
1762 {
paul718e3742002-12-13 20:15:29 +00001763 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1764 vty_out (vty, " %smulticast%s",
1765 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1766 VTY_NEWLINE);
1767 }
1768
Donald Sharp64257732015-11-20 08:33:30 -05001769#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +00001770 rtadv_config_write (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -05001771#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +00001772
hassoca776982004-06-12 14:33:05 +00001773#ifdef HAVE_IRDP
1774 irdp_config_write (vty, ifp);
1775#endif /* IRDP */
1776
paul718e3742002-12-13 20:15:29 +00001777 vty_out (vty, "!%s", VTY_NEWLINE);
1778 }
1779 return 0;
1780}
1781
1782/* Allocate and initialize interface vector. */
1783void
paula1ac18c2005-06-28 17:17:12 +00001784zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001785{
1786 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001787 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1788 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1789
1790 /* Install configuration write function. */
1791 install_node (&interface_node, if_config_write);
1792
1793 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001794 install_element (VIEW_NODE, &show_interface_vrf_cmd);
1795 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
1796 install_element (VIEW_NODE, &show_interface_name_cmd);
1797 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
1798 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001799 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001800 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00001801 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001802 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
paul718e3742002-12-13 20:15:29 +00001803 install_default (INTERFACE_NODE);
1804 install_element (INTERFACE_NODE, &interface_desc_cmd);
1805 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1806 install_element (INTERFACE_NODE, &multicast_cmd);
1807 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001808 install_element (INTERFACE_NODE, &linkdetect_cmd);
1809 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001810 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1811 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1812 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1813 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1814 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1815 install_element (INTERFACE_NODE, &ip_address_cmd);
1816 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1817#ifdef HAVE_IPV6
1818 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1819 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1820#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001821#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001822 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001823 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001824#endif /* HAVE_NETLINK */
1825}