blob: 411712d56b9a2746e1b1216dd681ebf5bf8c5915 [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{
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000708#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000709 struct sockaddr_dl *sdl;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000710#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000711 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000712 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000713 struct route_node *rn;
714 struct zebra_if *zebra_if;
715
716 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000717
paul2e3b2e42002-12-13 21:03:13 +0000718 vty_out (vty, "Interface %s is ", ifp->name);
719 if (if_is_up(ifp)) {
720 vty_out (vty, "up, line protocol ");
721
722 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
723 if (if_is_running(ifp))
724 vty_out (vty, "is up%s", VTY_NEWLINE);
725 else
726 vty_out (vty, "is down%s", VTY_NEWLINE);
727 } else {
728 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
729 }
730 } else {
731 vty_out (vty, "down%s", VTY_NEWLINE);
732 }
733
Feng Lu2fc97f62015-05-22 11:39:57 +0200734 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
735
paul718e3742002-12-13 20:15:29 +0000736 if (ifp->desc)
737 vty_out (vty, " Description: %s%s", ifp->desc,
738 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000739 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000740 {
ajsd2fc8892005-04-02 18:38:43 +0000741 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000742 return;
743 }
744 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
745 {
746 vty_out(vty, " index %d inactive interface%s",
747 ifp->ifindex,
748 VTY_NEWLINE);
749 return;
750 }
751
752 vty_out (vty, " index %d metric %d mtu %d ",
753 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000754#ifdef HAVE_IPV6
755 if (ifp->mtu6 != ifp->mtu)
756 vty_out (vty, "mtu6 %d ", ifp->mtu6);
757#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000758 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
759 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000760
paul718e3742002-12-13 20:15:29 +0000761 /* Hardware address. */
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000762#ifdef HAVE_STRUCT_SOCKADDR_DL
paul718e3742002-12-13 20:15:29 +0000763 sdl = &ifp->sdl;
764 if (sdl != NULL && sdl->sdl_alen != 0)
765 {
766 int i;
767 u_char *ptr;
768
769 vty_out (vty, " HWaddr: ");
paul5b73a672004-07-23 15:26:14 +0000770 for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
771 vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
paul718e3742002-12-13 20:15:29 +0000772 vty_out (vty, "%s", VTY_NEWLINE);
773 }
774#else
775 if (ifp->hw_addr_len != 0)
776 {
777 int i;
778
779 vty_out (vty, " HWaddr: ");
780 for (i = 0; i < ifp->hw_addr_len; i++)
781 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
782 vty_out (vty, "%s", VTY_NEWLINE);
783 }
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000784#endif /* HAVE_STRUCT_SOCKADDR_DL */
paul718e3742002-12-13 20:15:29 +0000785
786 /* Bandwidth in kbps */
787 if (ifp->bandwidth != 0)
788 {
789 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
790 vty_out(vty, "%s", VTY_NEWLINE);
791 }
792
hassoeef1fe12004-10-03 18:46:08 +0000793 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000794 {
hassoeef1fe12004-10-03 18:46:08 +0000795 if (! rn->info)
796 continue;
797
paul1eb8ef22005-04-07 07:30:20 +0000798 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
799 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000800 }
801
paul1eb8ef22005-04-07 07:30:20 +0000802 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000803 {
hasso39db97e2004-10-12 20:50:58 +0000804 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
805 (connected->address->family == AF_INET6))
806 connected_dump_vty (vty, connected);
807 }
808
Donald Sharp64257732015-11-20 08:33:30 -0500809#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000810 nd_dump_vty (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -0500811#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000812
813#ifdef HAVE_PROC_NET_DEV
814 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000815 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
816 "%lu dropped%s",
817 ifp->stats.rx_packets, ifp->stats.rx_multicast,
818 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000819
hasso6f2c27a2005-01-18 13:44:35 +0000820 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000821 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000822 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
823 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000824 ifp->stats.rx_frame_errors, VTY_NEWLINE);
825
826 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000827 ifp->stats.rx_missed_errors, VTY_NEWLINE);
828
hasso6f2c27a2005-01-18 13:44:35 +0000829 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000830 ifp->stats.tx_packets, ifp->stats.tx_bytes,
831 ifp->stats.tx_dropped, VTY_NEWLINE);
832
hasso6f2c27a2005-01-18 13:44:35 +0000833 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
834 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000835 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
836 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000837 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000838
hasso6f2c27a2005-01-18 13:44:35 +0000839 vty_out (vty, " %lu window, %lu collisions%s",
840 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000841#endif /* HAVE_PROC_NET_DEV */
842
843#ifdef HAVE_NET_RT_IFLIST
844#if defined (__bsdi__) || defined (__NetBSD__)
845 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200846 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
847 " multicast packets %llu%s",
848 (unsigned long long)ifp->stats.ifi_ipackets,
849 (unsigned long long)ifp->stats.ifi_ibytes,
850 (unsigned long long)ifp->stats.ifi_iqdrops,
851 (unsigned long long)ifp->stats.ifi_imcasts,
852 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000853
David Lamparter193e78f2015-04-21 10:42:30 +0200854 vty_out (vty, " input errors %llu%s",
855 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000856
David Lamparter193e78f2015-04-21 10:42:30 +0200857 vty_out (vty, " output packets %llu, bytes %llu,"
858 " multicast packets %llu%s",
859 (unsigned long long)ifp->stats.ifi_opackets,
860 (unsigned long long)ifp->stats.ifi_obytes,
861 (unsigned long long)ifp->stats.ifi_omcasts,
862 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000863
David Lamparter193e78f2015-04-21 10:42:30 +0200864 vty_out (vty, " output errors %llu%s",
865 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000866
David Lamparter193e78f2015-04-21 10:42:30 +0200867 vty_out (vty, " collisions %llu%s",
868 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000869#else
870 /* Statistics print out using sysctl (). */
871 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
872 " multicast packets %lu%s",
873 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
874 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
875 VTY_NEWLINE);
876
877 vty_out (vty, " input errors %lu%s",
878 ifp->stats.ifi_ierrors, VTY_NEWLINE);
879
880 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
881 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
882 ifp->stats.ifi_omcasts, VTY_NEWLINE);
883
884 vty_out (vty, " output errors %lu%s",
885 ifp->stats.ifi_oerrors, VTY_NEWLINE);
886
887 vty_out (vty, " collisions %lu%s",
888 ifp->stats.ifi_collisions, VTY_NEWLINE);
889#endif /* __bsdi__ || __NetBSD__ */
890#endif /* HAVE_NET_RT_IFLIST */
891}
892
paul718e3742002-12-13 20:15:29 +0000893/* Wrapper hook point for zebra daemon so that ifindex can be set
894 * DEFUN macro not used as extract.pl HAS to ignore this
895 * See also interface_cmd in lib/if.c
896 */
897DEFUN_NOSH (zebra_interface,
898 zebra_interface_cmd,
899 "interface IFNAME",
900 "Select an interface to configure\n"
901 "Interface's name\n")
902{
903 int ret;
904 struct interface * ifp;
905
906 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +0000907 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
908 return ret;
paul718e3742002-12-13 20:15:29 +0000909
910 ifp = vty->index;
911
ajsd2fc8892005-04-02 18:38:43 +0000912 if (ifp->ifindex == IFINDEX_INTERNAL)
913 /* Is this really necessary? Shouldn't status be initialized to 0
914 in that case? */
915 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +0000916
917 return ret;
918}
919
Feng Lu471ea392015-05-22 11:40:00 +0200920ALIAS (zebra_interface,
921 zebra_interface_vrf_cmd,
922 "interface IFNAME " VRF_CMD_STR,
923 "Select an interface to configure\n"
924 "Interface's name\n"
925 VRF_CMD_HELP_STR)
926
paul718e3742002-12-13 20:15:29 +0000927struct cmd_node interface_node =
928{
929 INTERFACE_NODE,
930 "%s(config-if)# ",
931 1
932};
933
Feng Lua2854772015-05-22 11:40:01 +0200934/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +0000935DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +0200936 "show interface",
paul718e3742002-12-13 20:15:29 +0000937 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +0200938 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +0000939{
hasso52dc7ee2004-09-23 19:18:23 +0000940 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000941 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +0200942 vrf_id_t vrf_id = VRF_DEFAULT;
943
paul718e3742002-12-13 20:15:29 +0000944#ifdef HAVE_PROC_NET_DEV
945 /* If system has interface statistics via proc file system, update
946 statistics. */
947 ifstat_update_proc ();
948#endif /* HAVE_PROC_NET_DEV */
949#ifdef HAVE_NET_RT_IFLIST
950 ifstat_update_sysctl ();
951#endif /* HAVE_NET_RT_IFLIST */
952
Feng Lua2854772015-05-22 11:40:01 +0200953 if (argc > 0)
954 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +0000955
956 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +0200957 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +0000958 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +0000959
960 return CMD_SUCCESS;
961}
962
Feng Lua2854772015-05-22 11:40:01 +0200963ALIAS (show_interface,
964 show_interface_vrf_cmd,
965 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +0000966 SHOW_STR
967 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +0200968 VRF_CMD_HELP_STR)
969
970/* Show all interfaces to vty. */
971DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
972 "show interface " VRF_ALL_CMD_STR,
973 SHOW_STR
974 "Interface status and configuration\n"
975 VRF_ALL_CMD_HELP_STR)
976{
977 struct listnode *node;
978 struct interface *ifp;
979 vrf_iter_t iter;
980
981#ifdef HAVE_PROC_NET_DEV
982 /* If system has interface statistics via proc file system, update
983 statistics. */
984 ifstat_update_proc ();
985#endif /* HAVE_PROC_NET_DEV */
986#ifdef HAVE_NET_RT_IFLIST
987 ifstat_update_sysctl ();
988#endif /* HAVE_NET_RT_IFLIST */
989
990 /* All interface print. */
991 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
992 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
993 if_dump_vty (vty, ifp);
994
995 return CMD_SUCCESS;
996}
997
998/* Show specified interface to vty. */
999DEFUN (show_interface_name, show_interface_name_cmd,
1000 "show interface IFNAME",
1001 SHOW_STR
1002 "Interface status and configuration\n"
1003 "Inteface name\n")
1004{
1005 struct interface *ifp;
1006 vrf_id_t vrf_id = VRF_DEFAULT;
1007
1008#ifdef HAVE_PROC_NET_DEV
1009 /* If system has interface statistics via proc file system, update
1010 statistics. */
1011 ifstat_update_proc ();
1012#endif /* HAVE_PROC_NET_DEV */
1013#ifdef HAVE_NET_RT_IFLIST
1014 ifstat_update_sysctl ();
1015#endif /* HAVE_NET_RT_IFLIST */
1016
1017 if (argc > 1)
1018 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1019
1020 /* Specified interface print. */
1021 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1022 if (ifp == NULL)
1023 {
1024 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1025 VTY_NEWLINE);
1026 return CMD_WARNING;
1027 }
1028 if_dump_vty (vty, ifp);
1029
1030 return CMD_SUCCESS;
1031}
1032
1033ALIAS (show_interface_name,
1034 show_interface_name_vrf_cmd,
1035 "show interface IFNAME " VRF_CMD_STR,
1036 SHOW_STR
1037 "Interface status and configuration\n"
1038 "Inteface name\n"
1039 VRF_CMD_HELP_STR)
1040
1041/* Show specified interface to vty. */
1042DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1043 "show interface IFNAME " VRF_ALL_CMD_STR,
1044 SHOW_STR
1045 "Interface status and configuration\n"
1046 "Inteface name\n"
1047 VRF_ALL_CMD_HELP_STR)
1048{
1049 struct interface *ifp;
1050 vrf_iter_t iter;
1051 int found = 0;
1052
1053#ifdef HAVE_PROC_NET_DEV
1054 /* If system has interface statistics via proc file system, update
1055 statistics. */
1056 ifstat_update_proc ();
1057#endif /* HAVE_PROC_NET_DEV */
1058#ifdef HAVE_NET_RT_IFLIST
1059 ifstat_update_sysctl ();
1060#endif /* HAVE_NET_RT_IFLIST */
1061
1062 /* All interface print. */
1063 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1064 {
1065 /* Specified interface print. */
1066 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1067 if (ifp)
1068 {
1069 if_dump_vty (vty, ifp);
1070 found++;
1071 }
1072 }
1073
1074 if (!found)
1075 {
1076 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1077 return CMD_WARNING;
1078 }
1079
1080 return CMD_SUCCESS;
1081}
1082
1083static void
1084if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001085{
1086 struct listnode *node;
1087 struct interface *ifp;
1088
1089 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001090 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001091 {
1092 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001093
1094 len = vty_out (vty, "%s", ifp->name);
1095 vty_out (vty, "%*s", (16 - len), " ");
1096
1097 if (if_is_up(ifp))
1098 {
1099 vty_out (vty, "up ");
1100 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1101 {
1102 if (if_is_running(ifp))
1103 vty_out (vty, "up ");
1104 else
1105 vty_out (vty, "down ");
1106 }
1107 else
1108 {
1109 vty_out (vty, "unknown ");
1110 }
1111 }
1112 else
1113 {
1114 vty_out (vty, "down down ");
1115 }
1116
1117 if (ifp->desc)
1118 vty_out (vty, "%s", ifp->desc);
1119 vty_out (vty, "%s", VTY_NEWLINE);
1120 }
Feng Lua2854772015-05-22 11:40:01 +02001121}
1122
1123DEFUN (show_interface_desc,
1124 show_interface_desc_cmd,
1125 "show interface description",
1126 SHOW_STR
1127 "Interface status and configuration\n"
1128 "Interface description\n")
1129{
1130 vrf_id_t vrf_id = VRF_DEFAULT;
1131
1132 if (argc > 0)
1133 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1134
1135 if_show_description (vty, vrf_id);
1136
1137 return CMD_SUCCESS;
1138}
1139
1140ALIAS (show_interface_desc,
1141 show_interface_desc_vrf_cmd,
1142 "show interface description " VRF_CMD_STR,
1143 SHOW_STR
1144 "Interface status and configuration\n"
1145 "Interface description\n"
1146 VRF_CMD_HELP_STR)
1147
1148DEFUN (show_interface_desc_vrf_all,
1149 show_interface_desc_vrf_all_cmd,
1150 "show interface description " VRF_ALL_CMD_STR,
1151 SHOW_STR
1152 "Interface status and configuration\n"
1153 "Interface description\n"
1154 VRF_ALL_CMD_HELP_STR)
1155{
1156 vrf_iter_t iter;
1157
1158 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1159 if (!list_isempty (vrf_iter2iflist (iter)))
1160 {
1161 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1162 vrf_iter2id (iter),
1163 VTY_NEWLINE, VTY_NEWLINE);
1164 if_show_description (vty, vrf_iter2id (iter));
1165 }
1166
hassoed9bb6d2005-03-13 19:17:21 +00001167 return CMD_SUCCESS;
1168}
1169
paul718e3742002-12-13 20:15:29 +00001170DEFUN (multicast,
1171 multicast_cmd,
1172 "multicast",
1173 "Set multicast flag to interface\n")
1174{
1175 int ret;
1176 struct interface *ifp;
1177 struct zebra_if *if_data;
1178
1179 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001180 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001181 {
paul48b33aa2002-12-13 20:52:52 +00001182 ret = if_set_flags (ifp, IFF_MULTICAST);
1183 if (ret < 0)
1184 {
1185 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1186 return CMD_WARNING;
1187 }
1188 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001189 }
paul718e3742002-12-13 20:15:29 +00001190 if_data = ifp->info;
1191 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001192
paul718e3742002-12-13 20:15:29 +00001193 return CMD_SUCCESS;
1194}
1195
1196DEFUN (no_multicast,
1197 no_multicast_cmd,
1198 "no multicast",
1199 NO_STR
1200 "Unset multicast flag to interface\n")
1201{
1202 int ret;
1203 struct interface *ifp;
1204 struct zebra_if *if_data;
1205
1206 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001207 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001208 {
paul48b33aa2002-12-13 20:52:52 +00001209 ret = if_unset_flags (ifp, IFF_MULTICAST);
1210 if (ret < 0)
1211 {
1212 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1213 return CMD_WARNING;
1214 }
1215 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001216 }
paul718e3742002-12-13 20:15:29 +00001217 if_data = ifp->info;
1218 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1219
1220 return CMD_SUCCESS;
1221}
1222
paul2e3b2e42002-12-13 21:03:13 +00001223DEFUN (linkdetect,
1224 linkdetect_cmd,
1225 "link-detect",
1226 "Enable link detection on interface\n")
1227{
paul2e3b2e42002-12-13 21:03:13 +00001228 struct interface *ifp;
1229 int if_was_operative;
1230
1231 ifp = (struct interface *) vty->index;
1232 if_was_operative = if_is_operative(ifp);
1233 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1234
1235 /* When linkdetection is enabled, if might come down */
1236 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
1237
1238 /* FIXME: Will defer status change forwarding if interface
1239 does not come down! */
1240
1241 return CMD_SUCCESS;
1242}
1243
1244
1245DEFUN (no_linkdetect,
1246 no_linkdetect_cmd,
1247 "no link-detect",
1248 NO_STR
1249 "Disable link detection on interface\n")
1250{
paul2e3b2e42002-12-13 21:03:13 +00001251 struct interface *ifp;
1252 int if_was_operative;
1253
1254 ifp = (struct interface *) vty->index;
1255 if_was_operative = if_is_operative(ifp);
1256 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1257
1258 /* Interface may come up after disabling link detection */
1259 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1260
1261 /* FIXME: see linkdetect_cmd */
1262
1263 return CMD_SUCCESS;
1264}
1265
paul718e3742002-12-13 20:15:29 +00001266DEFUN (shutdown_if,
1267 shutdown_if_cmd,
1268 "shutdown",
1269 "Shutdown the selected interface\n")
1270{
1271 int ret;
1272 struct interface *ifp;
1273 struct zebra_if *if_data;
1274
1275 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001276 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001277 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001278 ret = if_unset_flags (ifp, IFF_UP);
1279 if (ret < 0)
1280 {
1281 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1282 return CMD_WARNING;
1283 }
1284 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001285 }
paul718e3742002-12-13 20:15:29 +00001286 if_data = ifp->info;
1287 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1288
1289 return CMD_SUCCESS;
1290}
1291
1292DEFUN (no_shutdown_if,
1293 no_shutdown_if_cmd,
1294 "no shutdown",
1295 NO_STR
1296 "Shutdown the selected interface\n")
1297{
1298 int ret;
1299 struct interface *ifp;
1300 struct zebra_if *if_data;
1301
1302 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001303
1304 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001305 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001306 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1307 if (ret < 0)
1308 {
1309 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1310 return CMD_WARNING;
1311 }
1312 if_refresh (ifp);
1313
1314 /* Some addresses (in particular, IPv6 addresses on Linux) get
1315 * removed when the interface goes down. They need to be readded.
1316 */
1317 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001318 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001319
paul718e3742002-12-13 20:15:29 +00001320 if_data = ifp->info;
1321 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1322
1323 return CMD_SUCCESS;
1324}
1325
1326DEFUN (bandwidth_if,
1327 bandwidth_if_cmd,
1328 "bandwidth <1-10000000>",
1329 "Set bandwidth informational parameter\n"
1330 "Bandwidth in kilobits\n")
1331{
1332 struct interface *ifp;
1333 unsigned int bandwidth;
1334
1335 ifp = (struct interface *) vty->index;
1336 bandwidth = strtol(argv[0], NULL, 10);
1337
1338 /* bandwidth range is <1-10000000> */
1339 if (bandwidth < 1 || bandwidth > 10000000)
1340 {
1341 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1342 return CMD_WARNING;
1343 }
1344
1345 ifp->bandwidth = bandwidth;
1346
1347 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001348 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001349 zebra_interface_up_update (ifp);
1350
1351 return CMD_SUCCESS;
1352}
1353
1354DEFUN (no_bandwidth_if,
1355 no_bandwidth_if_cmd,
1356 "no bandwidth",
1357 NO_STR
1358 "Set bandwidth informational parameter\n")
1359{
1360 struct interface *ifp;
1361
1362 ifp = (struct interface *) vty->index;
1363
1364 ifp->bandwidth = 0;
1365
1366 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001367 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001368 zebra_interface_up_update (ifp);
1369
1370 return CMD_SUCCESS;
1371}
1372
1373ALIAS (no_bandwidth_if,
1374 no_bandwidth_if_val_cmd,
1375 "no bandwidth <1-10000000>",
1376 NO_STR
1377 "Set bandwidth informational parameter\n"
1378 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001379
paula1ac18c2005-06-28 17:17:12 +00001380static int
hasso39db97e2004-10-12 20:50:58 +00001381ip_address_install (struct vty *vty, struct interface *ifp,
1382 const char *addr_str, const char *peer_str,
1383 const char *label)
paul718e3742002-12-13 20:15:29 +00001384{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001385 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001386 struct prefix_ipv4 cp;
1387 struct connected *ifc;
1388 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00001389 int ret;
1390
Christian Frankebfac8dc2013-01-24 14:04:50 +00001391 if_data = ifp->info;
1392
paul718e3742002-12-13 20:15:29 +00001393 ret = str2prefix_ipv4 (addr_str, &cp);
1394 if (ret <= 0)
1395 {
1396 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1397 return CMD_WARNING;
1398 }
1399
paulca162182005-09-12 16:58:52 +00001400 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001401 if (! ifc)
1402 {
1403 ifc = connected_new ();
1404 ifc->ifp = ifp;
1405
1406 /* Address. */
1407 p = prefix_ipv4_new ();
1408 *p = cp;
1409 ifc->address = (struct prefix *) p;
1410
1411 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00001412 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00001413 {
1414 p = prefix_ipv4_new ();
1415 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00001416 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00001417 ifc->destination = (struct prefix *) p;
1418 }
1419
paul718e3742002-12-13 20:15:29 +00001420 /* Label. */
1421 if (label)
paul0752ef02005-11-03 12:35:21 +00001422 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001423
1424 /* Add to linked list. */
1425 listnode_add (ifp->connected, ifc);
1426 }
1427
1428 /* This address is configured from zebra. */
1429 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1430 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1431
1432 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001433 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001434 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1435 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001436 {
1437 /* Some system need to up the interface to set IP address. */
1438 if (! if_is_up (ifp))
1439 {
1440 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1441 if_refresh (ifp);
1442 }
1443
1444 ret = if_set_prefix (ifp, ifc);
1445 if (ret < 0)
1446 {
1447 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001448 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001449 return CMD_WARNING;
1450 }
1451
Christian Frankef7f740f2013-01-24 14:04:48 +00001452 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001453 /* The address will be advertised to zebra clients when the notification
1454 * from the kernel has been received.
1455 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00001456 }
1457
1458 return CMD_SUCCESS;
1459}
1460
paula1ac18c2005-06-28 17:17:12 +00001461static int
hasso39db97e2004-10-12 20:50:58 +00001462ip_address_uninstall (struct vty *vty, struct interface *ifp,
1463 const char *addr_str, const char *peer_str,
1464 const char *label)
paul718e3742002-12-13 20:15:29 +00001465{
1466 struct prefix_ipv4 cp;
1467 struct connected *ifc;
1468 int ret;
1469
1470 /* Convert to prefix structure. */
1471 ret = str2prefix_ipv4 (addr_str, &cp);
1472 if (ret <= 0)
1473 {
1474 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1475 return CMD_WARNING;
1476 }
1477
1478 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001479 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001480 if (! ifc)
1481 {
1482 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1483 return CMD_WARNING;
1484 }
1485
1486 /* This is not configured address. */
1487 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1488 return CMD_WARNING;
1489
Paul Jakma74ecdc92006-06-15 18:10:47 +00001490 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1491
paul718e3742002-12-13 20:15:29 +00001492 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001493 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001494 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1495 {
1496 listnode_delete (ifp->connected, ifc);
1497 connected_free (ifc);
1498 return CMD_WARNING;
1499 }
1500
1501 /* This is real route. */
1502 ret = if_unset_prefix (ifp, ifc);
1503 if (ret < 0)
1504 {
1505 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001506 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001507 return CMD_WARNING;
1508 }
Christian Frankef7f740f2013-01-24 14:04:48 +00001509 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001510 /* we will receive a kernel notification about this route being removed.
1511 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00001512 return CMD_SUCCESS;
1513}
1514
1515DEFUN (ip_address,
1516 ip_address_cmd,
1517 "ip address A.B.C.D/M",
1518 "Interface Internet Protocol config commands\n"
1519 "Set the IP address of an interface\n"
1520 "IP address (e.g. 10.0.0.1/8)\n")
1521{
hassoeef1fe12004-10-03 18:46:08 +00001522 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001523}
1524
1525DEFUN (no_ip_address,
1526 no_ip_address_cmd,
1527 "no ip address A.B.C.D/M",
1528 NO_STR
1529 "Interface Internet Protocol config commands\n"
1530 "Set the IP address of an interface\n"
1531 "IP Address (e.g. 10.0.0.1/8)")
1532{
hassoeef1fe12004-10-03 18:46:08 +00001533 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00001534}
1535
1536#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001537DEFUN (ip_address_label,
1538 ip_address_label_cmd,
1539 "ip address A.B.C.D/M label LINE",
1540 "Interface Internet Protocol config commands\n"
1541 "Set the IP address of an interface\n"
1542 "IP address (e.g. 10.0.0.1/8)\n"
1543 "Label of this address\n"
1544 "Label\n")
1545{
hassoeef1fe12004-10-03 18:46:08 +00001546 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001547}
1548
1549DEFUN (no_ip_address_label,
1550 no_ip_address_label_cmd,
1551 "no ip address A.B.C.D/M label LINE",
1552 NO_STR
1553 "Interface Internet Protocol config commands\n"
1554 "Set the IP address of an interface\n"
1555 "IP address (e.g. 10.0.0.1/8)\n"
1556 "Label of this address\n"
1557 "Label\n")
1558{
hassoeef1fe12004-10-03 18:46:08 +00001559 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00001560}
1561#endif /* HAVE_NETLINK */
1562
1563#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00001564static int
hasso39db97e2004-10-12 20:50:58 +00001565ipv6_address_install (struct vty *vty, struct interface *ifp,
1566 const char *addr_str, const char *peer_str,
1567 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00001568{
Christian Frankebfac8dc2013-01-24 14:04:50 +00001569 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00001570 struct prefix_ipv6 cp;
1571 struct connected *ifc;
1572 struct prefix_ipv6 *p;
1573 int ret;
1574
Christian Frankebfac8dc2013-01-24 14:04:50 +00001575 if_data = ifp->info;
1576
paul718e3742002-12-13 20:15:29 +00001577 ret = str2prefix_ipv6 (addr_str, &cp);
1578 if (ret <= 0)
1579 {
1580 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1581 return CMD_WARNING;
1582 }
1583
paulca162182005-09-12 16:58:52 +00001584 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001585 if (! ifc)
1586 {
1587 ifc = connected_new ();
1588 ifc->ifp = ifp;
1589
1590 /* Address. */
1591 p = prefix_ipv6_new ();
1592 *p = cp;
1593 ifc->address = (struct prefix *) p;
1594
1595 /* Secondary. */
1596 if (secondary)
1597 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
1598
1599 /* Label. */
1600 if (label)
paul0752ef02005-11-03 12:35:21 +00001601 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00001602
1603 /* Add to linked list. */
1604 listnode_add (ifp->connected, ifc);
1605 }
1606
1607 /* This address is configured from zebra. */
1608 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1609 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1610
1611 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001612 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00001613 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
1614 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00001615 {
1616 /* Some system need to up the interface to set IP address. */
1617 if (! if_is_up (ifp))
1618 {
1619 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1620 if_refresh (ifp);
1621 }
1622
1623 ret = if_prefix_add_ipv6 (ifp, ifc);
1624
1625 if (ret < 0)
1626 {
1627 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001628 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001629 return CMD_WARNING;
1630 }
1631
Christian Frankef7f740f2013-01-24 14:04:48 +00001632 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001633 /* The address will be advertised to zebra clients when the notification
1634 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00001635 }
1636
1637 return CMD_SUCCESS;
1638}
1639
paula1ac18c2005-06-28 17:17:12 +00001640static int
hasso39db97e2004-10-12 20:50:58 +00001641ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
1642 const char *addr_str, const char *peer_str,
1643 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00001644{
1645 struct prefix_ipv6 cp;
1646 struct connected *ifc;
1647 int ret;
1648
1649 /* Convert to prefix structure. */
1650 ret = str2prefix_ipv6 (addr_str, &cp);
1651 if (ret <= 0)
1652 {
1653 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
1654 return CMD_WARNING;
1655 }
1656
1657 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00001658 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00001659 if (! ifc)
1660 {
1661 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
1662 return CMD_WARNING;
1663 }
1664
1665 /* This is not configured address. */
1666 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1667 return CMD_WARNING;
1668
Christian Franke676e1a02013-01-24 14:04:45 +00001669 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
1670
paul718e3742002-12-13 20:15:29 +00001671 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00001672 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00001673 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1674 {
1675 listnode_delete (ifp->connected, ifc);
1676 connected_free (ifc);
1677 return CMD_WARNING;
1678 }
1679
1680 /* This is real route. */
1681 ret = if_prefix_delete_ipv6 (ifp, ifc);
1682 if (ret < 0)
1683 {
1684 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00001685 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001686 return CMD_WARNING;
1687 }
1688
Christian Frankef7f740f2013-01-24 14:04:48 +00001689 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00001690 /* This information will be propagated to the zclients when the
1691 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00001692 return CMD_SUCCESS;
1693}
1694
1695DEFUN (ipv6_address,
1696 ipv6_address_cmd,
1697 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00001698 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001699 "Set the IP address of an interface\n"
1700 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1701{
1702 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
1703}
1704
1705DEFUN (no_ipv6_address,
1706 no_ipv6_address_cmd,
1707 "no ipv6 address X:X::X:X/M",
1708 NO_STR
hassoe23949c2004-03-11 15:54:02 +00001709 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00001710 "Set the IP address of an interface\n"
1711 "IPv6 address (e.g. 3ffe:506::1/48)\n")
1712{
1713 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
1714}
1715#endif /* HAVE_IPV6 */
1716
paula1ac18c2005-06-28 17:17:12 +00001717static int
paul718e3742002-12-13 20:15:29 +00001718if_config_write (struct vty *vty)
1719{
hasso52dc7ee2004-09-23 19:18:23 +00001720 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001721 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02001722 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00001723
Feng Lu471ea392015-05-22 11:40:00 +02001724 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1725 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00001726 {
1727 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00001728 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00001729 struct connected *ifc;
1730 struct prefix *p;
1731
paul718e3742002-12-13 20:15:29 +00001732 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02001733
1734 if (ifp->vrf_id == VRF_DEFAULT)
1735 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
1736 else
1737 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
1738 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001739
Christian Frankebfac8dc2013-01-24 14:04:50 +00001740 if (if_data)
1741 {
1742 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
1743 vty_out (vty, " shutdown%s", VTY_NEWLINE);
1744 }
1745
paul718e3742002-12-13 20:15:29 +00001746 if (ifp->desc)
1747 vty_out (vty, " description %s%s", ifp->desc,
1748 VTY_NEWLINE);
1749
1750 /* Assign bandwidth here to avoid unnecessary interface flap
1751 while processing config script */
1752 if (ifp->bandwidth != 0)
1753 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
1754
paul2e3b2e42002-12-13 21:03:13 +00001755 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1756 vty_out(vty, " link-detect%s", VTY_NEWLINE);
David Lamparter4c421212015-03-02 06:42:11 +01001757 else
1758 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
paul2e3b2e42002-12-13 21:03:13 +00001759
paul1eb8ef22005-04-07 07:30:20 +00001760 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00001761 {
paul718e3742002-12-13 20:15:29 +00001762 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
1763 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07001764 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00001765 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03001766 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00001767 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03001768 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00001769
paul718e3742002-12-13 20:15:29 +00001770 if (ifc->label)
1771 vty_out (vty, " label %s", ifc->label);
1772
1773 vty_out (vty, "%s", VTY_NEWLINE);
1774 }
1775 }
1776
1777 if (if_data)
1778 {
paul718e3742002-12-13 20:15:29 +00001779 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
1780 vty_out (vty, " %smulticast%s",
1781 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
1782 VTY_NEWLINE);
1783 }
1784
Donald Sharp64257732015-11-20 08:33:30 -05001785#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +00001786 rtadv_config_write (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -05001787#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +00001788
hassoca776982004-06-12 14:33:05 +00001789#ifdef HAVE_IRDP
1790 irdp_config_write (vty, ifp);
1791#endif /* IRDP */
1792
paul718e3742002-12-13 20:15:29 +00001793 vty_out (vty, "!%s", VTY_NEWLINE);
1794 }
1795 return 0;
1796}
1797
1798/* Allocate and initialize interface vector. */
1799void
paula1ac18c2005-06-28 17:17:12 +00001800zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00001801{
1802 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00001803 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
1804 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
1805
1806 /* Install configuration write function. */
1807 install_node (&interface_node, if_config_write);
1808
1809 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001810 install_element (VIEW_NODE, &show_interface_vrf_cmd);
1811 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
1812 install_element (VIEW_NODE, &show_interface_name_cmd);
1813 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
1814 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001815 install_element (ENABLE_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001816 install_element (ENABLE_NODE, &show_interface_vrf_cmd);
1817 install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
1818 install_element (ENABLE_NODE, &show_interface_name_cmd);
1819 install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
1820 install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
hassoed9bb6d2005-03-13 19:17:21 +00001821 install_element (ENABLE_NODE, &show_interface_desc_cmd);
Feng Lua2854772015-05-22 11:40:01 +02001822 install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
1823 install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00001824 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001825 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00001826 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02001827 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
paul718e3742002-12-13 20:15:29 +00001828 install_default (INTERFACE_NODE);
1829 install_element (INTERFACE_NODE, &interface_desc_cmd);
1830 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
1831 install_element (INTERFACE_NODE, &multicast_cmd);
1832 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00001833 install_element (INTERFACE_NODE, &linkdetect_cmd);
1834 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00001835 install_element (INTERFACE_NODE, &shutdown_if_cmd);
1836 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
1837 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
1838 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
1839 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
1840 install_element (INTERFACE_NODE, &ip_address_cmd);
1841 install_element (INTERFACE_NODE, &no_ip_address_cmd);
1842#ifdef HAVE_IPV6
1843 install_element (INTERFACE_NODE, &ipv6_address_cmd);
1844 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
1845#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00001846#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00001847 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001848 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00001849#endif /* HAVE_NETLINK */
1850}