blob: 75597951c3f325febd8ad0027dbbe3ec53318243 [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"
Christian Franke581ecbf2016-05-03 19:59:43 +020036#include "command.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "zebra/interface.h"
39#include "zebra/rtadv.h"
40#include "zebra/rib.h"
41#include "zebra/zserv.h"
42#include "zebra/redistribute.h"
43#include "zebra/debug.h"
hassoca776982004-06-12 14:33:05 +000044#include "zebra/irdp.h"
paul718e3742002-12-13 20:15:29 +000045
Donald Sharp64257732015-11-20 08:33:30 -050046#if defined (HAVE_RTADV)
Chris Caputob60668d2009-05-03 04:40:57 +000047/* Order is intentional. Matches RFC4191. This array is also used for
48 command matching, so only modify with care. */
49const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
Donald Sharp64257732015-11-20 08:33:30 -050050#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +000051
Paul Jakma8f4269d2015-09-18 11:50:33 +010052/* We don't have a tidy top-level instance object for zebra, or interfaces */
53static struct zebra_if_defaults zif_defaults = {
54 .linkdetect = IF_LINKDETECT_UNSPEC,
55};
56
57/* helper only for if_zebra_linkdetect */
58static void
59if_zebra_linkdetect_set_val (struct interface *ifp, zebra_if_linkdetect val)
60{
61 switch (val)
62 {
63 case IF_LINKDETECT_ON:
64 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
65 break;
66 case IF_LINKDETECT_OFF:
67 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
68 break;
69 default: break;
70 }
71}
72
73static void
74if_zebra_linkdetect_set (struct interface *ifp)
75{
76 struct zebra_if *zif = ifp->info;
77 assert (zif != NULL);
78 int if_was_operative = if_is_operative(ifp);
79
80 /* If user has explicitly configured for the interface, let that set */
81 if (zif->linkdetect != IF_LINKDETECT_UNSPEC)
82 if_zebra_linkdetect_set_val (ifp, zif->linkdetect);
83 else
84 {
85 /* general compiled in default is to set */
86 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
87 /* but user can specify a default too */
88 if_zebra_linkdetect_set_val (ifp, zif_defaults.linkdetect);
89 }
90 /* When linkdetection is enabled, interface might come down */
91 if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
92 /* Alternatively, it may come up after disabling link detection */
93 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
94}
95
paul718e3742002-12-13 20:15:29 +000096/* Called when new interface is added. */
paula1ac18c2005-06-28 17:17:12 +000097static int
paul718e3742002-12-13 20:15:29 +000098if_zebra_new_hook (struct interface *ifp)
99{
100 struct zebra_if *zebra_if;
101
Stephen Hemminger393deb92008-08-18 14:13:29 -0700102 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
paul718e3742002-12-13 20:15:29 +0000103
104 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
Christian Frankebfac8dc2013-01-24 14:04:50 +0000105 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
paul718e3742002-12-13 20:15:29 +0000106
Paul Jakma8f4269d2015-09-18 11:50:33 +0100107 switch (zif_defaults.linkdetect)
108 {
109 case IF_LINKDETECT_OFF:
110 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
111 break;
112 case IF_LINKDETECT_UNSPEC:
113 case IF_LINKDETECT_ON:
114 default:
115 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
116 break;
117 }
118
Donald Sharp64257732015-11-20 08:33:30 -0500119#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000120 {
121 /* Set default router advertise values. */
122 struct rtadvconf *rtadv;
123
124 rtadv = &zebra_if->rtadv;
125
126 rtadv->AdvSendAdvertisements = 0;
127 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
128 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
129 rtadv->AdvIntervalTimer = 0;
130 rtadv->AdvManagedFlag = 0;
131 rtadv->AdvOtherConfigFlag = 0;
vincent7cee1bb2005-03-25 13:08:53 +0000132 rtadv->AdvHomeAgentFlag = 0;
paul718e3742002-12-13 20:15:29 +0000133 rtadv->AdvLinkMTU = 0;
134 rtadv->AdvReachableTime = 0;
135 rtadv->AdvRetransTimer = 0;
136 rtadv->AdvCurHopLimit = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +0400137 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
vincent7cee1bb2005-03-25 13:08:53 +0000138 rtadv->HomeAgentPreference = 0;
Denis Ovsienkod660f692011-12-30 21:55:49 +0400139 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
vincent7cee1bb2005-03-25 13:08:53 +0000140 rtadv->AdvIntervalOption = 0;
Chris Caputob60668d2009-05-03 04:40:57 +0000141 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
paul718e3742002-12-13 20:15:29 +0000142
143 rtadv->AdvPrefixList = list_new ();
144 }
Donald Sharp64257732015-11-20 08:33:30 -0500145#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000146
hassoeef1fe12004-10-03 18:46:08 +0000147 /* Initialize installed address chains tree. */
148 zebra_if->ipv4_subnets = route_table_init ();
149
paul718e3742002-12-13 20:15:29 +0000150 ifp->info = zebra_if;
151 return 0;
152}
153
154/* Called when interface is deleted. */
paula1ac18c2005-06-28 17:17:12 +0000155static int
paul718e3742002-12-13 20:15:29 +0000156if_zebra_delete_hook (struct interface *ifp)
157{
hassoeef1fe12004-10-03 18:46:08 +0000158 struct zebra_if *zebra_if;
159
paul718e3742002-12-13 20:15:29 +0000160 if (ifp->info)
hassoeef1fe12004-10-03 18:46:08 +0000161 {
162 zebra_if = ifp->info;
163
164 /* Free installed address chains tree. */
165 if (zebra_if->ipv4_subnets)
166 route_table_finish (zebra_if->ipv4_subnets);
167
168 XFREE (MTYPE_TMP, zebra_if);
169 }
170
171 return 0;
172}
173
174/* Tie an interface address to its derived subnet list of addresses. */
175int
176if_subnet_add (struct interface *ifp, struct connected *ifc)
177{
178 struct route_node *rn;
179 struct zebra_if *zebra_if;
180 struct prefix cp;
181 struct list *addr_list;
182
183 assert (ifp && ifp->info && ifc);
184 zebra_if = ifp->info;
185
186 /* Get address derived subnet node and associated address list, while marking
187 address secondary attribute appropriately. */
188 cp = *ifc->address;
189 apply_mask (&cp);
190 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
191
192 if ((addr_list = rn->info))
193 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
194 else
195 {
196 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
197 rn->info = addr_list = list_new ();
198 route_lock_node (rn);
199 }
200
201 /* Tie address at the tail of address list. */
202 listnode_add (addr_list, ifc);
203
204 /* Return list element count. */
205 return (addr_list->count);
206}
207
208/* Untie an interface address from its derived subnet list of addresses. */
209int
210if_subnet_delete (struct interface *ifp, struct connected *ifc)
211{
212 struct route_node *rn;
213 struct zebra_if *zebra_if;
214 struct list *addr_list;
215
216 assert (ifp && ifp->info && ifc);
217 zebra_if = ifp->info;
218
219 /* Get address derived subnet node. */
220 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
221 if (! (rn && rn->info))
Christian Franke9db047f2013-01-24 14:04:44 +0000222 {
223 zlog_warn("Trying to remove an address from an unknown subnet."
224 " (please report this bug)");
225 return -1;
226 }
hassoeef1fe12004-10-03 18:46:08 +0000227 route_unlock_node (rn);
228
229 /* Untie address from subnet's address list. */
230 addr_list = rn->info;
Christian Franke9db047f2013-01-24 14:04:44 +0000231
232 /* Deleting an address that is not registered is a bug.
233 * In any case, we shouldn't decrement the lock counter if the address
234 * is unknown. */
235 if (!listnode_lookup(addr_list, ifc))
236 {
237 zlog_warn("Trying to remove an address from a subnet where it is not"
238 " currently registered. (please report this bug)");
239 return -1;
240 }
241
hassoeef1fe12004-10-03 18:46:08 +0000242 listnode_delete (addr_list, ifc);
243 route_unlock_node (rn);
244
245 /* Return list element count, if not empty. */
246 if (addr_list->count)
247 {
248 /* If deleted address is primary, mark subsequent one as such and distribute. */
249 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
250 {
Olivier Dugeon15773a82016-04-19 18:29:55 +0200251 ifc = listgetdata ((struct listnode *)listhead (addr_list));
hassoeef1fe12004-10-03 18:46:08 +0000252 zebra_interface_address_delete_update (ifp, ifc);
253 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
Christian Franke02b48052013-01-24 14:04:49 +0000254 /* XXX: Linux kernel removes all the secondary addresses when the primary
255 * address is removed. We could try to work around that, though this is
256 * non-trivial. */
hassoeef1fe12004-10-03 18:46:08 +0000257 zebra_interface_address_add_update (ifp, ifc);
258 }
259
260 return addr_list->count;
261 }
262
263 /* Otherwise, free list and route node. */
264 list_free (addr_list);
265 rn->info = NULL;
266 route_unlock_node (rn);
267
paul718e3742002-12-13 20:15:29 +0000268 return 0;
269}
270
paul5c78b3d2006-01-25 04:31:40 +0000271/* if_flags_mangle: A place for hacks that require mangling
272 * or tweaking the interface flags.
273 *
274 * ******************** Solaris flags hacks **************************
275 *
276 * Solaris IFF_UP flag reflects only the primary interface as the
277 * routing socket only sends IFINFO for the primary interface. Hence
278 * ~IFF_UP does not per se imply all the logical interfaces are also
279 * down - which we only know of as addresses. Instead we must determine
280 * whether the interface really is up or not according to how many
281 * addresses are still attached. (Solaris always sends RTM_DELADDR if
282 * an interface, logical or not, goes ~IFF_UP).
283 *
284 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
285 * are addresses left in struct connected, not just the actual underlying
286 * IFF_UP flag.
287 *
288 * We must hence remember the real state of IFF_UP, which we do in
289 * struct zebra_if.primary_state.
290 *
291 * Setting IFF_UP within zebra to administratively shutdown the
292 * interface will affect only the primary interface/address on Solaris.
293 ************************End Solaris flags hacks ***********************
294 */
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100295static void
paul5c78b3d2006-01-25 04:31:40 +0000296if_flags_mangle (struct interface *ifp, uint64_t *newflags)
297{
298#ifdef SUNOS_5
299 struct zebra_if *zif = ifp->info;
300
301 zif->primary_state = *newflags & (IFF_UP & 0xff);
302
303 if (CHECK_FLAG (zif->primary_state, IFF_UP)
304 || listcount(ifp->connected) > 0)
305 SET_FLAG (*newflags, IFF_UP);
306 else
307 UNSET_FLAG (*newflags, IFF_UP);
308#endif /* SUNOS_5 */
309}
310
311/* Update the flags field of the ifp with the new flag set provided.
312 * Take whatever actions are required for any changes in flags we care
313 * about.
314 *
315 * newflags should be the raw value, as obtained from the OS.
316 */
317void
318if_flags_update (struct interface *ifp, uint64_t newflags)
319{
320 if_flags_mangle (ifp, &newflags);
321
322 if (if_is_operative (ifp))
323 {
324 /* operative -> inoperative? */
325 ifp->flags = newflags;
326 if (!if_is_operative (ifp))
327 if_down (ifp);
328 }
329 else
330 {
331 /* inoperative -> operative? */
332 ifp->flags = newflags;
333 if (if_is_operative (ifp))
334 if_up (ifp);
335 }
336}
337
paul718e3742002-12-13 20:15:29 +0000338/* Wake up configured address if it is not in current kernel
339 address. */
paula1ac18c2005-06-28 17:17:12 +0000340static void
paul718e3742002-12-13 20:15:29 +0000341if_addr_wakeup (struct interface *ifp)
342{
paul1eb8ef22005-04-07 07:30:20 +0000343 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000344 struct connected *ifc;
345 struct prefix *p;
346 int ret;
347
paul1eb8ef22005-04-07 07:30:20 +0000348 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
paul718e3742002-12-13 20:15:29 +0000349 {
paul718e3742002-12-13 20:15:29 +0000350 p = ifc->address;
351
352 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
Christian Frankef7f740f2013-01-24 14:04:48 +0000353 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
paul718e3742002-12-13 20:15:29 +0000354 {
355 /* Address check. */
356 if (p->family == AF_INET)
357 {
358 if (! if_is_up (ifp))
359 {
Christian Franke02b48052013-01-24 14:04:49 +0000360 /* Assume zebra is configured like following:
361 *
362 * interface gre0
363 * ip addr 192.0.2.1/24
364 * !
365 *
366 * As soon as zebra becomes first aware that gre0 exists in the
367 * kernel, it will set gre0 up and configure its addresses.
368 *
369 * (This may happen at startup when the interface already exists
370 * or during runtime when the interface is added to the kernel)
371 *
372 * XXX: IRDP code is calling here via if_add_update - this seems
373 * somewhat weird.
374 * XXX: RUNNING is not a settable flag on any system
375 * I (paulj) am aware of.
376 */
paul718e3742002-12-13 20:15:29 +0000377 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
378 if_refresh (ifp);
379 }
380
381 ret = if_set_prefix (ifp, ifc);
382 if (ret < 0)
383 {
384 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000385 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000386 continue;
387 }
hassoeef1fe12004-10-03 18:46:08 +0000388
Christian Frankef7f740f2013-01-24 14:04:48 +0000389 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000390 /* The address will be advertised to zebra clients when the notification
391 * from the kernel has been received.
392 * It will also be added to the interface's subnet list then. */
paul718e3742002-12-13 20:15:29 +0000393 }
394#ifdef HAVE_IPV6
395 if (p->family == AF_INET6)
396 {
397 if (! if_is_up (ifp))
398 {
Christian Franke02b48052013-01-24 14:04:49 +0000399 /* See long comment above */
paul718e3742002-12-13 20:15:29 +0000400 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
401 if_refresh (ifp);
402 }
403
404 ret = if_prefix_add_ipv6 (ifp, ifc);
405 if (ret < 0)
406 {
407 zlog_warn ("Can't set interface's address: %s",
ajs6099b3b2004-11-20 02:06:59 +0000408 safe_strerror(errno));
paul718e3742002-12-13 20:15:29 +0000409 continue;
410 }
Christian Franke02b48052013-01-24 14:04:49 +0000411
Christian Frankef7f740f2013-01-24 14:04:48 +0000412 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +0000413 /* The address will be advertised to zebra clients when the notification
414 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +0000415 }
416#endif /* HAVE_IPV6 */
417 }
418 }
419}
420
Christian Franke581ecbf2016-05-03 19:59:43 +0200421static void if_count_up(struct zebra_if *zif)
422{
423 event_counter_inc(&zif->up_events);
424}
425
426static void if_count_down(struct zebra_if *zif)
427{
428 event_counter_inc(&zif->down_events);
429}
430
431void
432if_startup_count_up (void)
433{
434 vrf_iter_t iter;
435 struct interface *ifp;
436 struct zebra_if *zif;
437 struct listnode *node;
438
439 for (iter = vrf_first(); iter != VRF_ITER_INVALID; iter = vrf_next(iter))
440 {
441 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist(iter), node, ifp))
442 {
443 zif = ifp->info;
444 if (!zif->up_events.count && if_is_operative(ifp))
445 if_count_up(zif);
446 }
447 }
448}
449
paul718e3742002-12-13 20:15:29 +0000450/* Handle interface addition */
451void
452if_add_update (struct interface *ifp)
453{
paul48b33aa2002-12-13 20:52:52 +0000454 struct zebra_if *if_data;
455
456 if_data = ifp->info;
Morgan Stewartc8394ac2015-09-17 19:04:30 -0400457 assert(if_data);
458
paul48b33aa2002-12-13 20:52:52 +0000459 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
460 if_set_flags (ifp, IFF_MULTICAST);
461 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
462 if_unset_flags (ifp, IFF_MULTICAST);
463
paul718e3742002-12-13 20:15:29 +0000464 zebra_interface_add_update (ifp);
465
466 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
467 {
468 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
469
Christian Frankebfac8dc2013-01-24 14:04:50 +0000470 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
471 {
472 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200473 zlog_debug ("interface %s vrf %u index %d is shutdown. "
474 "Won't wake it up.",
475 ifp->name, ifp->vrf_id, ifp->ifindex);
Christian Frankebfac8dc2013-01-24 14:04:50 +0000476 return;
477 }
478
paul718e3742002-12-13 20:15:29 +0000479 if_addr_wakeup (ifp);
480
481 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200482 zlog_debug ("interface %s vrf %u index %d becomes active.",
483 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000484 }
485 else
486 {
487 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200488 zlog_debug ("interface %s vrf %u index %d is added.",
489 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000490 }
Christian Franke581ecbf2016-05-03 19:59:43 +0200491
492 if (host_config_get())
493 {
494 /* If configuration and therefore link-detect have already been
495 * loaded, count an initial up event when new interfaces are added
496 * in up state.
497 * If configuration has not been loaded yet, this is handled by
498 * if_startup_count_up which is called after reading the config. */
499 if (!if_data->up_events.count && if_is_operative(ifp))
500 if_count_up(if_data);
501 }
paul718e3742002-12-13 20:15:29 +0000502}
503
paul6eb88272005-07-29 14:36:00 +0000504/* Handle an interface delete event */
paul718e3742002-12-13 20:15:29 +0000505void
506if_delete_update (struct interface *ifp)
507{
paul718e3742002-12-13 20:15:29 +0000508 struct connected *ifc;
509 struct prefix *p;
hassoeef1fe12004-10-03 18:46:08 +0000510 struct route_node *rn;
511 struct zebra_if *zebra_if;
hassoeef1fe12004-10-03 18:46:08 +0000512
513 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000514
515 if (if_is_up(ifp))
516 {
Feng Lu2fc97f62015-05-22 11:39:57 +0200517 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
518 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000519 return;
520 }
521
522 /* Mark interface as inactive */
523 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
524
525 if (IS_ZEBRA_DEBUG_KERNEL)
Feng Lu2fc97f62015-05-22 11:39:57 +0200526 zlog_debug ("interface %s vrf %u index %d is now inactive.",
527 ifp->name, ifp->vrf_id, ifp->ifindex);
paul718e3742002-12-13 20:15:29 +0000528
529 /* Delete connected routes from the kernel. */
530 if (ifp->connected)
531 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000532 struct listnode *node;
533 struct listnode *last = NULL;
534
hassoeef1fe12004-10-03 18:46:08 +0000535 while ((node = (last ? last->next : listhead (ifp->connected))))
paul718e3742002-12-13 20:15:29 +0000536 {
paul1eb8ef22005-04-07 07:30:20 +0000537 ifc = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000538 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000539
Paul Jakmabeb56332006-05-11 13:28:05 +0000540 if (p->family == AF_INET
541 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
hassoeef1fe12004-10-03 18:46:08 +0000542 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000543 struct listnode *anode;
544 struct listnode *next;
545 struct listnode *first;
546 struct list *addr_list;
547
hassoeef1fe12004-10-03 18:46:08 +0000548 route_unlock_node (rn);
549 addr_list = (struct list *) rn->info;
550
551 /* Remove addresses, secondaries first. */
552 first = listhead (addr_list);
Paul Jakmad9a18f12007-04-10 19:30:20 +0000553 for (anode = first->next; anode || first; anode = next)
hassoeef1fe12004-10-03 18:46:08 +0000554 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000555 if (!anode)
hassoeef1fe12004-10-03 18:46:08 +0000556 {
Paul Jakmad9a18f12007-04-10 19:30:20 +0000557 anode = first;
hassoeef1fe12004-10-03 18:46:08 +0000558 first = NULL;
559 }
Paul Jakmad9a18f12007-04-10 19:30:20 +0000560 next = anode->next;
hassoeef1fe12004-10-03 18:46:08 +0000561
Paul Jakmad9a18f12007-04-10 19:30:20 +0000562 ifc = listgetdata (anode);
hassoeef1fe12004-10-03 18:46:08 +0000563 p = ifc->address;
hassoeef1fe12004-10-03 18:46:08 +0000564 connected_down_ipv4 (ifp, ifc);
565
Christian Franke02b48052013-01-24 14:04:49 +0000566 /* XXX: We have to send notifications here explicitly, because we destroy
567 * the ifc before receiving the notification about the address being deleted.
568 */
hassoeef1fe12004-10-03 18:46:08 +0000569 zebra_interface_address_delete_update (ifp, ifc);
570
571 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000572 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000573
574 /* Remove from subnet chain. */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000575 list_delete_node (addr_list, anode);
hassoeef1fe12004-10-03 18:46:08 +0000576 route_unlock_node (rn);
577
578 /* Remove from interface address list (unconditionally). */
Paul Jakmad9a18f12007-04-10 19:30:20 +0000579 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
580 {
581 listnode_delete (ifp->connected, ifc);
582 connected_free (ifc);
583 }
584 else
585 last = node;
hassoeef1fe12004-10-03 18:46:08 +0000586 }
587
588 /* Free chain list and respective route node. */
589 list_delete (addr_list);
590 rn->info = NULL;
591 route_unlock_node (rn);
592 }
paul718e3742002-12-13 20:15:29 +0000593#ifdef HAVE_IPV6
594 else if (p->family == AF_INET6)
hassoeef1fe12004-10-03 18:46:08 +0000595 {
596 connected_down_ipv6 (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000597
hassoeef1fe12004-10-03 18:46:08 +0000598 zebra_interface_address_delete_update (ifp, ifc);
paul718e3742002-12-13 20:15:29 +0000599
hassoeef1fe12004-10-03 18:46:08 +0000600 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
Christian Frankef7f740f2013-01-24 14:04:48 +0000601 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
hassoeef1fe12004-10-03 18:46:08 +0000602
603 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
604 last = node;
605 else
606 {
607 listnode_delete (ifp->connected, ifc);
608 connected_free (ifc);
609 }
paul718e3742002-12-13 20:15:29 +0000610 }
hassoeef1fe12004-10-03 18:46:08 +0000611#endif /* HAVE_IPV6 */
Roman Hoog Antinke26873f2010-05-05 16:00:50 +0200612 else
613 {
614 last = node;
615 }
paul718e3742002-12-13 20:15:29 +0000616 }
617 }
618 zebra_interface_delete_update (ifp);
ajsd2fc8892005-04-02 18:38:43 +0000619
620 /* Update ifindex after distributing the delete message. This is in
621 case any client needs to have the old value of ifindex available
622 while processing the deletion. Each client daemon is responsible
623 for setting ifindex to IFINDEX_INTERNAL after processing the
624 interface deletion message. */
625 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000626}
627
628/* Interface is up. */
629void
630if_up (struct interface *ifp)
631{
hasso52dc7ee2004-09-23 19:18:23 +0000632 struct listnode *node;
633 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000634 struct connected *ifc;
635 struct prefix *p;
636
Christian Franke581ecbf2016-05-03 19:59:43 +0200637 if_count_up(ifp->info);
638
paul718e3742002-12-13 20:15:29 +0000639 /* Notify the protocol daemons. */
640 zebra_interface_up_update (ifp);
641
642 /* Install connected routes to the kernel. */
643 if (ifp->connected)
644 {
paul1eb8ef22005-04-07 07:30:20 +0000645 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000646 {
paul718e3742002-12-13 20:15:29 +0000647 p = ifc->address;
648
649 if (p->family == AF_INET)
650 connected_up_ipv4 (ifp, ifc);
651#ifdef HAVE_IPV6
652 else if (p->family == AF_INET6)
653 connected_up_ipv6 (ifp, ifc);
654#endif /* HAVE_IPV6 */
655 }
656 }
657
658 /* Examine all static routes. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200659 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000660}
661
662/* Interface goes down. We have to manage different behavior of based
663 OS. */
664void
665if_down (struct interface *ifp)
666{
hasso52dc7ee2004-09-23 19:18:23 +0000667 struct listnode *node;
668 struct listnode *next;
paul718e3742002-12-13 20:15:29 +0000669 struct connected *ifc;
670 struct prefix *p;
Christian Franke581ecbf2016-05-03 19:59:43 +0200671 struct zebra_if *zif;
672
673 zif = ifp->info;
674 if (zif->up_events.count)
675 if_count_down(zif);
paul718e3742002-12-13 20:15:29 +0000676
677 /* Notify to the protocol daemons. */
678 zebra_interface_down_update (ifp);
679
680 /* Delete connected routes from the kernel. */
681 if (ifp->connected)
682 {
paul1eb8ef22005-04-07 07:30:20 +0000683 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
paul718e3742002-12-13 20:15:29 +0000684 {
paul718e3742002-12-13 20:15:29 +0000685 p = ifc->address;
686
687 if (p->family == AF_INET)
688 connected_down_ipv4 (ifp, ifc);
689#ifdef HAVE_IPV6
690 else if (p->family == AF_INET6)
691 connected_down_ipv6 (ifp, ifc);
692#endif /* HAVE_IPV6 */
693 }
694 }
695
696 /* Examine all static routes which direct to the interface. */
Feng Lu0d0686f2015-05-22 11:40:02 +0200697 rib_update (ifp->vrf_id);
paul718e3742002-12-13 20:15:29 +0000698}
699
700void
701if_refresh (struct interface *ifp)
702{
paul5c78b3d2006-01-25 04:31:40 +0000703 if_get_flags (ifp);
paul718e3742002-12-13 20:15:29 +0000704}
705
paul718e3742002-12-13 20:15:29 +0000706/* Output prefix string to vty. */
paula1ac18c2005-06-28 17:17:12 +0000707static int
paul718e3742002-12-13 20:15:29 +0000708prefix_vty_out (struct vty *vty, struct prefix *p)
709{
710 char str[INET6_ADDRSTRLEN];
711
712 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
713 vty_out (vty, "%s", str);
714 return strlen (str);
715}
716
717/* Dump if address information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000718static void
paul718e3742002-12-13 20:15:29 +0000719connected_dump_vty (struct vty *vty, struct connected *connected)
720{
721 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000722
723 /* Print interface address. */
724 p = connected->address;
725 vty_out (vty, " %s ", prefix_family_str (p));
726 prefix_vty_out (vty, p);
727 vty_out (vty, "/%d", p->prefixlen);
728
729 /* If there is destination address, print it. */
Andrew J. Schorre4529632006-12-12 19:18:21 +0000730 if (connected->destination)
paul718e3742002-12-13 20:15:29 +0000731 {
Andrew J. Schorre4529632006-12-12 19:18:21 +0000732 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
733 prefix_vty_out (vty, connected->destination);
paul718e3742002-12-13 20:15:29 +0000734 }
735
736 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
737 vty_out (vty, " secondary");
738
739 if (connected->label)
740 vty_out (vty, " %s", connected->label);
741
742 vty_out (vty, "%s", VTY_NEWLINE);
743}
744
Donald Sharp64257732015-11-20 08:33:30 -0500745#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000746/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000747static void
paul718e3742002-12-13 20:15:29 +0000748nd_dump_vty (struct vty *vty, struct interface *ifp)
749{
750 struct zebra_if *zif;
751 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000752 int interval;
paul718e3742002-12-13 20:15:29 +0000753
754 zif = (struct zebra_if *) ifp->info;
755 rtadv = &zif->rtadv;
756
757 if (rtadv->AdvSendAdvertisements)
758 {
759 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
760 rtadv->AdvReachableTime, VTY_NEWLINE);
761 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
762 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000763 interval = rtadv->MaxRtrAdvInterval;
764 if (interval % 1000)
765 vty_out (vty, " ND router advertisements are sent every "
766 "%d milliseconds%s", interval,
767 VTY_NEWLINE);
768 else
769 vty_out (vty, " ND router advertisements are sent every "
770 "%d seconds%s", interval / 1000,
771 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400772 if (rtadv->AdvDefaultLifetime != -1)
773 vty_out (vty, " ND router advertisements live for %d seconds%s",
774 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
775 else
776 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
777 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000778 vty_out (vty, " ND router advertisement default router preference is "
779 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
780 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000781 if (rtadv->AdvManagedFlag)
782 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
783 VTY_NEWLINE);
784 else
785 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
786 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000787 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400788 {
vincent7cee1bb2005-03-25 13:08:53 +0000789 vty_out (vty, " ND router advertisements with "
790 "Home Agent flag bit set.%s",
791 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400792 if (rtadv->HomeAgentLifetime != -1)
793 vty_out (vty, " Home Agent lifetime is %u seconds%s",
794 rtadv->HomeAgentLifetime, VTY_NEWLINE);
795 else
796 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
797 VTY_NEWLINE);
798 vty_out (vty, " Home Agent preference is %u%s",
799 rtadv->HomeAgentPreference, VTY_NEWLINE);
800 }
vincent7cee1bb2005-03-25 13:08:53 +0000801 if (rtadv->AdvIntervalOption)
802 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
803 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000804 }
805}
Donald Sharp64257732015-11-20 08:33:30 -0500806#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000807
808/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000809static void
paul718e3742002-12-13 20:15:29 +0000810if_dump_vty (struct vty *vty, struct interface *ifp)
811{
paul718e3742002-12-13 20:15:29 +0000812 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000813 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000814 struct route_node *rn;
815 struct zebra_if *zebra_if;
816
817 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000818
paul2e3b2e42002-12-13 21:03:13 +0000819 vty_out (vty, "Interface %s is ", ifp->name);
820 if (if_is_up(ifp)) {
821 vty_out (vty, "up, line protocol ");
822
823 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
824 if (if_is_running(ifp))
825 vty_out (vty, "is up%s", VTY_NEWLINE);
826 else
827 vty_out (vty, "is down%s", VTY_NEWLINE);
828 } else {
829 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
830 }
831 } else {
832 vty_out (vty, "down%s", VTY_NEWLINE);
833 }
834
Christian Franke581ecbf2016-05-03 19:59:43 +0200835 vty_out (vty, " Link ups: %s%s",
836 event_counter_format(&zebra_if->up_events), VTY_NEWLINE);
837 vty_out (vty, " Link downs: %s%s",
838 event_counter_format(&zebra_if->down_events), VTY_NEWLINE);
839
Feng Lu2fc97f62015-05-22 11:39:57 +0200840 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
841
paul718e3742002-12-13 20:15:29 +0000842 if (ifp->desc)
843 vty_out (vty, " Description: %s%s", ifp->desc,
844 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000845 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000846 {
ajsd2fc8892005-04-02 18:38:43 +0000847 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000848 return;
849 }
850 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
851 {
852 vty_out(vty, " index %d inactive interface%s",
853 ifp->ifindex,
854 VTY_NEWLINE);
855 return;
856 }
857
858 vty_out (vty, " index %d metric %d mtu %d ",
859 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000860#ifdef HAVE_IPV6
861 if (ifp->mtu6 != ifp->mtu)
862 vty_out (vty, "mtu6 %d ", ifp->mtu6);
863#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000864 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
865 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000866
paul718e3742002-12-13 20:15:29 +0000867 /* Hardware address. */
Timo Teräs954c7d62016-01-15 17:36:33 +0200868 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000869 if (ifp->hw_addr_len != 0)
870 {
871 int i;
872
873 vty_out (vty, " HWaddr: ");
874 for (i = 0; i < ifp->hw_addr_len; i++)
875 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
876 vty_out (vty, "%s", VTY_NEWLINE);
877 }
paul718e3742002-12-13 20:15:29 +0000878
879 /* Bandwidth in kbps */
880 if (ifp->bandwidth != 0)
881 {
882 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
883 vty_out(vty, "%s", VTY_NEWLINE);
884 }
885
hassoeef1fe12004-10-03 18:46:08 +0000886 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000887 {
hassoeef1fe12004-10-03 18:46:08 +0000888 if (! rn->info)
889 continue;
Olivier Dugeon15773a82016-04-19 18:29:55 +0200890
paul1eb8ef22005-04-07 07:30:20 +0000891 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
892 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000893 }
894
paul1eb8ef22005-04-07 07:30:20 +0000895 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000896 {
hasso39db97e2004-10-12 20:50:58 +0000897 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
898 (connected->address->family == AF_INET6))
899 connected_dump_vty (vty, connected);
900 }
901
Olivier Dugeon15773a82016-04-19 18:29:55 +0200902 if (HAS_LINK_PARAMS(ifp))
903 {
904 int i;
905 struct if_link_params *iflp = ifp->link_params;
906 vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
907 if (IS_PARAM_SET(iflp, LP_TE))
908 vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
909 if (IS_PARAM_SET(iflp, LP_MAX_BW))
910 vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
911 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
912 vty_out(vty, " Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
913 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
914 vty_out(vty, " Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
915 for (i = 0; i < MAX_CLASS_TYPE; i+=2)
916 vty_out(vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
917 i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
918 }
919
920 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
921 vty_out(vty, " Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
922 if (IS_PARAM_SET(iflp, LP_DELAY))
923 {
924 vty_out(vty, " Link Delay Average: %u (micro-sec.)", iflp->av_delay);
925 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
926 {
927 vty_out(vty, " Min: %u (micro-sec.)", iflp->min_delay);
928 vty_out(vty, " Max: %u (micro-sec.)", iflp->max_delay);
929 }
930 vty_out(vty, "%s", VTY_NEWLINE);
931 }
932 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
933 vty_out(vty, " Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
934 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
935 vty_out(vty, " Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
936 if (IS_PARAM_SET(iflp, LP_AVA_BW))
937 vty_out(vty, " Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
938 if (IS_PARAM_SET(iflp, LP_RES_BW))
939 vty_out(vty, " Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
940 if (IS_PARAM_SET(iflp, LP_USE_BW))
941 vty_out(vty, " Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
942 if (IS_PARAM_SET(iflp, LP_RMT_AS))
943 vty_out(vty, " Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
944 }
945
946 #ifdef RTADV
947 nd_dump_vty (vty, ifp);
948 #endif /* RTADV */
Donald Sharp64257732015-11-20 08:33:30 -0500949#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000950 nd_dump_vty (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -0500951#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000952
953#ifdef HAVE_PROC_NET_DEV
954 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000955 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
956 "%lu dropped%s",
957 ifp->stats.rx_packets, ifp->stats.rx_multicast,
958 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000959
hasso6f2c27a2005-01-18 13:44:35 +0000960 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000961 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000962 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
963 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000964 ifp->stats.rx_frame_errors, VTY_NEWLINE);
965
966 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000967 ifp->stats.rx_missed_errors, VTY_NEWLINE);
968
hasso6f2c27a2005-01-18 13:44:35 +0000969 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000970 ifp->stats.tx_packets, ifp->stats.tx_bytes,
971 ifp->stats.tx_dropped, VTY_NEWLINE);
972
hasso6f2c27a2005-01-18 13:44:35 +0000973 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
974 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000975 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
976 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000977 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000978
hasso6f2c27a2005-01-18 13:44:35 +0000979 vty_out (vty, " %lu window, %lu collisions%s",
980 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000981#endif /* HAVE_PROC_NET_DEV */
982
983#ifdef HAVE_NET_RT_IFLIST
984#if defined (__bsdi__) || defined (__NetBSD__)
985 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200986 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
987 " multicast packets %llu%s",
988 (unsigned long long)ifp->stats.ifi_ipackets,
989 (unsigned long long)ifp->stats.ifi_ibytes,
990 (unsigned long long)ifp->stats.ifi_iqdrops,
991 (unsigned long long)ifp->stats.ifi_imcasts,
992 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000993
David Lamparter193e78f2015-04-21 10:42:30 +0200994 vty_out (vty, " input errors %llu%s",
995 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000996
David Lamparter193e78f2015-04-21 10:42:30 +0200997 vty_out (vty, " output packets %llu, bytes %llu,"
998 " multicast packets %llu%s",
999 (unsigned long long)ifp->stats.ifi_opackets,
1000 (unsigned long long)ifp->stats.ifi_obytes,
1001 (unsigned long long)ifp->stats.ifi_omcasts,
1002 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001003
David Lamparter193e78f2015-04-21 10:42:30 +02001004 vty_out (vty, " output errors %llu%s",
1005 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001006
David Lamparter193e78f2015-04-21 10:42:30 +02001007 vty_out (vty, " collisions %llu%s",
1008 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001009#else
1010 /* Statistics print out using sysctl (). */
1011 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
1012 " multicast packets %lu%s",
1013 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1014 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1015 VTY_NEWLINE);
1016
1017 vty_out (vty, " input errors %lu%s",
1018 ifp->stats.ifi_ierrors, VTY_NEWLINE);
1019
1020 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
1021 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1022 ifp->stats.ifi_omcasts, VTY_NEWLINE);
1023
1024 vty_out (vty, " output errors %lu%s",
1025 ifp->stats.ifi_oerrors, VTY_NEWLINE);
1026
1027 vty_out (vty, " collisions %lu%s",
1028 ifp->stats.ifi_collisions, VTY_NEWLINE);
1029#endif /* __bsdi__ || __NetBSD__ */
1030#endif /* HAVE_NET_RT_IFLIST */
1031}
1032
paul718e3742002-12-13 20:15:29 +00001033/* Wrapper hook point for zebra daemon so that ifindex can be set
1034 * DEFUN macro not used as extract.pl HAS to ignore this
1035 * See also interface_cmd in lib/if.c
1036 */
1037DEFUN_NOSH (zebra_interface,
1038 zebra_interface_cmd,
1039 "interface IFNAME",
1040 "Select an interface to configure\n"
1041 "Interface's name\n")
1042{
1043 int ret;
Olivier Dugeon15773a82016-04-19 18:29:55 +02001044 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001045
1046 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +00001047 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
1048 return ret;
paul718e3742002-12-13 20:15:29 +00001049
Olivier Dugeon15773a82016-04-19 18:29:55 +02001050 ifp = vty->index;
paul718e3742002-12-13 20:15:29 +00001051
ajsd2fc8892005-04-02 18:38:43 +00001052 if (ifp->ifindex == IFINDEX_INTERNAL)
1053 /* Is this really necessary? Shouldn't status be initialized to 0
1054 in that case? */
1055 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001056
1057 return ret;
1058}
1059
Feng Lu471ea392015-05-22 11:40:00 +02001060ALIAS (zebra_interface,
1061 zebra_interface_vrf_cmd,
1062 "interface IFNAME " VRF_CMD_STR,
1063 "Select an interface to configure\n"
1064 "Interface's name\n"
1065 VRF_CMD_HELP_STR)
1066
paul718e3742002-12-13 20:15:29 +00001067struct cmd_node interface_node =
1068{
1069 INTERFACE_NODE,
1070 "%s(config-if)# ",
1071 1
1072};
1073
Feng Lua2854772015-05-22 11:40:01 +02001074/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +00001075DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +02001076 "show interface",
paul718e3742002-12-13 20:15:29 +00001077 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +02001078 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +00001079{
hasso52dc7ee2004-09-23 19:18:23 +00001080 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001081 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +02001082 vrf_id_t vrf_id = VRF_DEFAULT;
1083
paul718e3742002-12-13 20:15:29 +00001084#ifdef HAVE_PROC_NET_DEV
1085 /* If system has interface statistics via proc file system, update
1086 statistics. */
1087 ifstat_update_proc ();
1088#endif /* HAVE_PROC_NET_DEV */
1089#ifdef HAVE_NET_RT_IFLIST
1090 ifstat_update_sysctl ();
1091#endif /* HAVE_NET_RT_IFLIST */
1092
Feng Lua2854772015-05-22 11:40:01 +02001093 if (argc > 0)
1094 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +00001095
1096 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +02001097 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +00001098 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +00001099
1100 return CMD_SUCCESS;
1101}
1102
Feng Lua2854772015-05-22 11:40:01 +02001103ALIAS (show_interface,
1104 show_interface_vrf_cmd,
1105 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +00001106 SHOW_STR
1107 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +02001108 VRF_CMD_HELP_STR)
1109
1110/* Show all interfaces to vty. */
1111DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
1112 "show interface " VRF_ALL_CMD_STR,
1113 SHOW_STR
1114 "Interface status and configuration\n"
1115 VRF_ALL_CMD_HELP_STR)
1116{
1117 struct listnode *node;
1118 struct interface *ifp;
1119 vrf_iter_t iter;
1120
1121#ifdef HAVE_PROC_NET_DEV
1122 /* If system has interface statistics via proc file system, update
1123 statistics. */
1124 ifstat_update_proc ();
1125#endif /* HAVE_PROC_NET_DEV */
1126#ifdef HAVE_NET_RT_IFLIST
1127 ifstat_update_sysctl ();
1128#endif /* HAVE_NET_RT_IFLIST */
1129
1130 /* All interface print. */
1131 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1132 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1133 if_dump_vty (vty, ifp);
1134
1135 return CMD_SUCCESS;
1136}
1137
1138/* Show specified interface to vty. */
1139DEFUN (show_interface_name, show_interface_name_cmd,
1140 "show interface IFNAME",
1141 SHOW_STR
1142 "Interface status and configuration\n"
1143 "Inteface name\n")
1144{
1145 struct interface *ifp;
1146 vrf_id_t vrf_id = VRF_DEFAULT;
1147
1148#ifdef HAVE_PROC_NET_DEV
1149 /* If system has interface statistics via proc file system, update
1150 statistics. */
1151 ifstat_update_proc ();
1152#endif /* HAVE_PROC_NET_DEV */
1153#ifdef HAVE_NET_RT_IFLIST
1154 ifstat_update_sysctl ();
1155#endif /* HAVE_NET_RT_IFLIST */
1156
1157 if (argc > 1)
1158 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1159
1160 /* Specified interface print. */
1161 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1162 if (ifp == NULL)
1163 {
1164 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1165 VTY_NEWLINE);
1166 return CMD_WARNING;
1167 }
1168 if_dump_vty (vty, ifp);
1169
1170 return CMD_SUCCESS;
1171}
1172
1173ALIAS (show_interface_name,
1174 show_interface_name_vrf_cmd,
1175 "show interface IFNAME " VRF_CMD_STR,
1176 SHOW_STR
1177 "Interface status and configuration\n"
1178 "Inteface name\n"
1179 VRF_CMD_HELP_STR)
1180
1181/* Show specified interface to vty. */
1182DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1183 "show interface IFNAME " VRF_ALL_CMD_STR,
1184 SHOW_STR
1185 "Interface status and configuration\n"
1186 "Inteface name\n"
1187 VRF_ALL_CMD_HELP_STR)
1188{
1189 struct interface *ifp;
1190 vrf_iter_t iter;
1191 int found = 0;
1192
1193#ifdef HAVE_PROC_NET_DEV
1194 /* If system has interface statistics via proc file system, update
1195 statistics. */
1196 ifstat_update_proc ();
1197#endif /* HAVE_PROC_NET_DEV */
1198#ifdef HAVE_NET_RT_IFLIST
1199 ifstat_update_sysctl ();
1200#endif /* HAVE_NET_RT_IFLIST */
1201
1202 /* All interface print. */
1203 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1204 {
1205 /* Specified interface print. */
1206 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1207 if (ifp)
1208 {
1209 if_dump_vty (vty, ifp);
1210 found++;
1211 }
1212 }
1213
1214 if (!found)
1215 {
1216 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1217 return CMD_WARNING;
1218 }
1219
1220 return CMD_SUCCESS;
1221}
1222
1223static void
1224if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001225{
1226 struct listnode *node;
1227 struct interface *ifp;
1228
1229 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001230 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001231 {
1232 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001233
1234 len = vty_out (vty, "%s", ifp->name);
1235 vty_out (vty, "%*s", (16 - len), " ");
1236
1237 if (if_is_up(ifp))
1238 {
1239 vty_out (vty, "up ");
1240 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1241 {
1242 if (if_is_running(ifp))
1243 vty_out (vty, "up ");
1244 else
1245 vty_out (vty, "down ");
1246 }
1247 else
1248 {
1249 vty_out (vty, "unknown ");
1250 }
1251 }
1252 else
1253 {
1254 vty_out (vty, "down down ");
1255 }
1256
1257 if (ifp->desc)
1258 vty_out (vty, "%s", ifp->desc);
1259 vty_out (vty, "%s", VTY_NEWLINE);
1260 }
Feng Lua2854772015-05-22 11:40:01 +02001261}
1262
1263DEFUN (show_interface_desc,
1264 show_interface_desc_cmd,
1265 "show interface description",
1266 SHOW_STR
1267 "Interface status and configuration\n"
1268 "Interface description\n")
1269{
1270 vrf_id_t vrf_id = VRF_DEFAULT;
1271
1272 if (argc > 0)
1273 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1274
1275 if_show_description (vty, vrf_id);
1276
1277 return CMD_SUCCESS;
1278}
1279
1280ALIAS (show_interface_desc,
1281 show_interface_desc_vrf_cmd,
1282 "show interface description " VRF_CMD_STR,
1283 SHOW_STR
1284 "Interface status and configuration\n"
1285 "Interface description\n"
1286 VRF_CMD_HELP_STR)
1287
1288DEFUN (show_interface_desc_vrf_all,
1289 show_interface_desc_vrf_all_cmd,
1290 "show interface description " VRF_ALL_CMD_STR,
1291 SHOW_STR
1292 "Interface status and configuration\n"
1293 "Interface description\n"
1294 VRF_ALL_CMD_HELP_STR)
1295{
1296 vrf_iter_t iter;
1297
1298 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1299 if (!list_isempty (vrf_iter2iflist (iter)))
1300 {
1301 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1302 vrf_iter2id (iter),
1303 VTY_NEWLINE, VTY_NEWLINE);
1304 if_show_description (vty, vrf_iter2id (iter));
1305 }
1306
hassoed9bb6d2005-03-13 19:17:21 +00001307 return CMD_SUCCESS;
1308}
1309
paul718e3742002-12-13 20:15:29 +00001310DEFUN (multicast,
1311 multicast_cmd,
1312 "multicast",
1313 "Set multicast flag to interface\n")
1314{
1315 int ret;
1316 struct interface *ifp;
1317 struct zebra_if *if_data;
1318
1319 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001320 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001321 {
paul48b33aa2002-12-13 20:52:52 +00001322 ret = if_set_flags (ifp, IFF_MULTICAST);
1323 if (ret < 0)
1324 {
1325 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1326 return CMD_WARNING;
1327 }
1328 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001329 }
paul718e3742002-12-13 20:15:29 +00001330 if_data = ifp->info;
1331 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001332
paul718e3742002-12-13 20:15:29 +00001333 return CMD_SUCCESS;
1334}
1335
1336DEFUN (no_multicast,
1337 no_multicast_cmd,
1338 "no multicast",
1339 NO_STR
1340 "Unset multicast flag to interface\n")
1341{
1342 int ret;
1343 struct interface *ifp;
1344 struct zebra_if *if_data;
1345
1346 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001347 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001348 {
paul48b33aa2002-12-13 20:52:52 +00001349 ret = if_unset_flags (ifp, IFF_MULTICAST);
1350 if (ret < 0)
1351 {
1352 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1353 return CMD_WARNING;
1354 }
1355 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001356 }
paul718e3742002-12-13 20:15:29 +00001357 if_data = ifp->info;
1358 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1359
1360 return CMD_SUCCESS;
1361}
1362
Paul Jakma8f4269d2015-09-18 11:50:33 +01001363/* Hacky: create a dummy node just to hang a config-writer callback off it */
1364static struct cmd_node zebra_if_defaults_node = {
1365 ZEBRA_IF_DEFAULTS_NODE,
1366 "",
1367 1,
1368};
1369
1370static int
1371config_write_zebra_if_defaults (struct vty *vty)
1372{
1373 if (zif_defaults.linkdetect != IF_LINKDETECT_UNSPEC)
1374 vty_out (vty, "default link-detect %s%s",
1375 zif_defaults.linkdetect == IF_LINKDETECT_ON ? "on" : "off",
1376 VTY_NEWLINE);
1377 return 0;
1378}
1379
1380DEFUN(default_linkdetect,
1381 default_linkdetect_cmd,
1382 "default link-detect (on|off)",
1383 "Configure defaults of settings\n"
1384 "Interface link detection\n"
1385 "Interface link-detect defaults to enabled\n"
1386 "Interface link-detect defaults to disabled\n")
1387{
1388 zebra_if_linkdetect prev = zif_defaults.linkdetect;
1389 struct listnode *node;
1390 struct interface *ifp;
1391 vrf_iter_t iter;
1392
1393 if (strcmp (argv[1], "on") == 0)
1394 zif_defaults.linkdetect = IF_LINKDETECT_ON;
1395 else
1396 zif_defaults.linkdetect = IF_LINKDETECT_OFF;
1397
1398 if (zif_defaults.linkdetect != prev)
1399 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1400 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1401 if_zebra_linkdetect_set (ifp);
1402
1403 return CMD_SUCCESS;
1404}
1405
paul2e3b2e42002-12-13 21:03:13 +00001406DEFUN (linkdetect,
1407 linkdetect_cmd,
Paul Jakma8f4269d2015-09-18 11:50:33 +01001408 "link-detect [default]",
1409 "Enable link detection on interface\n"
1410 "Leave link-detect to the default\n")
paul2e3b2e42002-12-13 21:03:13 +00001411{
paul2e3b2e42002-12-13 21:03:13 +00001412 struct interface *ifp;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001413 struct zebra_if *zif;
paul2e3b2e42002-12-13 21:03:13 +00001414
1415 ifp = (struct interface *) vty->index;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001416 zif = ifp->info;
1417 assert (zif != NULL);
1418
1419 zif->linkdetect = IF_LINKDETECT_ON;
1420 if_zebra_linkdetect_set (ifp);
1421
paul2e3b2e42002-12-13 21:03:13 +00001422 /* FIXME: Will defer status change forwarding if interface
1423 does not come down! */
1424
1425 return CMD_SUCCESS;
1426}
1427
1428
1429DEFUN (no_linkdetect,
1430 no_linkdetect_cmd,
1431 "no link-detect",
1432 NO_STR
1433 "Disable link detection on interface\n")
1434{
paul2e3b2e42002-12-13 21:03:13 +00001435 struct interface *ifp;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001436 struct zebra_if *zif;
paul2e3b2e42002-12-13 21:03:13 +00001437
Paul Jakma8f4269d2015-09-18 11:50:33 +01001438 ifp = (struct interface *) vty->index;
1439 zif = ifp->info;
1440 assert (zif != NULL);
1441
1442 zif->linkdetect = IF_LINKDETECT_OFF;
1443 if_zebra_linkdetect_set (ifp);
1444
paul2e3b2e42002-12-13 21:03:13 +00001445 /* FIXME: see linkdetect_cmd */
1446
1447 return CMD_SUCCESS;
1448}
1449
paul718e3742002-12-13 20:15:29 +00001450DEFUN (shutdown_if,
1451 shutdown_if_cmd,
1452 "shutdown",
1453 "Shutdown the selected interface\n")
1454{
1455 int ret;
1456 struct interface *ifp;
1457 struct zebra_if *if_data;
1458
1459 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001460 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001461 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001462 ret = if_unset_flags (ifp, IFF_UP);
1463 if (ret < 0)
1464 {
1465 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1466 return CMD_WARNING;
1467 }
1468 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001469 }
paul718e3742002-12-13 20:15:29 +00001470 if_data = ifp->info;
1471 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1472
1473 return CMD_SUCCESS;
1474}
1475
1476DEFUN (no_shutdown_if,
1477 no_shutdown_if_cmd,
1478 "no shutdown",
1479 NO_STR
1480 "Shutdown the selected interface\n")
1481{
1482 int ret;
1483 struct interface *ifp;
1484 struct zebra_if *if_data;
1485
1486 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001487
1488 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001489 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001490 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1491 if (ret < 0)
1492 {
1493 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1494 return CMD_WARNING;
1495 }
1496 if_refresh (ifp);
1497
1498 /* Some addresses (in particular, IPv6 addresses on Linux) get
1499 * removed when the interface goes down. They need to be readded.
1500 */
1501 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001502 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001503
paul718e3742002-12-13 20:15:29 +00001504 if_data = ifp->info;
1505 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1506
1507 return CMD_SUCCESS;
1508}
1509
1510DEFUN (bandwidth_if,
1511 bandwidth_if_cmd,
1512 "bandwidth <1-10000000>",
1513 "Set bandwidth informational parameter\n"
1514 "Bandwidth in kilobits\n")
1515{
1516 struct interface *ifp;
1517 unsigned int bandwidth;
1518
1519 ifp = (struct interface *) vty->index;
1520 bandwidth = strtol(argv[0], NULL, 10);
1521
1522 /* bandwidth range is <1-10000000> */
1523 if (bandwidth < 1 || bandwidth > 10000000)
1524 {
1525 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1526 return CMD_WARNING;
1527 }
1528
1529 ifp->bandwidth = bandwidth;
1530
1531 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001532 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001533 zebra_interface_up_update (ifp);
1534
1535 return CMD_SUCCESS;
1536}
1537
1538DEFUN (no_bandwidth_if,
1539 no_bandwidth_if_cmd,
1540 "no bandwidth",
1541 NO_STR
1542 "Set bandwidth informational parameter\n")
1543{
1544 struct interface *ifp;
1545
1546 ifp = (struct interface *) vty->index;
1547
1548 ifp->bandwidth = 0;
1549
1550 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001551 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001552 zebra_interface_up_update (ifp);
1553
1554 return CMD_SUCCESS;
1555}
1556
1557ALIAS (no_bandwidth_if,
1558 no_bandwidth_if_val_cmd,
1559 "no bandwidth <1-10000000>",
1560 NO_STR
1561 "Set bandwidth informational parameter\n"
1562 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001563
Olivier Dugeon15773a82016-04-19 18:29:55 +02001564struct cmd_node link_params_node =
1565{
1566 LINK_PARAMS_NODE,
1567 "%s(config-link-params)# ",
1568 1,
1569};
1570
1571static void
1572link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field,
1573 uint32_t type, uint32_t value)
1574{
1575 /* Update field as needed */
1576 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1577 {
1578 *field = value;
1579 SET_PARAM(ifp->link_params, type);
1580
1581 /* force protocols to update LINK STATE due to parameters change */
1582 if (if_is_operative (ifp))
1583 zebra_interface_parameters_update (ifp);
1584 }
1585}
1586static void
1587link_param_cmd_set_float (struct interface *ifp, float *field,
1588 uint32_t type, float value)
1589{
1590
1591 /* Update field as needed */
1592 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1593 {
1594 *field = value;
1595 SET_PARAM(ifp->link_params, type);
1596
1597 /* force protocols to update LINK STATE due to parameters change */
1598 if (if_is_operative (ifp))
1599 zebra_interface_parameters_update (ifp);
1600 }
1601}
1602
1603static void
1604link_param_cmd_unset (struct interface *ifp, uint32_t type)
1605{
1606
1607 /* Unset field */
1608 UNSET_PARAM(ifp->link_params, type);
1609
1610 /* force protocols to update LINK STATE due to parameters change */
1611 if (if_is_operative (ifp))
1612 zebra_interface_parameters_update (ifp);
1613}
1614
1615DEFUN (link_params,
1616 link_params_cmd,
1617 "link-params",
1618 LINK_PARAMS_STR)
1619{
1620 vty->node = LINK_PARAMS_NODE;
1621
1622 return CMD_SUCCESS;
1623}
1624
1625/* Specific Traffic Engineering parameters commands */
1626DEFUN (link_params_enable,
1627 link_params_enable_cmd,
1628 "enable",
1629 "Activate link parameters on this interface\n")
1630{
1631 struct interface *ifp = (struct interface *) vty->index;
1632
1633 /* This command could be issue at startup, when activate MPLS TE */
1634 /* on a new interface or after a ON / OFF / ON toggle */
1635 /* In all case, TE parameters are reset to their default factory */
1636 if (IS_ZEBRA_DEBUG_EVENT)
1637 zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
1638
1639 if (!if_link_params_get (ifp))
1640 {
1641 if (IS_ZEBRA_DEBUG_EVENT)
1642 zlog_debug ("Link-params: failed to init TE link parameters %s", ifp->name);
1643
1644 return CMD_WARNING;
1645 }
1646
1647 /* force protocols to update LINK STATE due to parameters change */
1648 if (if_is_operative (ifp))
1649 zebra_interface_parameters_update (ifp);
1650
1651 return CMD_SUCCESS;
1652}
1653
1654DEFUN (no_link_params_enable,
1655 no_link_params_enable_cmd,
1656 "no enable",
1657 NO_STR
1658 "Disable link parameters on this interface\n")
1659{
1660 struct interface *ifp = (struct interface *) vty->index;
1661
1662 zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
1663
1664 if_link_params_free (ifp);
1665
1666 /* force protocols to update LINK STATE due to parameters change */
1667 if (if_is_operative (ifp))
1668 zebra_interface_parameters_update (ifp);
1669
1670 return CMD_SUCCESS;
1671}
1672
1673/* STANDARD TE metrics */
1674DEFUN (link_params_metric,
1675 link_params_metric_cmd,
1676 "metric <0-4294967295>",
1677 "Link metric for MPLS-TE purpose\n"
1678 "Metric value in decimal\n")
1679{
1680 struct interface *ifp = (struct interface *) vty->index;
1681 struct if_link_params *iflp = if_link_params_get (ifp);
1682 u_int32_t metric;
1683
1684 VTY_GET_ULONG("metric", metric, argv[0]);
1685
1686 /* Update TE metric if needed */
1687 link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric);
1688
1689 return CMD_SUCCESS;
1690}
1691
1692DEFUN (no_link_params_metric,
1693 no_link_params_metric_cmd,
1694 "no metric",
1695 NO_STR
1696 "Disbale Link Metric on this interface\n")
1697{
1698 struct interface *ifp = (struct interface *) vty->index;
1699
1700 /* Unset TE Metric */
1701 link_param_cmd_unset(ifp, LP_TE);
1702
1703 return CMD_SUCCESS;
1704}
1705
1706DEFUN (link_params_maxbw,
1707 link_params_maxbw_cmd,
1708 "max-bw BANDWIDTH",
1709 "Maximum bandwidth that can be used\n"
1710 "Bytes/second (IEEE floating point format)\n")
1711{
1712 struct interface *ifp = (struct interface *) vty->index;
1713 struct if_link_params *iflp = if_link_params_get (ifp);
1714
1715 float bw;
1716
1717 if (sscanf (argv[0], "%g", &bw) != 1)
1718 {
1719 vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
1720 VTY_NEWLINE);
1721 return CMD_WARNING;
1722 }
1723
1724 /* Check that Maximum bandwidth is not lower than other bandwidth parameters */
1725 if ((bw <= iflp->max_rsv_bw)
1726 || (bw <= iflp->unrsv_bw[0])
1727 || (bw <= iflp->unrsv_bw[1])
1728 || (bw <= iflp->unrsv_bw[2])
1729 || (bw <= iflp->unrsv_bw[3])
1730 || (bw <= iflp->unrsv_bw[4])
1731 || (bw <= iflp->unrsv_bw[5])
1732 || (bw <= iflp->unrsv_bw[6])
1733 || (bw <= iflp->unrsv_bw[7])
1734 || (bw <= iflp->ava_bw)
1735 || (bw <= iflp->res_bw)
1736 || (bw <= iflp->use_bw))
1737 {
1738 vty_out (vty,
1739 "Maximum Bandwidth could not be lower than others bandwidth%s",
1740 VTY_NEWLINE);
1741 return CMD_WARNING;
1742 }
1743
1744 /* Update Maximum Bandwidth if needed */
1745 link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
1746
1747 return CMD_SUCCESS;
1748}
1749
1750DEFUN (link_params_max_rsv_bw,
1751 link_params_max_rsv_bw_cmd,
1752 "max-rsv-bw BANDWIDTH",
1753 "Maximum bandwidth that may be reserved\n"
1754 "Bytes/second (IEEE floating point format)\n")
1755{
1756 struct interface *ifp = (struct interface *) vty->index;
1757 struct if_link_params *iflp = if_link_params_get (ifp);
1758 float bw;
1759
1760 if (sscanf (argv[0], "%g", &bw) != 1)
1761 {
1762 vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
1763 VTY_NEWLINE);
1764 return CMD_WARNING;
1765 }
1766
1767 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1768 if (bw > iflp->max_bw)
1769 {
1770 vty_out (vty,
1771 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1772 iflp->max_bw, VTY_NEWLINE);
1773 return CMD_WARNING;
1774 }
1775
1776 /* Update Maximum Reservable Bandwidth if needed */
1777 link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
1778
1779 return CMD_SUCCESS;
1780}
1781
1782DEFUN (link_params_unrsv_bw,
1783 link_params_unrsv_bw_cmd,
1784 "unrsv-bw <0-7> BANDWIDTH",
1785 "Unreserved bandwidth at each priority level\n"
1786 "Priority\n"
1787 "Bytes/second (IEEE floating point format)\n")
1788{
1789 struct interface *ifp = (struct interface *) vty->index;
1790 struct if_link_params *iflp = if_link_params_get (ifp);
1791 int priority;
1792 float bw;
1793
1794 /* We don't have to consider about range check here. */
1795 if (sscanf (argv[0], "%d", &priority) != 1)
1796 {
1797 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1798 VTY_NEWLINE);
1799 return CMD_WARNING;
1800 }
1801
1802 if (sscanf (argv[1], "%g", &bw) != 1)
1803 {
1804 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1805 VTY_NEWLINE);
1806 return CMD_WARNING;
1807 }
1808
1809 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1810 if (bw > iflp->max_bw)
1811 {
1812 vty_out (vty,
1813 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1814 iflp->max_bw, VTY_NEWLINE);
1815 return CMD_WARNING;
1816 }
1817
1818 /* Update Unreserved Bandwidth if needed */
1819 link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
1820
1821 return CMD_SUCCESS;
1822}
1823
1824DEFUN (link_params_admin_grp,
1825 link_params_admin_grp_cmd,
1826 "admin-grp BITPATTERN",
1827 "Administrative group membership\n"
1828 "32-bit Hexadecimal value (e.g. 0xa1)\n")
1829{
1830 struct interface *ifp = (struct interface *) vty->index;
1831 struct if_link_params *iflp = if_link_params_get (ifp);
1832 unsigned long value;
1833
1834 if (sscanf (argv[0], "0x%lx", &value) != 1)
1835 {
1836 vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
1837 safe_strerror (errno), VTY_NEWLINE);
1838 return CMD_WARNING;
1839 }
1840
1841 /* Update Administrative Group if needed */
1842 link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
1843
1844 return CMD_SUCCESS;
1845}
1846
1847DEFUN (no_link_params_admin_grp,
1848 no_link_params_admin_grp_cmd,
1849 "no admin-grp",
1850 NO_STR
1851 "Disbale Administrative group membership on this interface\n")
1852{
1853 struct interface *ifp = (struct interface *) vty->index;
1854
1855 /* Unset Admin Group */
1856 link_param_cmd_unset(ifp, LP_ADM_GRP);
1857
1858 return CMD_SUCCESS;
1859}
1860
1861/* RFC5392 & RFC5316: INTER-AS */
1862DEFUN (link_params_inter_as,
1863 link_params_inter_as_cmd,
1864 "neighbor A.B.C.D as <1-4294967295>",
1865 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
1866 "Remote IP address in dot decimal A.B.C.D\n"
1867 "Remote AS number\n"
1868 "AS number in the range <1-4294967295>\n")
1869{
1870
1871 struct interface *ifp = (struct interface *) vty->index;
1872 struct if_link_params *iflp = if_link_params_get (ifp);
1873 struct in_addr addr;
1874 u_int32_t as;
1875
1876 if (!inet_aton (argv[0], &addr))
1877 {
1878 vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
1879 return CMD_WARNING;
1880 }
1881
1882 VTY_GET_ULONG("AS number", as, argv[1]);
1883
1884 /* Update Remote IP and Remote AS fields if needed */
1885 if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
1886 || iflp->rmt_as != as
1887 || iflp->rmt_ip.s_addr != addr.s_addr)
1888 {
1889
1890 iflp->rmt_as = as;
1891 iflp->rmt_ip.s_addr = addr.s_addr;
1892 SET_PARAM(iflp, LP_RMT_AS);
1893
1894 /* force protocols to update LINK STATE due to parameters change */
1895 if (if_is_operative (ifp))
1896 zebra_interface_parameters_update (ifp);
1897 }
1898 return CMD_SUCCESS;
1899}
1900
1901DEFUN (no_link_params_inter_as,
1902 no_link_params_inter_as_cmd,
1903 "no neighbor",
1904 NO_STR
1905 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
1906{
1907
1908 struct interface *ifp = (struct interface *) vty->index;
1909 struct if_link_params *iflp = if_link_params_get (ifp);
1910
1911 /* Reset Remote IP and AS neighbor */
1912 iflp->rmt_as = 0;
1913 iflp->rmt_ip.s_addr = 0;
1914 UNSET_PARAM(iflp, LP_RMT_AS);
1915
1916 /* force protocols to update LINK STATE due to parameters change */
1917 if (if_is_operative (ifp))
1918 zebra_interface_parameters_update (ifp);
1919
1920 return CMD_SUCCESS;
1921}
1922
1923/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
1924DEFUN (link_params_delay,
1925 link_params_delay_cmd,
1926 "delay <0-16777215>",
1927 "Unidirectional Average Link Delay\n"
1928 "Average delay in micro-second as decimal (0...16777215)\n")
1929{
1930
1931 struct interface *ifp = (struct interface *) vty->index;
1932 struct if_link_params *iflp = if_link_params_get (ifp);
1933 u_int32_t delay = 0, low = 0, high = 0;
1934 u_int8_t update = 0;
1935
1936 /* Get and Check new delay values */
1937 VTY_GET_ULONG("delay", delay, argv[0]);
1938 switch (argc)
1939 {
1940 case 1:
1941 /* Check new delay value against old Min and Max delays if set */
1942 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
1943 && (delay <= iflp->min_delay || delay >= iflp->max_delay))
1944 {
1945 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1946 iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
1947 return CMD_WARNING;
1948 }
1949 /* Update delay if value is not set or change */
1950 if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
1951 {
1952 iflp->av_delay = delay;
1953 SET_PARAM(iflp, LP_DELAY);
1954 update = 1;
1955 }
1956 /* Unset Min and Max delays if already set */
1957 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
1958 {
1959 iflp->min_delay = 0;
1960 iflp->max_delay = 0;
1961 UNSET_PARAM(iflp, LP_MM_DELAY);
1962 update = 1;
1963 }
1964 break;
1965 case 2:
1966 vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
1967 VTY_NEWLINE);
1968 return CMD_WARNING;
1969 break;
1970 case 3:
1971 VTY_GET_ULONG("minimum delay", low, argv[1]);
1972 VTY_GET_ULONG("maximum delay", high, argv[2]);
1973 /* Check new delays value coherency */
1974 if (delay <= low || delay >= high)
1975 {
1976 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1977 low, high, VTY_NEWLINE);
1978 return CMD_WARNING;
1979 }
1980 /* Update Delays if needed */
1981 if (IS_PARAM_UNSET(iflp, LP_DELAY)
1982 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
1983 || iflp->av_delay != delay
1984 || iflp->min_delay != low
1985 || iflp->max_delay != high)
1986 {
1987 iflp->av_delay = delay;
1988 SET_PARAM(iflp, LP_DELAY);
1989 iflp->min_delay = low;
1990 iflp->max_delay = high;
1991 SET_PARAM(iflp, LP_MM_DELAY);
1992 update = 1;
1993 }
1994 break;
1995 default:
1996 return CMD_WARNING;
1997 break;
1998 }
1999
2000 /* force protocols to update LINK STATE due to parameters change */
2001 if (update == 1 && if_is_operative (ifp))
2002 zebra_interface_parameters_update (ifp);
2003
2004 return CMD_SUCCESS;
2005}
2006
2007ALIAS (link_params_delay,
2008 link_params_delay_mm_cmd,
2009 "delay <0-16777215> min <0-16777215> max <0-16777215>",
2010 "Unidirectional Average Link Delay (optionally Minimum and Maximum delays)\n"
2011 "Average delay in micro-second as decimal (0...16777215)\n"
2012 "Minimum delay\n"
2013 "Minimum delay in micro-second as decimal (0...16777215)\n"
2014 "Maximum delay\n"
2015 "Maximum delay in micro-second as decimal (0...16777215)\n")
2016
2017DEFUN (no_link_params_delay,
2018 no_link_params_delay_cmd,
2019 "no delay",
2020 NO_STR
2021 "Disbale Unidirectional Average, Min & Max Link Delay on this interface\n")
2022{
2023 struct interface *ifp = (struct interface *) vty->index;
2024 struct if_link_params *iflp = if_link_params_get (ifp);
2025
2026 /* Unset Delays */
2027 iflp->av_delay = 0;
2028 UNSET_PARAM(iflp, LP_DELAY);
2029 iflp->min_delay = 0;
2030 iflp->max_delay = 0;
2031 UNSET_PARAM(iflp, LP_MM_DELAY);
2032
2033 /* force protocols to update LINK STATE due to parameters change */
2034 if (if_is_operative (ifp))
2035 zebra_interface_parameters_update (ifp);
2036
2037 return CMD_SUCCESS;
2038}
2039
2040DEFUN (link_params_delay_var,
2041 link_params_delay_var_cmd,
2042 "delay-variation <0-16777215>",
2043 "Unidirectional Link Delay Variation\n"
2044 "delay variation in micro-second as decimal (0...16777215)\n")
2045{
2046 struct interface *ifp = (struct interface *) vty->index;
2047 struct if_link_params *iflp = if_link_params_get (ifp);
2048 u_int32_t value;
2049
2050 VTY_GET_ULONG("delay variation", value, argv[0]);
2051
2052 /* Update Delay Variation if needed */
2053 link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2054
2055 return CMD_SUCCESS;
2056}
2057
2058DEFUN (no_link_params_delay_var,
2059 no_link_params_delay_var_cmd,
2060 "no delay-variation",
2061 NO_STR
2062 "Disbale Unidirectional Delay Variation on this interface\n")
2063{
2064 struct interface *ifp = (struct interface *) vty->index;
2065
2066 /* Unset Delay Variation */
2067 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2068
2069 return CMD_SUCCESS;
2070}
2071
2072DEFUN (link_params_pkt_loss,
2073 link_params_pkt_loss_cmd,
2074 "packet-loss PERCENTAGE",
2075 "Unidirectional Link Packet Loss\n"
2076 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2077{
2078 struct interface *ifp = (struct interface *) vty->index;
2079 struct if_link_params *iflp = if_link_params_get (ifp);
2080 float fval;
2081
2082 if (sscanf (argv[0], "%g", &fval) != 1)
2083 {
2084 vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
2085 VTY_NEWLINE);
2086 return CMD_WARNING;
2087 }
2088
2089 if (fval > MAX_PKT_LOSS)
2090 fval = MAX_PKT_LOSS;
2091
2092 /* Update Packet Loss if needed */
2093 link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2094
2095 return CMD_SUCCESS;
2096}
2097
2098DEFUN (no_link_params_pkt_loss,
2099 no_link_params_pkt_loss_cmd,
2100 "no packet-loss",
2101 NO_STR
2102 "Disbale Unidirectional Link Packet Loss on this interface\n")
2103{
2104 struct interface *ifp = (struct interface *) vty->index;
2105
2106 /* Unset Packet Loss */
2107 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2108
2109 return CMD_SUCCESS;
2110}
2111
2112DEFUN (link_params_res_bw,
2113 link_params_res_bw_cmd,
2114 "res-bw BANDWIDTH",
2115 "Unidirectional Residual Bandwidth\n"
2116 "Bytes/second (IEEE floating point format)\n")
2117{
2118 struct interface *ifp = (struct interface *) vty->index;
2119 struct if_link_params *iflp = if_link_params_get (ifp);
2120 float bw;
2121
2122 if (sscanf (argv[0], "%g", &bw) != 1)
2123 {
2124 vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
2125 VTY_NEWLINE);
2126 return CMD_WARNING;
2127 }
2128
2129 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2130 if (bw > iflp->max_bw)
2131 {
2132 vty_out (vty,
2133 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2134 iflp->max_bw, VTY_NEWLINE);
2135 return CMD_WARNING;
2136 }
2137
2138 /* Update Residual Bandwidth if needed */
2139 link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
2140
2141 return CMD_SUCCESS;
2142}
2143
2144DEFUN (no_link_params_res_bw,
2145 no_link_params_res_bw_cmd,
2146 "no res-bw",
2147 NO_STR
2148 "Disbale Unidirectional Residual Bandwidth on this interface\n")
2149{
2150 struct interface *ifp = (struct interface *) vty->index;
2151
2152 /* Unset Residual Bandwidth */
2153 link_param_cmd_unset(ifp, LP_RES_BW);
2154
2155 return CMD_SUCCESS;
2156}
2157
2158DEFUN (link_params_ava_bw,
2159 link_params_ava_bw_cmd,
2160 "ava-bw BANDWIDTH",
2161 "Unidirectional Available Bandwidth\n"
2162 "Bytes/second (IEEE floating point format)\n")
2163{
2164 struct interface *ifp = (struct interface *) vty->index;
2165 struct if_link_params *iflp = if_link_params_get (ifp);
2166 float bw;
2167
2168 if (sscanf (argv[0], "%g", &bw) != 1)
2169 {
2170 vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
2171 VTY_NEWLINE);
2172 return CMD_WARNING;
2173 }
2174
2175 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2176 if (bw > iflp->max_bw)
2177 {
2178 vty_out (vty,
2179 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2180 iflp->max_bw, VTY_NEWLINE);
2181 return CMD_WARNING;
2182 }
2183
2184 /* Update Residual Bandwidth if needed */
2185 link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2186
2187 return CMD_SUCCESS;
2188}
2189
2190DEFUN (no_link_params_ava_bw,
2191 no_link_params_ava_bw_cmd,
2192 "no ava-bw",
2193 NO_STR
2194 "Disbale Unidirectional Available Bandwidth on this interface\n")
2195{
2196 struct interface *ifp = (struct interface *) vty->index;
2197
2198 /* Unset Available Bandwidth */
2199 link_param_cmd_unset(ifp, LP_AVA_BW);
2200
2201 return CMD_SUCCESS;
2202}
2203
2204DEFUN (link_params_use_bw,
2205 link_params_use_bw_cmd,
2206 "use-bw BANDWIDTH",
2207 "Unidirectional Utilised Bandwidth\n"
2208 "Bytes/second (IEEE floating point format)\n")
2209{
2210 struct interface *ifp = (struct interface *) vty->index;
2211 struct if_link_params *iflp = if_link_params_get (ifp);
2212 float bw;
2213
2214 if (sscanf (argv[0], "%g", &bw) != 1)
2215 {
2216 vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
2217 VTY_NEWLINE);
2218 return CMD_WARNING;
2219 }
2220
2221 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2222 if (bw > iflp->max_bw)
2223 {
2224 vty_out (vty,
2225 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2226 iflp->max_bw, VTY_NEWLINE);
2227 return CMD_WARNING;
2228 }
2229
2230 /* Update Utilized Bandwidth if needed */
2231 link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
2232
2233 return CMD_SUCCESS;
2234}
2235
2236DEFUN (no_link_params_use_bw,
2237 no_link_params_use_bw_cmd,
2238 "no use-bw",
2239 NO_STR
2240 "Disbale Unidirectional Utilised Bandwidth on this interface\n")
2241{
2242 struct interface *ifp = (struct interface *) vty->index;
2243
2244 /* Unset Utilised Bandwidth */
2245 link_param_cmd_unset(ifp, LP_USE_BW);
2246
2247 return CMD_SUCCESS;
2248}
2249
paula1ac18c2005-06-28 17:17:12 +00002250static int
hasso39db97e2004-10-12 20:50:58 +00002251ip_address_install (struct vty *vty, struct interface *ifp,
2252 const char *addr_str, const char *peer_str,
2253 const char *label)
paul718e3742002-12-13 20:15:29 +00002254{
Christian Frankebfac8dc2013-01-24 14:04:50 +00002255 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00002256 struct prefix_ipv4 cp;
2257 struct connected *ifc;
2258 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00002259 int ret;
2260
Christian Frankebfac8dc2013-01-24 14:04:50 +00002261 if_data = ifp->info;
2262
paul718e3742002-12-13 20:15:29 +00002263 ret = str2prefix_ipv4 (addr_str, &cp);
2264 if (ret <= 0)
2265 {
2266 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2267 return CMD_WARNING;
2268 }
2269
paulca162182005-09-12 16:58:52 +00002270 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002271 if (! ifc)
2272 {
2273 ifc = connected_new ();
2274 ifc->ifp = ifp;
2275
2276 /* Address. */
2277 p = prefix_ipv4_new ();
2278 *p = cp;
2279 ifc->address = (struct prefix *) p;
2280
2281 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00002282 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00002283 {
2284 p = prefix_ipv4_new ();
2285 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00002286 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00002287 ifc->destination = (struct prefix *) p;
2288 }
2289
paul718e3742002-12-13 20:15:29 +00002290 /* Label. */
2291 if (label)
paul0752ef02005-11-03 12:35:21 +00002292 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00002293
2294 /* Add to linked list. */
2295 listnode_add (ifp->connected, ifc);
2296 }
2297
2298 /* This address is configured from zebra. */
2299 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2300 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2301
2302 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002303 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00002304 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2305 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00002306 {
2307 /* Some system need to up the interface to set IP address. */
2308 if (! if_is_up (ifp))
2309 {
2310 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2311 if_refresh (ifp);
2312 }
2313
2314 ret = if_set_prefix (ifp, ifc);
2315 if (ret < 0)
2316 {
2317 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002318 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002319 return CMD_WARNING;
2320 }
2321
Christian Frankef7f740f2013-01-24 14:04:48 +00002322 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002323 /* The address will be advertised to zebra clients when the notification
2324 * from the kernel has been received.
2325 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00002326 }
2327
2328 return CMD_SUCCESS;
2329}
2330
paula1ac18c2005-06-28 17:17:12 +00002331static int
hasso39db97e2004-10-12 20:50:58 +00002332ip_address_uninstall (struct vty *vty, struct interface *ifp,
2333 const char *addr_str, const char *peer_str,
2334 const char *label)
paul718e3742002-12-13 20:15:29 +00002335{
2336 struct prefix_ipv4 cp;
2337 struct connected *ifc;
2338 int ret;
2339
2340 /* Convert to prefix structure. */
2341 ret = str2prefix_ipv4 (addr_str, &cp);
2342 if (ret <= 0)
2343 {
2344 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2345 return CMD_WARNING;
2346 }
2347
2348 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00002349 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002350 if (! ifc)
2351 {
2352 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2353 return CMD_WARNING;
2354 }
2355
2356 /* This is not configured address. */
2357 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2358 return CMD_WARNING;
2359
Paul Jakma74ecdc92006-06-15 18:10:47 +00002360 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2361
paul718e3742002-12-13 20:15:29 +00002362 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002363 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00002364 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2365 {
2366 listnode_delete (ifp->connected, ifc);
2367 connected_free (ifc);
2368 return CMD_WARNING;
2369 }
2370
2371 /* This is real route. */
2372 ret = if_unset_prefix (ifp, ifc);
2373 if (ret < 0)
2374 {
2375 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002376 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002377 return CMD_WARNING;
2378 }
Christian Frankef7f740f2013-01-24 14:04:48 +00002379 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002380 /* we will receive a kernel notification about this route being removed.
2381 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00002382 return CMD_SUCCESS;
2383}
2384
2385DEFUN (ip_address,
2386 ip_address_cmd,
2387 "ip address A.B.C.D/M",
2388 "Interface Internet Protocol config commands\n"
2389 "Set the IP address of an interface\n"
2390 "IP address (e.g. 10.0.0.1/8)\n")
2391{
hassoeef1fe12004-10-03 18:46:08 +00002392 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00002393}
2394
2395DEFUN (no_ip_address,
2396 no_ip_address_cmd,
2397 "no ip address A.B.C.D/M",
2398 NO_STR
2399 "Interface Internet Protocol config commands\n"
2400 "Set the IP address of an interface\n"
2401 "IP Address (e.g. 10.0.0.1/8)")
2402{
hassoeef1fe12004-10-03 18:46:08 +00002403 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00002404}
2405
2406#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00002407DEFUN (ip_address_label,
2408 ip_address_label_cmd,
2409 "ip address A.B.C.D/M label LINE",
2410 "Interface Internet Protocol config commands\n"
2411 "Set the IP address of an interface\n"
2412 "IP address (e.g. 10.0.0.1/8)\n"
2413 "Label of this address\n"
2414 "Label\n")
2415{
hassoeef1fe12004-10-03 18:46:08 +00002416 return ip_address_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00002417}
2418
2419DEFUN (no_ip_address_label,
2420 no_ip_address_label_cmd,
2421 "no ip address A.B.C.D/M label LINE",
2422 NO_STR
2423 "Interface Internet Protocol config commands\n"
2424 "Set the IP address of an interface\n"
2425 "IP address (e.g. 10.0.0.1/8)\n"
2426 "Label of this address\n"
2427 "Label\n")
2428{
hassoeef1fe12004-10-03 18:46:08 +00002429 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00002430}
2431#endif /* HAVE_NETLINK */
2432
2433#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002434static int
hasso39db97e2004-10-12 20:50:58 +00002435ipv6_address_install (struct vty *vty, struct interface *ifp,
2436 const char *addr_str, const char *peer_str,
2437 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00002438{
Christian Frankebfac8dc2013-01-24 14:04:50 +00002439 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00002440 struct prefix_ipv6 cp;
2441 struct connected *ifc;
2442 struct prefix_ipv6 *p;
2443 int ret;
2444
Christian Frankebfac8dc2013-01-24 14:04:50 +00002445 if_data = ifp->info;
2446
paul718e3742002-12-13 20:15:29 +00002447 ret = str2prefix_ipv6 (addr_str, &cp);
2448 if (ret <= 0)
2449 {
2450 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2451 return CMD_WARNING;
2452 }
2453
paulca162182005-09-12 16:58:52 +00002454 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002455 if (! ifc)
2456 {
2457 ifc = connected_new ();
2458 ifc->ifp = ifp;
2459
2460 /* Address. */
2461 p = prefix_ipv6_new ();
2462 *p = cp;
2463 ifc->address = (struct prefix *) p;
2464
2465 /* Secondary. */
2466 if (secondary)
2467 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
2468
2469 /* Label. */
2470 if (label)
paul0752ef02005-11-03 12:35:21 +00002471 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00002472
2473 /* Add to linked list. */
2474 listnode_add (ifp->connected, ifc);
2475 }
2476
2477 /* This address is configured from zebra. */
2478 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2479 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2480
2481 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002482 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00002483 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2484 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00002485 {
2486 /* Some system need to up the interface to set IP address. */
2487 if (! if_is_up (ifp))
2488 {
2489 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2490 if_refresh (ifp);
2491 }
2492
2493 ret = if_prefix_add_ipv6 (ifp, ifc);
2494
2495 if (ret < 0)
2496 {
2497 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002498 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002499 return CMD_WARNING;
2500 }
2501
Christian Frankef7f740f2013-01-24 14:04:48 +00002502 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002503 /* The address will be advertised to zebra clients when the notification
2504 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00002505 }
2506
2507 return CMD_SUCCESS;
2508}
2509
paula1ac18c2005-06-28 17:17:12 +00002510static int
hasso39db97e2004-10-12 20:50:58 +00002511ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
2512 const char *addr_str, const char *peer_str,
2513 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00002514{
2515 struct prefix_ipv6 cp;
2516 struct connected *ifc;
2517 int ret;
2518
2519 /* Convert to prefix structure. */
2520 ret = str2prefix_ipv6 (addr_str, &cp);
2521 if (ret <= 0)
2522 {
2523 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2524 return CMD_WARNING;
2525 }
2526
2527 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00002528 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002529 if (! ifc)
2530 {
2531 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2532 return CMD_WARNING;
2533 }
2534
2535 /* This is not configured address. */
2536 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2537 return CMD_WARNING;
2538
Christian Franke676e1a02013-01-24 14:04:45 +00002539 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2540
paul718e3742002-12-13 20:15:29 +00002541 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002542 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00002543 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2544 {
2545 listnode_delete (ifp->connected, ifc);
2546 connected_free (ifc);
2547 return CMD_WARNING;
2548 }
2549
2550 /* This is real route. */
2551 ret = if_prefix_delete_ipv6 (ifp, ifc);
2552 if (ret < 0)
2553 {
2554 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002555 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002556 return CMD_WARNING;
2557 }
2558
Christian Frankef7f740f2013-01-24 14:04:48 +00002559 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002560 /* This information will be propagated to the zclients when the
2561 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00002562 return CMD_SUCCESS;
2563}
2564
2565DEFUN (ipv6_address,
2566 ipv6_address_cmd,
2567 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00002568 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00002569 "Set the IP address of an interface\n"
2570 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2571{
2572 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
2573}
2574
2575DEFUN (no_ipv6_address,
2576 no_ipv6_address_cmd,
2577 "no ipv6 address X:X::X:X/M",
2578 NO_STR
hassoe23949c2004-03-11 15:54:02 +00002579 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00002580 "Set the IP address of an interface\n"
2581 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2582{
2583 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
2584}
2585#endif /* HAVE_IPV6 */
2586
paula1ac18c2005-06-28 17:17:12 +00002587static int
Olivier Dugeon15773a82016-04-19 18:29:55 +02002588link_params_config_write (struct vty *vty, struct interface *ifp)
2589{
Paul Jakma3676cb02016-07-29 13:39:37 +01002590 int i;
2591
Olivier Dugeon15773a82016-04-19 18:29:55 +02002592 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2593 return -1;
2594
2595 struct if_link_params *iflp = ifp->link_params;
2596
2597 vty_out (vty, " link-params%s", VTY_NEWLINE);
2598 vty_out(vty, " enable%s", VTY_NEWLINE);
2599 if (IS_PARAM_SET(iflp, LP_TE))
2600 vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
2601 if (IS_PARAM_SET(iflp, LP_MAX_BW))
2602 vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
2603 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2604 vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
2605 if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
2606 {
Paul Jakma3676cb02016-07-29 13:39:37 +01002607 for (i = 0; i < 8; i++)
Olivier Dugeon15773a82016-04-19 18:29:55 +02002608 vty_out(vty, " unrsv-bw %d %g%s",
2609 i, iflp->unrsv_bw[i], VTY_NEWLINE);
2610 }
2611 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2612 vty_out(vty, " admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE);
2613 if (IS_PARAM_SET(iflp, LP_DELAY))
2614 {
2615 vty_out(vty, " delay %u", iflp->av_delay);
2616 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2617 {
2618 vty_out(vty, " min %u", iflp->min_delay);
2619 vty_out(vty, " max %u", iflp->max_delay);
2620 }
2621 vty_out(vty, "%s", VTY_NEWLINE);
2622 }
2623 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2624 vty_out(vty, " delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
2625 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2626 vty_out(vty, " packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
2627 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2628 vty_out(vty, " ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
2629 if (IS_PARAM_SET(iflp, LP_RES_BW))
2630 vty_out(vty, " res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
2631 if (IS_PARAM_SET(iflp, LP_USE_BW))
2632 vty_out(vty, " use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
2633 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2634 vty_out(vty, " neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
2635 iflp->rmt_as, VTY_NEWLINE);
2636 return 0;
2637}
2638
2639static int
paul718e3742002-12-13 20:15:29 +00002640if_config_write (struct vty *vty)
2641{
hasso52dc7ee2004-09-23 19:18:23 +00002642 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002643 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02002644 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00002645
Feng Lu471ea392015-05-22 11:40:00 +02002646 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2647 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00002648 {
2649 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00002650 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00002651 struct connected *ifc;
2652 struct prefix *p;
2653
paul718e3742002-12-13 20:15:29 +00002654 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02002655
2656 if (ifp->vrf_id == VRF_DEFAULT)
2657 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2658 else
2659 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
2660 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002661
Christian Frankebfac8dc2013-01-24 14:04:50 +00002662 if (if_data)
2663 {
2664 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2665 vty_out (vty, " shutdown%s", VTY_NEWLINE);
2666 }
2667
paul718e3742002-12-13 20:15:29 +00002668 if (ifp->desc)
2669 vty_out (vty, " description %s%s", ifp->desc,
2670 VTY_NEWLINE);
2671
2672 /* Assign bandwidth here to avoid unnecessary interface flap
2673 while processing config script */
2674 if (ifp->bandwidth != 0)
2675 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002676
2677 switch (if_data->linkdetect)
2678 {
2679 case IF_LINKDETECT_ON:
2680 vty_out(vty, " link-detect%s", VTY_NEWLINE);
2681 break;
2682 case IF_LINKDETECT_OFF:
2683 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2684 break;
2685 default: break;
2686 }
2687
paul1eb8ef22005-04-07 07:30:20 +00002688 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00002689 {
paul718e3742002-12-13 20:15:29 +00002690 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2691 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07002692 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002693 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002694 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00002695 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03002696 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00002697
paul718e3742002-12-13 20:15:29 +00002698 if (ifc->label)
2699 vty_out (vty, " label %s", ifc->label);
2700
2701 vty_out (vty, "%s", VTY_NEWLINE);
2702 }
2703 }
2704
2705 if (if_data)
2706 {
paul718e3742002-12-13 20:15:29 +00002707 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2708 vty_out (vty, " %smulticast%s",
2709 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2710 VTY_NEWLINE);
2711 }
2712
Donald Sharp64257732015-11-20 08:33:30 -05002713#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +00002714 rtadv_config_write (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -05002715#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +00002716
hassoca776982004-06-12 14:33:05 +00002717#ifdef HAVE_IRDP
2718 irdp_config_write (vty, ifp);
2719#endif /* IRDP */
2720
Olivier Dugeon15773a82016-04-19 18:29:55 +02002721 link_params_config_write (vty, ifp);
2722
paul718e3742002-12-13 20:15:29 +00002723 vty_out (vty, "!%s", VTY_NEWLINE);
2724 }
2725 return 0;
2726}
2727
Olivier Dugeon15773a82016-04-19 18:29:55 +02002728
paul718e3742002-12-13 20:15:29 +00002729/* Allocate and initialize interface vector. */
2730void
paula1ac18c2005-06-28 17:17:12 +00002731zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00002732{
2733 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00002734 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2735 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2736
2737 /* Install configuration write function. */
2738 install_node (&interface_node, if_config_write);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002739
2740 install_node (&zebra_if_defaults_node, config_write_zebra_if_defaults);
paul718e3742002-12-13 20:15:29 +00002741
Olivier Dugeon15773a82016-04-19 18:29:55 +02002742 install_node (&link_params_node, NULL);
2743
paul718e3742002-12-13 20:15:29 +00002744 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02002745 install_element (VIEW_NODE, &show_interface_vrf_cmd);
2746 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
2747 install_element (VIEW_NODE, &show_interface_name_cmd);
2748 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2749 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00002750 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02002751 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00002752 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02002753 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002754 install_element (CONFIG_NODE, &default_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00002755 install_default (INTERFACE_NODE);
2756 install_element (INTERFACE_NODE, &interface_desc_cmd);
2757 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2758 install_element (INTERFACE_NODE, &multicast_cmd);
2759 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00002760 install_element (INTERFACE_NODE, &linkdetect_cmd);
2761 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00002762 install_element (INTERFACE_NODE, &shutdown_if_cmd);
2763 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2764 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2765 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
2766 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
2767 install_element (INTERFACE_NODE, &ip_address_cmd);
2768 install_element (INTERFACE_NODE, &no_ip_address_cmd);
2769#ifdef HAVE_IPV6
2770 install_element (INTERFACE_NODE, &ipv6_address_cmd);
2771 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
2772#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00002773#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00002774 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00002775 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00002776#endif /* HAVE_NETLINK */
Olivier Dugeon15773a82016-04-19 18:29:55 +02002777 install_element(INTERFACE_NODE, &link_params_cmd);
2778 install_default(LINK_PARAMS_NODE);
2779 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2780 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2781 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
2782 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2783 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2784 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2785 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
2786 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2787 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2788 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
2789 install_element(LINK_PARAMS_NODE, &link_params_delay_mm_cmd);
2790 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
2791 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
2792 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
2793 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
2794 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
paul718e3742002-12-13 20:15:29 +00002795}