blob: f8b946ff44b893c71148791ffabd2ac3aaf04fd5 [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
Donald Sharp4c7efde2015-11-16 18:19:18 -0500739 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED))
740 vty_out (vty, " unnumbered");
741
paul718e3742002-12-13 20:15:29 +0000742 if (connected->label)
743 vty_out (vty, " %s", connected->label);
744
745 vty_out (vty, "%s", VTY_NEWLINE);
746}
747
Donald Sharp64257732015-11-20 08:33:30 -0500748#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000749/* Dump interface ND information to vty. */
paula1ac18c2005-06-28 17:17:12 +0000750static void
paul718e3742002-12-13 20:15:29 +0000751nd_dump_vty (struct vty *vty, struct interface *ifp)
752{
753 struct zebra_if *zif;
754 struct rtadvconf *rtadv;
vincent7cee1bb2005-03-25 13:08:53 +0000755 int interval;
paul718e3742002-12-13 20:15:29 +0000756
757 zif = (struct zebra_if *) ifp->info;
758 rtadv = &zif->rtadv;
759
760 if (rtadv->AdvSendAdvertisements)
761 {
762 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
763 rtadv->AdvReachableTime, VTY_NEWLINE);
764 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
765 rtadv->AdvRetransTimer, VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000766 interval = rtadv->MaxRtrAdvInterval;
767 if (interval % 1000)
768 vty_out (vty, " ND router advertisements are sent every "
769 "%d milliseconds%s", interval,
770 VTY_NEWLINE);
771 else
772 vty_out (vty, " ND router advertisements are sent every "
773 "%d seconds%s", interval / 1000,
774 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400775 if (rtadv->AdvDefaultLifetime != -1)
776 vty_out (vty, " ND router advertisements live for %d seconds%s",
777 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
778 else
779 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
780 VTY_NEWLINE);
Chris Caputob60668d2009-05-03 04:40:57 +0000781 vty_out (vty, " ND router advertisement default router preference is "
782 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
783 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000784 if (rtadv->AdvManagedFlag)
785 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
786 VTY_NEWLINE);
787 else
788 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
789 VTY_NEWLINE);
vincent7cee1bb2005-03-25 13:08:53 +0000790 if (rtadv->AdvHomeAgentFlag)
Denis Ovsienkod660f692011-12-30 21:55:49 +0400791 {
vincent7cee1bb2005-03-25 13:08:53 +0000792 vty_out (vty, " ND router advertisements with "
793 "Home Agent flag bit set.%s",
794 VTY_NEWLINE);
Denis Ovsienkod660f692011-12-30 21:55:49 +0400795 if (rtadv->HomeAgentLifetime != -1)
796 vty_out (vty, " Home Agent lifetime is %u seconds%s",
797 rtadv->HomeAgentLifetime, VTY_NEWLINE);
798 else
799 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
800 VTY_NEWLINE);
801 vty_out (vty, " Home Agent preference is %u%s",
802 rtadv->HomeAgentPreference, VTY_NEWLINE);
803 }
vincent7cee1bb2005-03-25 13:08:53 +0000804 if (rtadv->AdvIntervalOption)
805 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
806 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000807 }
808}
Donald Sharp64257732015-11-20 08:33:30 -0500809#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000810
811/* Interface's information print out to vty interface. */
paula1ac18c2005-06-28 17:17:12 +0000812static void
paul718e3742002-12-13 20:15:29 +0000813if_dump_vty (struct vty *vty, struct interface *ifp)
814{
paul718e3742002-12-13 20:15:29 +0000815 struct connected *connected;
hasso52dc7ee2004-09-23 19:18:23 +0000816 struct listnode *node;
hassoeef1fe12004-10-03 18:46:08 +0000817 struct route_node *rn;
818 struct zebra_if *zebra_if;
819
820 zebra_if = ifp->info;
paul718e3742002-12-13 20:15:29 +0000821
paul2e3b2e42002-12-13 21:03:13 +0000822 vty_out (vty, "Interface %s is ", ifp->name);
823 if (if_is_up(ifp)) {
824 vty_out (vty, "up, line protocol ");
825
826 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
827 if (if_is_running(ifp))
828 vty_out (vty, "is up%s", VTY_NEWLINE);
829 else
830 vty_out (vty, "is down%s", VTY_NEWLINE);
831 } else {
832 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
833 }
834 } else {
835 vty_out (vty, "down%s", VTY_NEWLINE);
836 }
837
Christian Franke581ecbf2016-05-03 19:59:43 +0200838 vty_out (vty, " Link ups: %s%s",
839 event_counter_format(&zebra_if->up_events), VTY_NEWLINE);
840 vty_out (vty, " Link downs: %s%s",
841 event_counter_format(&zebra_if->down_events), VTY_NEWLINE);
842
Feng Lu2fc97f62015-05-22 11:39:57 +0200843 vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
844
paul718e3742002-12-13 20:15:29 +0000845 if (ifp->desc)
846 vty_out (vty, " Description: %s%s", ifp->desc,
847 VTY_NEWLINE);
ajsd2fc8892005-04-02 18:38:43 +0000848 if (ifp->ifindex == IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +0000849 {
ajsd2fc8892005-04-02 18:38:43 +0000850 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000851 return;
852 }
853 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
854 {
855 vty_out(vty, " index %d inactive interface%s",
856 ifp->ifindex,
857 VTY_NEWLINE);
858 return;
859 }
860
861 vty_out (vty, " index %d metric %d mtu %d ",
862 ifp->ifindex, ifp->metric, ifp->mtu);
paul44145db2004-05-09 11:00:23 +0000863#ifdef HAVE_IPV6
864 if (ifp->mtu6 != ifp->mtu)
865 vty_out (vty, "mtu6 %d ", ifp->mtu6);
866#endif
Paul Jakma630c97c2006-06-15 12:48:17 +0000867 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
868 if_flag_dump (ifp->flags), VTY_NEWLINE);
paul3a570c82006-02-02 17:27:13 +0000869
paul718e3742002-12-13 20:15:29 +0000870 /* Hardware address. */
Timo Teräs954c7d62016-01-15 17:36:33 +0200871 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000872 if (ifp->hw_addr_len != 0)
873 {
874 int i;
875
876 vty_out (vty, " HWaddr: ");
877 for (i = 0; i < ifp->hw_addr_len; i++)
878 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
879 vty_out (vty, "%s", VTY_NEWLINE);
880 }
paul718e3742002-12-13 20:15:29 +0000881
882 /* Bandwidth in kbps */
883 if (ifp->bandwidth != 0)
884 {
885 vty_out(vty, " bandwidth %u kbps", ifp->bandwidth);
886 vty_out(vty, "%s", VTY_NEWLINE);
887 }
888
hassoeef1fe12004-10-03 18:46:08 +0000889 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
paul718e3742002-12-13 20:15:29 +0000890 {
hassoeef1fe12004-10-03 18:46:08 +0000891 if (! rn->info)
892 continue;
Olivier Dugeon15773a82016-04-19 18:29:55 +0200893
paul1eb8ef22005-04-07 07:30:20 +0000894 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
895 connected_dump_vty (vty, connected);
paul718e3742002-12-13 20:15:29 +0000896 }
897
paul1eb8ef22005-04-07 07:30:20 +0000898 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
hasso39db97e2004-10-12 20:50:58 +0000899 {
hasso39db97e2004-10-12 20:50:58 +0000900 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
901 (connected->address->family == AF_INET6))
902 connected_dump_vty (vty, connected);
903 }
904
Olivier Dugeon15773a82016-04-19 18:29:55 +0200905 if (HAS_LINK_PARAMS(ifp))
906 {
907 int i;
908 struct if_link_params *iflp = ifp->link_params;
909 vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
910 if (IS_PARAM_SET(iflp, LP_TE))
911 vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
912 if (IS_PARAM_SET(iflp, LP_MAX_BW))
913 vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
914 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
915 vty_out(vty, " Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
916 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
917 vty_out(vty, " Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
918 for (i = 0; i < MAX_CLASS_TYPE; i+=2)
919 vty_out(vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
920 i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
921 }
922
923 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
924 vty_out(vty, " Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
925 if (IS_PARAM_SET(iflp, LP_DELAY))
926 {
927 vty_out(vty, " Link Delay Average: %u (micro-sec.)", iflp->av_delay);
928 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
929 {
930 vty_out(vty, " Min: %u (micro-sec.)", iflp->min_delay);
931 vty_out(vty, " Max: %u (micro-sec.)", iflp->max_delay);
932 }
933 vty_out(vty, "%s", VTY_NEWLINE);
934 }
935 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
936 vty_out(vty, " Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
937 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
938 vty_out(vty, " Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
939 if (IS_PARAM_SET(iflp, LP_AVA_BW))
940 vty_out(vty, " Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
941 if (IS_PARAM_SET(iflp, LP_RES_BW))
942 vty_out(vty, " Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
943 if (IS_PARAM_SET(iflp, LP_USE_BW))
944 vty_out(vty, " Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
945 if (IS_PARAM_SET(iflp, LP_RMT_AS))
946 vty_out(vty, " Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
947 }
948
949 #ifdef RTADV
950 nd_dump_vty (vty, ifp);
951 #endif /* RTADV */
Donald Sharp64257732015-11-20 08:33:30 -0500952#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +0000953 nd_dump_vty (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -0500954#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +0000955
956#ifdef HAVE_PROC_NET_DEV
957 /* Statistics print out using proc file system. */
hasso6f2c27a2005-01-18 13:44:35 +0000958 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
959 "%lu dropped%s",
960 ifp->stats.rx_packets, ifp->stats.rx_multicast,
961 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000962
hasso6f2c27a2005-01-18 13:44:35 +0000963 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
hasso3452d472005-03-06 13:42:05 +0000964 " %lu CRC, %lu frame%s",
paul718e3742002-12-13 20:15:29 +0000965 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
966 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000967 ifp->stats.rx_frame_errors, VTY_NEWLINE);
968
969 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
paul718e3742002-12-13 20:15:29 +0000970 ifp->stats.rx_missed_errors, VTY_NEWLINE);
971
hasso6f2c27a2005-01-18 13:44:35 +0000972 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
paul718e3742002-12-13 20:15:29 +0000973 ifp->stats.tx_packets, ifp->stats.tx_bytes,
974 ifp->stats.tx_dropped, VTY_NEWLINE);
975
hasso6f2c27a2005-01-18 13:44:35 +0000976 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
977 " %lu fifo, %lu heartbeat%s",
paul718e3742002-12-13 20:15:29 +0000978 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
979 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
hasso6f2c27a2005-01-18 13:44:35 +0000980 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000981
hasso6f2c27a2005-01-18 13:44:35 +0000982 vty_out (vty, " %lu window, %lu collisions%s",
983 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000984#endif /* HAVE_PROC_NET_DEV */
985
986#ifdef HAVE_NET_RT_IFLIST
987#if defined (__bsdi__) || defined (__NetBSD__)
988 /* Statistics print out using sysctl (). */
David Lamparter193e78f2015-04-21 10:42:30 +0200989 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
990 " multicast packets %llu%s",
991 (unsigned long long)ifp->stats.ifi_ipackets,
992 (unsigned long long)ifp->stats.ifi_ibytes,
993 (unsigned long long)ifp->stats.ifi_iqdrops,
994 (unsigned long long)ifp->stats.ifi_imcasts,
995 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000996
David Lamparter193e78f2015-04-21 10:42:30 +0200997 vty_out (vty, " input errors %llu%s",
998 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000999
David Lamparter193e78f2015-04-21 10:42:30 +02001000 vty_out (vty, " output packets %llu, bytes %llu,"
1001 " multicast packets %llu%s",
1002 (unsigned long long)ifp->stats.ifi_opackets,
1003 (unsigned long long)ifp->stats.ifi_obytes,
1004 (unsigned long long)ifp->stats.ifi_omcasts,
1005 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001006
David Lamparter193e78f2015-04-21 10:42:30 +02001007 vty_out (vty, " output errors %llu%s",
1008 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001009
David Lamparter193e78f2015-04-21 10:42:30 +02001010 vty_out (vty, " collisions %llu%s",
1011 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00001012#else
1013 /* Statistics print out using sysctl (). */
1014 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
1015 " multicast packets %lu%s",
1016 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1017 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1018 VTY_NEWLINE);
1019
1020 vty_out (vty, " input errors %lu%s",
1021 ifp->stats.ifi_ierrors, VTY_NEWLINE);
1022
1023 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
1024 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1025 ifp->stats.ifi_omcasts, VTY_NEWLINE);
1026
1027 vty_out (vty, " output errors %lu%s",
1028 ifp->stats.ifi_oerrors, VTY_NEWLINE);
1029
1030 vty_out (vty, " collisions %lu%s",
1031 ifp->stats.ifi_collisions, VTY_NEWLINE);
1032#endif /* __bsdi__ || __NetBSD__ */
1033#endif /* HAVE_NET_RT_IFLIST */
1034}
1035
paul718e3742002-12-13 20:15:29 +00001036/* Wrapper hook point for zebra daemon so that ifindex can be set
1037 * DEFUN macro not used as extract.pl HAS to ignore this
1038 * See also interface_cmd in lib/if.c
1039 */
1040DEFUN_NOSH (zebra_interface,
1041 zebra_interface_cmd,
1042 "interface IFNAME",
1043 "Select an interface to configure\n"
1044 "Interface's name\n")
1045{
1046 int ret;
Olivier Dugeon15773a82016-04-19 18:29:55 +02001047 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +00001048
1049 /* Call lib interface() */
ajsd2fc8892005-04-02 18:38:43 +00001050 if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
1051 return ret;
paul718e3742002-12-13 20:15:29 +00001052
Olivier Dugeon15773a82016-04-19 18:29:55 +02001053 ifp = vty->index;
paul718e3742002-12-13 20:15:29 +00001054
ajsd2fc8892005-04-02 18:38:43 +00001055 if (ifp->ifindex == IFINDEX_INTERNAL)
1056 /* Is this really necessary? Shouldn't status be initialized to 0
1057 in that case? */
1058 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
paul718e3742002-12-13 20:15:29 +00001059
1060 return ret;
1061}
1062
Feng Lu471ea392015-05-22 11:40:00 +02001063ALIAS (zebra_interface,
1064 zebra_interface_vrf_cmd,
1065 "interface IFNAME " VRF_CMD_STR,
1066 "Select an interface to configure\n"
1067 "Interface's name\n"
1068 VRF_CMD_HELP_STR)
1069
paul718e3742002-12-13 20:15:29 +00001070struct cmd_node interface_node =
1071{
1072 INTERFACE_NODE,
1073 "%s(config-if)# ",
1074 1
1075};
1076
Feng Lua2854772015-05-22 11:40:01 +02001077/* Show all interfaces to vty. */
paul718e3742002-12-13 20:15:29 +00001078DEFUN (show_interface, show_interface_cmd,
Feng Lua2854772015-05-22 11:40:01 +02001079 "show interface",
paul718e3742002-12-13 20:15:29 +00001080 SHOW_STR
Feng Lua2854772015-05-22 11:40:01 +02001081 "Interface status and configuration\n")
paul718e3742002-12-13 20:15:29 +00001082{
hasso52dc7ee2004-09-23 19:18:23 +00001083 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001084 struct interface *ifp;
Feng Lua2854772015-05-22 11:40:01 +02001085 vrf_id_t vrf_id = VRF_DEFAULT;
1086
paul718e3742002-12-13 20:15:29 +00001087#ifdef HAVE_PROC_NET_DEV
1088 /* If system has interface statistics via proc file system, update
1089 statistics. */
1090 ifstat_update_proc ();
1091#endif /* HAVE_PROC_NET_DEV */
1092#ifdef HAVE_NET_RT_IFLIST
1093 ifstat_update_sysctl ();
1094#endif /* HAVE_NET_RT_IFLIST */
1095
Feng Lua2854772015-05-22 11:40:01 +02001096 if (argc > 0)
1097 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
paul718e3742002-12-13 20:15:29 +00001098
1099 /* All interface print. */
Feng Lua2854772015-05-22 11:40:01 +02001100 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
paul1eb8ef22005-04-07 07:30:20 +00001101 if_dump_vty (vty, ifp);
paul718e3742002-12-13 20:15:29 +00001102
1103 return CMD_SUCCESS;
1104}
1105
Feng Lua2854772015-05-22 11:40:01 +02001106ALIAS (show_interface,
1107 show_interface_vrf_cmd,
1108 "show interface " VRF_CMD_STR,
hassoed9bb6d2005-03-13 19:17:21 +00001109 SHOW_STR
1110 "Interface status and configuration\n"
Feng Lua2854772015-05-22 11:40:01 +02001111 VRF_CMD_HELP_STR)
1112
1113/* Show all interfaces to vty. */
1114DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
1115 "show interface " VRF_ALL_CMD_STR,
1116 SHOW_STR
1117 "Interface status and configuration\n"
1118 VRF_ALL_CMD_HELP_STR)
1119{
1120 struct listnode *node;
1121 struct interface *ifp;
1122 vrf_iter_t iter;
1123
1124#ifdef HAVE_PROC_NET_DEV
1125 /* If system has interface statistics via proc file system, update
1126 statistics. */
1127 ifstat_update_proc ();
1128#endif /* HAVE_PROC_NET_DEV */
1129#ifdef HAVE_NET_RT_IFLIST
1130 ifstat_update_sysctl ();
1131#endif /* HAVE_NET_RT_IFLIST */
1132
1133 /* All interface print. */
1134 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1135 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1136 if_dump_vty (vty, ifp);
1137
1138 return CMD_SUCCESS;
1139}
1140
1141/* Show specified interface to vty. */
1142DEFUN (show_interface_name, show_interface_name_cmd,
1143 "show interface IFNAME",
1144 SHOW_STR
1145 "Interface status and configuration\n"
1146 "Inteface name\n")
1147{
1148 struct interface *ifp;
1149 vrf_id_t vrf_id = VRF_DEFAULT;
1150
1151#ifdef HAVE_PROC_NET_DEV
1152 /* If system has interface statistics via proc file system, update
1153 statistics. */
1154 ifstat_update_proc ();
1155#endif /* HAVE_PROC_NET_DEV */
1156#ifdef HAVE_NET_RT_IFLIST
1157 ifstat_update_sysctl ();
1158#endif /* HAVE_NET_RT_IFLIST */
1159
1160 if (argc > 1)
1161 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
1162
1163 /* Specified interface print. */
1164 ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
1165 if (ifp == NULL)
1166 {
1167 vty_out (vty, "%% Can't find interface %s%s", argv[0],
1168 VTY_NEWLINE);
1169 return CMD_WARNING;
1170 }
1171 if_dump_vty (vty, ifp);
1172
1173 return CMD_SUCCESS;
1174}
1175
1176ALIAS (show_interface_name,
1177 show_interface_name_vrf_cmd,
1178 "show interface IFNAME " VRF_CMD_STR,
1179 SHOW_STR
1180 "Interface status and configuration\n"
1181 "Inteface name\n"
1182 VRF_CMD_HELP_STR)
1183
1184/* Show specified interface to vty. */
1185DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
1186 "show interface IFNAME " VRF_ALL_CMD_STR,
1187 SHOW_STR
1188 "Interface status and configuration\n"
1189 "Inteface name\n"
1190 VRF_ALL_CMD_HELP_STR)
1191{
1192 struct interface *ifp;
1193 vrf_iter_t iter;
1194 int found = 0;
1195
1196#ifdef HAVE_PROC_NET_DEV
1197 /* If system has interface statistics via proc file system, update
1198 statistics. */
1199 ifstat_update_proc ();
1200#endif /* HAVE_PROC_NET_DEV */
1201#ifdef HAVE_NET_RT_IFLIST
1202 ifstat_update_sysctl ();
1203#endif /* HAVE_NET_RT_IFLIST */
1204
1205 /* All interface print. */
1206 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1207 {
1208 /* Specified interface print. */
1209 ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
1210 if (ifp)
1211 {
1212 if_dump_vty (vty, ifp);
1213 found++;
1214 }
1215 }
1216
1217 if (!found)
1218 {
1219 vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
1220 return CMD_WARNING;
1221 }
1222
1223 return CMD_SUCCESS;
1224}
1225
1226static void
1227if_show_description (struct vty *vty, vrf_id_t vrf_id)
hassoed9bb6d2005-03-13 19:17:21 +00001228{
1229 struct listnode *node;
1230 struct interface *ifp;
1231
1232 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
Feng Lua2854772015-05-22 11:40:01 +02001233 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
hassoed9bb6d2005-03-13 19:17:21 +00001234 {
1235 int len;
hassoed9bb6d2005-03-13 19:17:21 +00001236
1237 len = vty_out (vty, "%s", ifp->name);
1238 vty_out (vty, "%*s", (16 - len), " ");
1239
1240 if (if_is_up(ifp))
1241 {
1242 vty_out (vty, "up ");
1243 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1244 {
1245 if (if_is_running(ifp))
1246 vty_out (vty, "up ");
1247 else
1248 vty_out (vty, "down ");
1249 }
1250 else
1251 {
1252 vty_out (vty, "unknown ");
1253 }
1254 }
1255 else
1256 {
1257 vty_out (vty, "down down ");
1258 }
1259
1260 if (ifp->desc)
1261 vty_out (vty, "%s", ifp->desc);
1262 vty_out (vty, "%s", VTY_NEWLINE);
1263 }
Feng Lua2854772015-05-22 11:40:01 +02001264}
1265
1266DEFUN (show_interface_desc,
1267 show_interface_desc_cmd,
1268 "show interface description",
1269 SHOW_STR
1270 "Interface status and configuration\n"
1271 "Interface description\n")
1272{
1273 vrf_id_t vrf_id = VRF_DEFAULT;
1274
1275 if (argc > 0)
1276 VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
1277
1278 if_show_description (vty, vrf_id);
1279
1280 return CMD_SUCCESS;
1281}
1282
1283ALIAS (show_interface_desc,
1284 show_interface_desc_vrf_cmd,
1285 "show interface description " VRF_CMD_STR,
1286 SHOW_STR
1287 "Interface status and configuration\n"
1288 "Interface description\n"
1289 VRF_CMD_HELP_STR)
1290
1291DEFUN (show_interface_desc_vrf_all,
1292 show_interface_desc_vrf_all_cmd,
1293 "show interface description " VRF_ALL_CMD_STR,
1294 SHOW_STR
1295 "Interface status and configuration\n"
1296 "Interface description\n"
1297 VRF_ALL_CMD_HELP_STR)
1298{
1299 vrf_iter_t iter;
1300
1301 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1302 if (!list_isempty (vrf_iter2iflist (iter)))
1303 {
1304 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
1305 vrf_iter2id (iter),
1306 VTY_NEWLINE, VTY_NEWLINE);
1307 if_show_description (vty, vrf_iter2id (iter));
1308 }
1309
hassoed9bb6d2005-03-13 19:17:21 +00001310 return CMD_SUCCESS;
1311}
1312
paul718e3742002-12-13 20:15:29 +00001313DEFUN (multicast,
1314 multicast_cmd,
1315 "multicast",
1316 "Set multicast flag to interface\n")
1317{
1318 int ret;
1319 struct interface *ifp;
1320 struct zebra_if *if_data;
1321
1322 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001323 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001324 {
paul48b33aa2002-12-13 20:52:52 +00001325 ret = if_set_flags (ifp, IFF_MULTICAST);
1326 if (ret < 0)
1327 {
1328 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1329 return CMD_WARNING;
1330 }
1331 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001332 }
paul718e3742002-12-13 20:15:29 +00001333 if_data = ifp->info;
1334 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
paul48b33aa2002-12-13 20:52:52 +00001335
paul718e3742002-12-13 20:15:29 +00001336 return CMD_SUCCESS;
1337}
1338
1339DEFUN (no_multicast,
1340 no_multicast_cmd,
1341 "no multicast",
1342 NO_STR
1343 "Unset multicast flag to interface\n")
1344{
1345 int ret;
1346 struct interface *ifp;
1347 struct zebra_if *if_data;
1348
1349 ifp = (struct interface *) vty->index;
paul48b33aa2002-12-13 20:52:52 +00001350 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
paul718e3742002-12-13 20:15:29 +00001351 {
paul48b33aa2002-12-13 20:52:52 +00001352 ret = if_unset_flags (ifp, IFF_MULTICAST);
1353 if (ret < 0)
1354 {
1355 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1356 return CMD_WARNING;
1357 }
1358 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001359 }
paul718e3742002-12-13 20:15:29 +00001360 if_data = ifp->info;
1361 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1362
1363 return CMD_SUCCESS;
1364}
1365
Paul Jakma8f4269d2015-09-18 11:50:33 +01001366/* Hacky: create a dummy node just to hang a config-writer callback off it */
1367static struct cmd_node zebra_if_defaults_node = {
1368 ZEBRA_IF_DEFAULTS_NODE,
1369 "",
1370 1,
1371};
1372
1373static int
1374config_write_zebra_if_defaults (struct vty *vty)
1375{
1376 if (zif_defaults.linkdetect != IF_LINKDETECT_UNSPEC)
1377 vty_out (vty, "default link-detect %s%s",
1378 zif_defaults.linkdetect == IF_LINKDETECT_ON ? "on" : "off",
1379 VTY_NEWLINE);
1380 return 0;
1381}
1382
1383DEFUN(default_linkdetect,
1384 default_linkdetect_cmd,
1385 "default link-detect (on|off)",
1386 "Configure defaults of settings\n"
1387 "Interface link detection\n"
1388 "Interface link-detect defaults to enabled\n"
1389 "Interface link-detect defaults to disabled\n")
1390{
1391 zebra_if_linkdetect prev = zif_defaults.linkdetect;
1392 struct listnode *node;
1393 struct interface *ifp;
1394 vrf_iter_t iter;
1395
1396 if (strcmp (argv[1], "on") == 0)
1397 zif_defaults.linkdetect = IF_LINKDETECT_ON;
1398 else
1399 zif_defaults.linkdetect = IF_LINKDETECT_OFF;
1400
1401 if (zif_defaults.linkdetect != prev)
1402 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
1403 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
1404 if_zebra_linkdetect_set (ifp);
1405
1406 return CMD_SUCCESS;
1407}
1408
paul2e3b2e42002-12-13 21:03:13 +00001409DEFUN (linkdetect,
1410 linkdetect_cmd,
Paul Jakma8f4269d2015-09-18 11:50:33 +01001411 "link-detect [default]",
1412 "Enable link detection on interface\n"
1413 "Leave link-detect to the default\n")
paul2e3b2e42002-12-13 21:03:13 +00001414{
paul2e3b2e42002-12-13 21:03:13 +00001415 struct interface *ifp;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001416 struct zebra_if *zif;
paul2e3b2e42002-12-13 21:03:13 +00001417
1418 ifp = (struct interface *) vty->index;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001419 zif = ifp->info;
1420 assert (zif != NULL);
1421
1422 zif->linkdetect = IF_LINKDETECT_ON;
1423 if_zebra_linkdetect_set (ifp);
1424
paul2e3b2e42002-12-13 21:03:13 +00001425 /* FIXME: Will defer status change forwarding if interface
1426 does not come down! */
1427
1428 return CMD_SUCCESS;
1429}
1430
1431
1432DEFUN (no_linkdetect,
1433 no_linkdetect_cmd,
1434 "no link-detect",
1435 NO_STR
1436 "Disable link detection on interface\n")
1437{
paul2e3b2e42002-12-13 21:03:13 +00001438 struct interface *ifp;
Paul Jakma8f4269d2015-09-18 11:50:33 +01001439 struct zebra_if *zif;
paul2e3b2e42002-12-13 21:03:13 +00001440
Paul Jakma8f4269d2015-09-18 11:50:33 +01001441 ifp = (struct interface *) vty->index;
1442 zif = ifp->info;
1443 assert (zif != NULL);
1444
1445 zif->linkdetect = IF_LINKDETECT_OFF;
1446 if_zebra_linkdetect_set (ifp);
1447
paul2e3b2e42002-12-13 21:03:13 +00001448 /* FIXME: see linkdetect_cmd */
1449
1450 return CMD_SUCCESS;
1451}
1452
paul718e3742002-12-13 20:15:29 +00001453DEFUN (shutdown_if,
1454 shutdown_if_cmd,
1455 "shutdown",
1456 "Shutdown the selected interface\n")
1457{
1458 int ret;
1459 struct interface *ifp;
1460 struct zebra_if *if_data;
1461
1462 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001463 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001464 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001465 ret = if_unset_flags (ifp, IFF_UP);
1466 if (ret < 0)
1467 {
1468 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1469 return CMD_WARNING;
1470 }
1471 if_refresh (ifp);
paul718e3742002-12-13 20:15:29 +00001472 }
paul718e3742002-12-13 20:15:29 +00001473 if_data = ifp->info;
1474 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1475
1476 return CMD_SUCCESS;
1477}
1478
1479DEFUN (no_shutdown_if,
1480 no_shutdown_if_cmd,
1481 "no shutdown",
1482 NO_STR
1483 "Shutdown the selected interface\n")
1484{
1485 int ret;
1486 struct interface *ifp;
1487 struct zebra_if *if_data;
1488
1489 ifp = (struct interface *) vty->index;
Christian Frankebfac8dc2013-01-24 14:04:50 +00001490
1491 if (ifp->ifindex != IFINDEX_INTERNAL)
paul718e3742002-12-13 20:15:29 +00001492 {
Christian Frankebfac8dc2013-01-24 14:04:50 +00001493 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1494 if (ret < 0)
1495 {
1496 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1497 return CMD_WARNING;
1498 }
1499 if_refresh (ifp);
1500
1501 /* Some addresses (in particular, IPv6 addresses on Linux) get
1502 * removed when the interface goes down. They need to be readded.
1503 */
1504 if_addr_wakeup(ifp);
paul718e3742002-12-13 20:15:29 +00001505 }
Christian Frankebfac8dc2013-01-24 14:04:50 +00001506
paul718e3742002-12-13 20:15:29 +00001507 if_data = ifp->info;
1508 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1509
1510 return CMD_SUCCESS;
1511}
1512
1513DEFUN (bandwidth_if,
1514 bandwidth_if_cmd,
1515 "bandwidth <1-10000000>",
1516 "Set bandwidth informational parameter\n"
1517 "Bandwidth in kilobits\n")
1518{
1519 struct interface *ifp;
1520 unsigned int bandwidth;
1521
1522 ifp = (struct interface *) vty->index;
1523 bandwidth = strtol(argv[0], NULL, 10);
1524
1525 /* bandwidth range is <1-10000000> */
1526 if (bandwidth < 1 || bandwidth > 10000000)
1527 {
1528 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1529 return CMD_WARNING;
1530 }
1531
1532 ifp->bandwidth = bandwidth;
1533
1534 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001535 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001536 zebra_interface_up_update (ifp);
1537
1538 return CMD_SUCCESS;
1539}
1540
1541DEFUN (no_bandwidth_if,
1542 no_bandwidth_if_cmd,
1543 "no bandwidth",
1544 NO_STR
1545 "Set bandwidth informational parameter\n")
1546{
1547 struct interface *ifp;
1548
1549 ifp = (struct interface *) vty->index;
1550
1551 ifp->bandwidth = 0;
1552
1553 /* force protocols to recalculate routes due to cost change */
paul2e3b2e42002-12-13 21:03:13 +00001554 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001555 zebra_interface_up_update (ifp);
1556
1557 return CMD_SUCCESS;
1558}
1559
1560ALIAS (no_bandwidth_if,
1561 no_bandwidth_if_val_cmd,
1562 "no bandwidth <1-10000000>",
1563 NO_STR
1564 "Set bandwidth informational parameter\n"
1565 "Bandwidth in kilobits\n")
David Lamparter6b0655a2014-06-04 06:53:35 +02001566
Olivier Dugeon15773a82016-04-19 18:29:55 +02001567struct cmd_node link_params_node =
1568{
1569 LINK_PARAMS_NODE,
1570 "%s(config-link-params)# ",
1571 1,
1572};
1573
1574static void
1575link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field,
1576 uint32_t type, uint32_t value)
1577{
1578 /* Update field as needed */
1579 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1580 {
1581 *field = value;
1582 SET_PARAM(ifp->link_params, type);
1583
1584 /* force protocols to update LINK STATE due to parameters change */
1585 if (if_is_operative (ifp))
1586 zebra_interface_parameters_update (ifp);
1587 }
1588}
1589static void
1590link_param_cmd_set_float (struct interface *ifp, float *field,
1591 uint32_t type, float value)
1592{
1593
1594 /* Update field as needed */
1595 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1596 {
1597 *field = value;
1598 SET_PARAM(ifp->link_params, type);
1599
1600 /* force protocols to update LINK STATE due to parameters change */
1601 if (if_is_operative (ifp))
1602 zebra_interface_parameters_update (ifp);
1603 }
1604}
1605
1606static void
1607link_param_cmd_unset (struct interface *ifp, uint32_t type)
1608{
1609
1610 /* Unset field */
1611 UNSET_PARAM(ifp->link_params, type);
1612
1613 /* force protocols to update LINK STATE due to parameters change */
1614 if (if_is_operative (ifp))
1615 zebra_interface_parameters_update (ifp);
1616}
1617
1618DEFUN (link_params,
1619 link_params_cmd,
1620 "link-params",
1621 LINK_PARAMS_STR)
1622{
1623 vty->node = LINK_PARAMS_NODE;
1624
1625 return CMD_SUCCESS;
1626}
1627
Donald Sharp2c0adbf2016-11-18 15:42:41 -05001628DEFUN (exit_link_params,
1629 exit_link_params_cmd,
1630 "exit-link-params",
1631 "Exit from Link Params configuration mode\n")
1632{
1633 if (vty->node == LINK_PARAMS_NODE)
1634 vty->node = INTERFACE_NODE;
1635 return CMD_SUCCESS;
1636}
1637
Olivier Dugeon15773a82016-04-19 18:29:55 +02001638/* Specific Traffic Engineering parameters commands */
1639DEFUN (link_params_enable,
1640 link_params_enable_cmd,
1641 "enable",
1642 "Activate link parameters on this interface\n")
1643{
1644 struct interface *ifp = (struct interface *) vty->index;
1645
1646 /* This command could be issue at startup, when activate MPLS TE */
1647 /* on a new interface or after a ON / OFF / ON toggle */
1648 /* In all case, TE parameters are reset to their default factory */
1649 if (IS_ZEBRA_DEBUG_EVENT)
1650 zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
1651
1652 if (!if_link_params_get (ifp))
1653 {
1654 if (IS_ZEBRA_DEBUG_EVENT)
1655 zlog_debug ("Link-params: failed to init TE link parameters %s", ifp->name);
1656
1657 return CMD_WARNING;
1658 }
1659
1660 /* force protocols to update LINK STATE due to parameters change */
1661 if (if_is_operative (ifp))
1662 zebra_interface_parameters_update (ifp);
1663
1664 return CMD_SUCCESS;
1665}
1666
1667DEFUN (no_link_params_enable,
1668 no_link_params_enable_cmd,
1669 "no enable",
1670 NO_STR
1671 "Disable link parameters on this interface\n")
1672{
1673 struct interface *ifp = (struct interface *) vty->index;
1674
1675 zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
1676
1677 if_link_params_free (ifp);
1678
1679 /* force protocols to update LINK STATE due to parameters change */
1680 if (if_is_operative (ifp))
1681 zebra_interface_parameters_update (ifp);
1682
1683 return CMD_SUCCESS;
1684}
1685
1686/* STANDARD TE metrics */
1687DEFUN (link_params_metric,
1688 link_params_metric_cmd,
1689 "metric <0-4294967295>",
1690 "Link metric for MPLS-TE purpose\n"
1691 "Metric value in decimal\n")
1692{
1693 struct interface *ifp = (struct interface *) vty->index;
1694 struct if_link_params *iflp = if_link_params_get (ifp);
1695 u_int32_t metric;
1696
1697 VTY_GET_ULONG("metric", metric, argv[0]);
1698
1699 /* Update TE metric if needed */
1700 link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric);
1701
1702 return CMD_SUCCESS;
1703}
1704
1705DEFUN (no_link_params_metric,
1706 no_link_params_metric_cmd,
1707 "no metric",
1708 NO_STR
1709 "Disbale Link Metric on this interface\n")
1710{
1711 struct interface *ifp = (struct interface *) vty->index;
1712
1713 /* Unset TE Metric */
1714 link_param_cmd_unset(ifp, LP_TE);
1715
1716 return CMD_SUCCESS;
1717}
1718
1719DEFUN (link_params_maxbw,
1720 link_params_maxbw_cmd,
1721 "max-bw BANDWIDTH",
1722 "Maximum bandwidth that can be used\n"
1723 "Bytes/second (IEEE floating point format)\n")
1724{
1725 struct interface *ifp = (struct interface *) vty->index;
1726 struct if_link_params *iflp = if_link_params_get (ifp);
1727
1728 float bw;
1729
1730 if (sscanf (argv[0], "%g", &bw) != 1)
1731 {
1732 vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
1733 VTY_NEWLINE);
1734 return CMD_WARNING;
1735 }
1736
1737 /* Check that Maximum bandwidth is not lower than other bandwidth parameters */
1738 if ((bw <= iflp->max_rsv_bw)
1739 || (bw <= iflp->unrsv_bw[0])
1740 || (bw <= iflp->unrsv_bw[1])
1741 || (bw <= iflp->unrsv_bw[2])
1742 || (bw <= iflp->unrsv_bw[3])
1743 || (bw <= iflp->unrsv_bw[4])
1744 || (bw <= iflp->unrsv_bw[5])
1745 || (bw <= iflp->unrsv_bw[6])
1746 || (bw <= iflp->unrsv_bw[7])
1747 || (bw <= iflp->ava_bw)
1748 || (bw <= iflp->res_bw)
1749 || (bw <= iflp->use_bw))
1750 {
1751 vty_out (vty,
1752 "Maximum Bandwidth could not be lower than others bandwidth%s",
1753 VTY_NEWLINE);
1754 return CMD_WARNING;
1755 }
1756
1757 /* Update Maximum Bandwidth if needed */
1758 link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
1759
1760 return CMD_SUCCESS;
1761}
1762
1763DEFUN (link_params_max_rsv_bw,
1764 link_params_max_rsv_bw_cmd,
1765 "max-rsv-bw BANDWIDTH",
1766 "Maximum bandwidth that may be reserved\n"
1767 "Bytes/second (IEEE floating point format)\n")
1768{
1769 struct interface *ifp = (struct interface *) vty->index;
1770 struct if_link_params *iflp = if_link_params_get (ifp);
1771 float bw;
1772
1773 if (sscanf (argv[0], "%g", &bw) != 1)
1774 {
1775 vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
1776 VTY_NEWLINE);
1777 return CMD_WARNING;
1778 }
1779
1780 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1781 if (bw > iflp->max_bw)
1782 {
1783 vty_out (vty,
1784 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1785 iflp->max_bw, VTY_NEWLINE);
1786 return CMD_WARNING;
1787 }
1788
1789 /* Update Maximum Reservable Bandwidth if needed */
1790 link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
1791
1792 return CMD_SUCCESS;
1793}
1794
1795DEFUN (link_params_unrsv_bw,
1796 link_params_unrsv_bw_cmd,
1797 "unrsv-bw <0-7> BANDWIDTH",
1798 "Unreserved bandwidth at each priority level\n"
1799 "Priority\n"
1800 "Bytes/second (IEEE floating point format)\n")
1801{
1802 struct interface *ifp = (struct interface *) vty->index;
1803 struct if_link_params *iflp = if_link_params_get (ifp);
1804 int priority;
1805 float bw;
1806
1807 /* We don't have to consider about range check here. */
1808 if (sscanf (argv[0], "%d", &priority) != 1)
1809 {
1810 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1811 VTY_NEWLINE);
1812 return CMD_WARNING;
1813 }
1814
1815 if (sscanf (argv[1], "%g", &bw) != 1)
1816 {
1817 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1818 VTY_NEWLINE);
1819 return CMD_WARNING;
1820 }
1821
1822 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1823 if (bw > iflp->max_bw)
1824 {
1825 vty_out (vty,
1826 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1827 iflp->max_bw, VTY_NEWLINE);
1828 return CMD_WARNING;
1829 }
1830
1831 /* Update Unreserved Bandwidth if needed */
1832 link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
1833
1834 return CMD_SUCCESS;
1835}
1836
1837DEFUN (link_params_admin_grp,
1838 link_params_admin_grp_cmd,
1839 "admin-grp BITPATTERN",
1840 "Administrative group membership\n"
1841 "32-bit Hexadecimal value (e.g. 0xa1)\n")
1842{
1843 struct interface *ifp = (struct interface *) vty->index;
1844 struct if_link_params *iflp = if_link_params_get (ifp);
1845 unsigned long value;
1846
1847 if (sscanf (argv[0], "0x%lx", &value) != 1)
1848 {
1849 vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
1850 safe_strerror (errno), VTY_NEWLINE);
1851 return CMD_WARNING;
1852 }
1853
1854 /* Update Administrative Group if needed */
1855 link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
1856
1857 return CMD_SUCCESS;
1858}
1859
1860DEFUN (no_link_params_admin_grp,
1861 no_link_params_admin_grp_cmd,
1862 "no admin-grp",
1863 NO_STR
1864 "Disbale Administrative group membership on this interface\n")
1865{
1866 struct interface *ifp = (struct interface *) vty->index;
1867
1868 /* Unset Admin Group */
1869 link_param_cmd_unset(ifp, LP_ADM_GRP);
1870
1871 return CMD_SUCCESS;
1872}
1873
1874/* RFC5392 & RFC5316: INTER-AS */
1875DEFUN (link_params_inter_as,
1876 link_params_inter_as_cmd,
1877 "neighbor A.B.C.D as <1-4294967295>",
1878 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
1879 "Remote IP address in dot decimal A.B.C.D\n"
1880 "Remote AS number\n"
1881 "AS number in the range <1-4294967295>\n")
1882{
1883
1884 struct interface *ifp = (struct interface *) vty->index;
1885 struct if_link_params *iflp = if_link_params_get (ifp);
1886 struct in_addr addr;
1887 u_int32_t as;
1888
1889 if (!inet_aton (argv[0], &addr))
1890 {
1891 vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
1892 return CMD_WARNING;
1893 }
1894
1895 VTY_GET_ULONG("AS number", as, argv[1]);
1896
1897 /* Update Remote IP and Remote AS fields if needed */
1898 if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
1899 || iflp->rmt_as != as
1900 || iflp->rmt_ip.s_addr != addr.s_addr)
1901 {
1902
1903 iflp->rmt_as = as;
1904 iflp->rmt_ip.s_addr = addr.s_addr;
1905 SET_PARAM(iflp, LP_RMT_AS);
1906
1907 /* force protocols to update LINK STATE due to parameters change */
1908 if (if_is_operative (ifp))
1909 zebra_interface_parameters_update (ifp);
1910 }
1911 return CMD_SUCCESS;
1912}
1913
1914DEFUN (no_link_params_inter_as,
1915 no_link_params_inter_as_cmd,
1916 "no neighbor",
1917 NO_STR
1918 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
1919{
1920
1921 struct interface *ifp = (struct interface *) vty->index;
1922 struct if_link_params *iflp = if_link_params_get (ifp);
1923
1924 /* Reset Remote IP and AS neighbor */
1925 iflp->rmt_as = 0;
1926 iflp->rmt_ip.s_addr = 0;
1927 UNSET_PARAM(iflp, LP_RMT_AS);
1928
1929 /* force protocols to update LINK STATE due to parameters change */
1930 if (if_is_operative (ifp))
1931 zebra_interface_parameters_update (ifp);
1932
1933 return CMD_SUCCESS;
1934}
1935
1936/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
1937DEFUN (link_params_delay,
1938 link_params_delay_cmd,
1939 "delay <0-16777215>",
1940 "Unidirectional Average Link Delay\n"
1941 "Average delay in micro-second as decimal (0...16777215)\n")
1942{
1943
1944 struct interface *ifp = (struct interface *) vty->index;
1945 struct if_link_params *iflp = if_link_params_get (ifp);
1946 u_int32_t delay = 0, low = 0, high = 0;
1947 u_int8_t update = 0;
1948
1949 /* Get and Check new delay values */
1950 VTY_GET_ULONG("delay", delay, argv[0]);
1951 switch (argc)
1952 {
1953 case 1:
1954 /* Check new delay value against old Min and Max delays if set */
1955 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
1956 && (delay <= iflp->min_delay || delay >= iflp->max_delay))
1957 {
1958 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1959 iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
1960 return CMD_WARNING;
1961 }
1962 /* Update delay if value is not set or change */
1963 if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
1964 {
1965 iflp->av_delay = delay;
1966 SET_PARAM(iflp, LP_DELAY);
1967 update = 1;
1968 }
1969 /* Unset Min and Max delays if already set */
1970 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
1971 {
1972 iflp->min_delay = 0;
1973 iflp->max_delay = 0;
1974 UNSET_PARAM(iflp, LP_MM_DELAY);
1975 update = 1;
1976 }
1977 break;
1978 case 2:
1979 vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
1980 VTY_NEWLINE);
1981 return CMD_WARNING;
1982 break;
1983 case 3:
1984 VTY_GET_ULONG("minimum delay", low, argv[1]);
1985 VTY_GET_ULONG("maximum delay", high, argv[2]);
1986 /* Check new delays value coherency */
1987 if (delay <= low || delay >= high)
1988 {
1989 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
1990 low, high, VTY_NEWLINE);
1991 return CMD_WARNING;
1992 }
1993 /* Update Delays if needed */
1994 if (IS_PARAM_UNSET(iflp, LP_DELAY)
1995 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
1996 || iflp->av_delay != delay
1997 || iflp->min_delay != low
1998 || iflp->max_delay != high)
1999 {
2000 iflp->av_delay = delay;
2001 SET_PARAM(iflp, LP_DELAY);
2002 iflp->min_delay = low;
2003 iflp->max_delay = high;
2004 SET_PARAM(iflp, LP_MM_DELAY);
2005 update = 1;
2006 }
2007 break;
2008 default:
2009 return CMD_WARNING;
2010 break;
2011 }
2012
2013 /* force protocols to update LINK STATE due to parameters change */
2014 if (update == 1 && if_is_operative (ifp))
2015 zebra_interface_parameters_update (ifp);
2016
2017 return CMD_SUCCESS;
2018}
2019
2020ALIAS (link_params_delay,
2021 link_params_delay_mm_cmd,
2022 "delay <0-16777215> min <0-16777215> max <0-16777215>",
2023 "Unidirectional Average Link Delay (optionally Minimum and Maximum delays)\n"
2024 "Average delay in micro-second as decimal (0...16777215)\n"
2025 "Minimum delay\n"
2026 "Minimum delay in micro-second as decimal (0...16777215)\n"
2027 "Maximum delay\n"
2028 "Maximum delay in micro-second as decimal (0...16777215)\n")
2029
2030DEFUN (no_link_params_delay,
2031 no_link_params_delay_cmd,
2032 "no delay",
2033 NO_STR
2034 "Disbale Unidirectional Average, Min & Max Link Delay on this interface\n")
2035{
2036 struct interface *ifp = (struct interface *) vty->index;
2037 struct if_link_params *iflp = if_link_params_get (ifp);
2038
2039 /* Unset Delays */
2040 iflp->av_delay = 0;
2041 UNSET_PARAM(iflp, LP_DELAY);
2042 iflp->min_delay = 0;
2043 iflp->max_delay = 0;
2044 UNSET_PARAM(iflp, LP_MM_DELAY);
2045
2046 /* force protocols to update LINK STATE due to parameters change */
2047 if (if_is_operative (ifp))
2048 zebra_interface_parameters_update (ifp);
2049
2050 return CMD_SUCCESS;
2051}
2052
2053DEFUN (link_params_delay_var,
2054 link_params_delay_var_cmd,
2055 "delay-variation <0-16777215>",
2056 "Unidirectional Link Delay Variation\n"
2057 "delay variation in micro-second as decimal (0...16777215)\n")
2058{
2059 struct interface *ifp = (struct interface *) vty->index;
2060 struct if_link_params *iflp = if_link_params_get (ifp);
2061 u_int32_t value;
2062
2063 VTY_GET_ULONG("delay variation", value, argv[0]);
2064
2065 /* Update Delay Variation if needed */
2066 link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2067
2068 return CMD_SUCCESS;
2069}
2070
2071DEFUN (no_link_params_delay_var,
2072 no_link_params_delay_var_cmd,
2073 "no delay-variation",
2074 NO_STR
2075 "Disbale Unidirectional Delay Variation on this interface\n")
2076{
2077 struct interface *ifp = (struct interface *) vty->index;
2078
2079 /* Unset Delay Variation */
2080 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2081
2082 return CMD_SUCCESS;
2083}
2084
2085DEFUN (link_params_pkt_loss,
2086 link_params_pkt_loss_cmd,
2087 "packet-loss PERCENTAGE",
2088 "Unidirectional Link Packet Loss\n"
2089 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2090{
2091 struct interface *ifp = (struct interface *) vty->index;
2092 struct if_link_params *iflp = if_link_params_get (ifp);
2093 float fval;
2094
2095 if (sscanf (argv[0], "%g", &fval) != 1)
2096 {
2097 vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
2098 VTY_NEWLINE);
2099 return CMD_WARNING;
2100 }
2101
2102 if (fval > MAX_PKT_LOSS)
2103 fval = MAX_PKT_LOSS;
2104
2105 /* Update Packet Loss if needed */
2106 link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2107
2108 return CMD_SUCCESS;
2109}
2110
2111DEFUN (no_link_params_pkt_loss,
2112 no_link_params_pkt_loss_cmd,
2113 "no packet-loss",
2114 NO_STR
2115 "Disbale Unidirectional Link Packet Loss on this interface\n")
2116{
2117 struct interface *ifp = (struct interface *) vty->index;
2118
2119 /* Unset Packet Loss */
2120 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2121
2122 return CMD_SUCCESS;
2123}
2124
2125DEFUN (link_params_res_bw,
2126 link_params_res_bw_cmd,
2127 "res-bw BANDWIDTH",
2128 "Unidirectional Residual Bandwidth\n"
2129 "Bytes/second (IEEE floating point format)\n")
2130{
2131 struct interface *ifp = (struct interface *) vty->index;
2132 struct if_link_params *iflp = if_link_params_get (ifp);
2133 float bw;
2134
2135 if (sscanf (argv[0], "%g", &bw) != 1)
2136 {
2137 vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
2138 VTY_NEWLINE);
2139 return CMD_WARNING;
2140 }
2141
2142 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2143 if (bw > iflp->max_bw)
2144 {
2145 vty_out (vty,
2146 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2147 iflp->max_bw, VTY_NEWLINE);
2148 return CMD_WARNING;
2149 }
2150
2151 /* Update Residual Bandwidth if needed */
2152 link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
2153
2154 return CMD_SUCCESS;
2155}
2156
2157DEFUN (no_link_params_res_bw,
2158 no_link_params_res_bw_cmd,
2159 "no res-bw",
2160 NO_STR
2161 "Disbale Unidirectional Residual Bandwidth on this interface\n")
2162{
2163 struct interface *ifp = (struct interface *) vty->index;
2164
2165 /* Unset Residual Bandwidth */
2166 link_param_cmd_unset(ifp, LP_RES_BW);
2167
2168 return CMD_SUCCESS;
2169}
2170
2171DEFUN (link_params_ava_bw,
2172 link_params_ava_bw_cmd,
2173 "ava-bw BANDWIDTH",
2174 "Unidirectional Available Bandwidth\n"
2175 "Bytes/second (IEEE floating point format)\n")
2176{
2177 struct interface *ifp = (struct interface *) vty->index;
2178 struct if_link_params *iflp = if_link_params_get (ifp);
2179 float bw;
2180
2181 if (sscanf (argv[0], "%g", &bw) != 1)
2182 {
2183 vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
2184 VTY_NEWLINE);
2185 return CMD_WARNING;
2186 }
2187
2188 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2189 if (bw > iflp->max_bw)
2190 {
2191 vty_out (vty,
2192 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2193 iflp->max_bw, VTY_NEWLINE);
2194 return CMD_WARNING;
2195 }
2196
2197 /* Update Residual Bandwidth if needed */
2198 link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2199
2200 return CMD_SUCCESS;
2201}
2202
2203DEFUN (no_link_params_ava_bw,
2204 no_link_params_ava_bw_cmd,
2205 "no ava-bw",
2206 NO_STR
2207 "Disbale Unidirectional Available Bandwidth on this interface\n")
2208{
2209 struct interface *ifp = (struct interface *) vty->index;
2210
2211 /* Unset Available Bandwidth */
2212 link_param_cmd_unset(ifp, LP_AVA_BW);
2213
2214 return CMD_SUCCESS;
2215}
2216
2217DEFUN (link_params_use_bw,
2218 link_params_use_bw_cmd,
2219 "use-bw BANDWIDTH",
2220 "Unidirectional Utilised Bandwidth\n"
2221 "Bytes/second (IEEE floating point format)\n")
2222{
2223 struct interface *ifp = (struct interface *) vty->index;
2224 struct if_link_params *iflp = if_link_params_get (ifp);
2225 float bw;
2226
2227 if (sscanf (argv[0], "%g", &bw) != 1)
2228 {
2229 vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
2230 VTY_NEWLINE);
2231 return CMD_WARNING;
2232 }
2233
2234 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2235 if (bw > iflp->max_bw)
2236 {
2237 vty_out (vty,
2238 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2239 iflp->max_bw, VTY_NEWLINE);
2240 return CMD_WARNING;
2241 }
2242
2243 /* Update Utilized Bandwidth if needed */
2244 link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
2245
2246 return CMD_SUCCESS;
2247}
2248
2249DEFUN (no_link_params_use_bw,
2250 no_link_params_use_bw_cmd,
2251 "no use-bw",
2252 NO_STR
2253 "Disbale Unidirectional Utilised Bandwidth on this interface\n")
2254{
2255 struct interface *ifp = (struct interface *) vty->index;
2256
2257 /* Unset Utilised Bandwidth */
2258 link_param_cmd_unset(ifp, LP_USE_BW);
2259
2260 return CMD_SUCCESS;
2261}
2262
paula1ac18c2005-06-28 17:17:12 +00002263static int
hasso39db97e2004-10-12 20:50:58 +00002264ip_address_install (struct vty *vty, struct interface *ifp,
2265 const char *addr_str, const char *peer_str,
2266 const char *label)
paul718e3742002-12-13 20:15:29 +00002267{
Christian Frankebfac8dc2013-01-24 14:04:50 +00002268 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00002269 struct prefix_ipv4 cp;
2270 struct connected *ifc;
2271 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +00002272 int ret;
2273
Christian Frankebfac8dc2013-01-24 14:04:50 +00002274 if_data = ifp->info;
2275
paul718e3742002-12-13 20:15:29 +00002276 ret = str2prefix_ipv4 (addr_str, &cp);
2277 if (ret <= 0)
2278 {
2279 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2280 return CMD_WARNING;
2281 }
2282
paulca162182005-09-12 16:58:52 +00002283 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002284 if (! ifc)
2285 {
2286 ifc = connected_new ();
2287 ifc->ifp = ifp;
2288
2289 /* Address. */
2290 p = prefix_ipv4_new ();
2291 *p = cp;
2292 ifc->address = (struct prefix *) p;
2293
2294 /* Broadcast. */
hasso3fb9cd62004-10-19 19:44:43 +00002295 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
paul718e3742002-12-13 20:15:29 +00002296 {
2297 p = prefix_ipv4_new ();
2298 *p = cp;
hasso3fb9cd62004-10-19 19:44:43 +00002299 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
paul718e3742002-12-13 20:15:29 +00002300 ifc->destination = (struct prefix *) p;
2301 }
2302
paul718e3742002-12-13 20:15:29 +00002303 /* Label. */
2304 if (label)
paul0752ef02005-11-03 12:35:21 +00002305 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00002306
2307 /* Add to linked list. */
2308 listnode_add (ifp->connected, ifc);
2309 }
2310
2311 /* This address is configured from zebra. */
2312 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2313 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2314
2315 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002316 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00002317 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2318 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00002319 {
2320 /* Some system need to up the interface to set IP address. */
2321 if (! if_is_up (ifp))
2322 {
2323 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2324 if_refresh (ifp);
2325 }
2326
2327 ret = if_set_prefix (ifp, ifc);
2328 if (ret < 0)
2329 {
2330 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002331 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002332 return CMD_WARNING;
2333 }
2334
Christian Frankef7f740f2013-01-24 14:04:48 +00002335 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002336 /* The address will be advertised to zebra clients when the notification
2337 * from the kernel has been received.
2338 * It will also be added to the subnet chain list, then. */
paul718e3742002-12-13 20:15:29 +00002339 }
2340
2341 return CMD_SUCCESS;
2342}
2343
paula1ac18c2005-06-28 17:17:12 +00002344static int
hasso39db97e2004-10-12 20:50:58 +00002345ip_address_uninstall (struct vty *vty, struct interface *ifp,
2346 const char *addr_str, const char *peer_str,
2347 const char *label)
paul718e3742002-12-13 20:15:29 +00002348{
2349 struct prefix_ipv4 cp;
2350 struct connected *ifc;
2351 int ret;
2352
2353 /* Convert to prefix structure. */
2354 ret = str2prefix_ipv4 (addr_str, &cp);
2355 if (ret <= 0)
2356 {
2357 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2358 return CMD_WARNING;
2359 }
2360
2361 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00002362 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002363 if (! ifc)
2364 {
2365 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2366 return CMD_WARNING;
2367 }
2368
2369 /* This is not configured address. */
2370 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2371 return CMD_WARNING;
2372
Paul Jakma74ecdc92006-06-15 18:10:47 +00002373 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2374
paul718e3742002-12-13 20:15:29 +00002375 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002376 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00002377 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2378 {
2379 listnode_delete (ifp->connected, ifc);
2380 connected_free (ifc);
2381 return CMD_WARNING;
2382 }
2383
2384 /* This is real route. */
2385 ret = if_unset_prefix (ifp, ifc);
2386 if (ret < 0)
2387 {
2388 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002389 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002390 return CMD_WARNING;
2391 }
Christian Frankef7f740f2013-01-24 14:04:48 +00002392 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002393 /* we will receive a kernel notification about this route being removed.
2394 * this will trigger its removal from the connected list. */
paul718e3742002-12-13 20:15:29 +00002395 return CMD_SUCCESS;
2396}
2397
2398DEFUN (ip_address,
2399 ip_address_cmd,
2400 "ip address A.B.C.D/M",
2401 "Interface Internet Protocol config commands\n"
2402 "Set the IP address of an interface\n"
2403 "IP address (e.g. 10.0.0.1/8)\n")
2404{
hassoeef1fe12004-10-03 18:46:08 +00002405 return ip_address_install (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00002406}
2407
2408DEFUN (no_ip_address,
2409 no_ip_address_cmd,
2410 "no ip address A.B.C.D/M",
2411 NO_STR
2412 "Interface Internet Protocol config commands\n"
2413 "Set the IP address of an interface\n"
2414 "IP Address (e.g. 10.0.0.1/8)")
2415{
hassoeef1fe12004-10-03 18:46:08 +00002416 return ip_address_uninstall (vty, vty->index, argv[0], NULL, NULL);
paul718e3742002-12-13 20:15:29 +00002417}
2418
2419#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00002420DEFUN (ip_address_label,
2421 ip_address_label_cmd,
2422 "ip address A.B.C.D/M label LINE",
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_install (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00002430}
2431
2432DEFUN (no_ip_address_label,
2433 no_ip_address_label_cmd,
2434 "no ip address A.B.C.D/M label LINE",
2435 NO_STR
2436 "Interface Internet Protocol config commands\n"
2437 "Set the IP address of an interface\n"
2438 "IP address (e.g. 10.0.0.1/8)\n"
2439 "Label of this address\n"
2440 "Label\n")
2441{
hassoeef1fe12004-10-03 18:46:08 +00002442 return ip_address_uninstall (vty, vty->index, argv[0], NULL, argv[1]);
paul718e3742002-12-13 20:15:29 +00002443}
2444#endif /* HAVE_NETLINK */
2445
2446#ifdef HAVE_IPV6
paula1ac18c2005-06-28 17:17:12 +00002447static int
hasso39db97e2004-10-12 20:50:58 +00002448ipv6_address_install (struct vty *vty, struct interface *ifp,
2449 const char *addr_str, const char *peer_str,
2450 const char *label, int secondary)
paul718e3742002-12-13 20:15:29 +00002451{
Christian Frankebfac8dc2013-01-24 14:04:50 +00002452 struct zebra_if *if_data;
paul718e3742002-12-13 20:15:29 +00002453 struct prefix_ipv6 cp;
2454 struct connected *ifc;
2455 struct prefix_ipv6 *p;
2456 int ret;
2457
Christian Frankebfac8dc2013-01-24 14:04:50 +00002458 if_data = ifp->info;
2459
paul718e3742002-12-13 20:15:29 +00002460 ret = str2prefix_ipv6 (addr_str, &cp);
2461 if (ret <= 0)
2462 {
2463 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2464 return CMD_WARNING;
2465 }
2466
paulca162182005-09-12 16:58:52 +00002467 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002468 if (! ifc)
2469 {
2470 ifc = connected_new ();
2471 ifc->ifp = ifp;
2472
2473 /* Address. */
2474 p = prefix_ipv6_new ();
2475 *p = cp;
2476 ifc->address = (struct prefix *) p;
2477
2478 /* Secondary. */
2479 if (secondary)
2480 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
2481
2482 /* Label. */
2483 if (label)
paul0752ef02005-11-03 12:35:21 +00002484 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
paul718e3742002-12-13 20:15:29 +00002485
2486 /* Add to linked list. */
2487 listnode_add (ifp->connected, ifc);
2488 }
2489
2490 /* This address is configured from zebra. */
2491 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2492 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2493
2494 /* In case of this route need to install kernel. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002495 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
Christian Frankebfac8dc2013-01-24 14:04:50 +00002496 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2497 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
paul718e3742002-12-13 20:15:29 +00002498 {
2499 /* Some system need to up the interface to set IP address. */
2500 if (! if_is_up (ifp))
2501 {
2502 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2503 if_refresh (ifp);
2504 }
2505
2506 ret = if_prefix_add_ipv6 (ifp, ifc);
2507
2508 if (ret < 0)
2509 {
2510 vty_out (vty, "%% Can't set interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002511 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002512 return CMD_WARNING;
2513 }
2514
Christian Frankef7f740f2013-01-24 14:04:48 +00002515 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002516 /* The address will be advertised to zebra clients when the notification
2517 * from the kernel has been received. */
paul718e3742002-12-13 20:15:29 +00002518 }
2519
2520 return CMD_SUCCESS;
2521}
2522
paula1ac18c2005-06-28 17:17:12 +00002523static int
hasso39db97e2004-10-12 20:50:58 +00002524ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
2525 const char *addr_str, const char *peer_str,
2526 const char *label, int secondry)
paul718e3742002-12-13 20:15:29 +00002527{
2528 struct prefix_ipv6 cp;
2529 struct connected *ifc;
2530 int ret;
2531
2532 /* Convert to prefix structure. */
2533 ret = str2prefix_ipv6 (addr_str, &cp);
2534 if (ret <= 0)
2535 {
2536 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2537 return CMD_WARNING;
2538 }
2539
2540 /* Check current interface address. */
paulca162182005-09-12 16:58:52 +00002541 ifc = connected_check (ifp, (struct prefix *) &cp);
paul718e3742002-12-13 20:15:29 +00002542 if (! ifc)
2543 {
2544 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2545 return CMD_WARNING;
2546 }
2547
2548 /* This is not configured address. */
2549 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2550 return CMD_WARNING;
2551
Christian Franke676e1a02013-01-24 14:04:45 +00002552 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2553
paul718e3742002-12-13 20:15:29 +00002554 /* This is not real address or interface is not active. */
Christian Frankef7f740f2013-01-24 14:04:48 +00002555 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
paul718e3742002-12-13 20:15:29 +00002556 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2557 {
2558 listnode_delete (ifp->connected, ifc);
2559 connected_free (ifc);
2560 return CMD_WARNING;
2561 }
2562
2563 /* This is real route. */
2564 ret = if_prefix_delete_ipv6 (ifp, ifc);
2565 if (ret < 0)
2566 {
2567 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
ajs6099b3b2004-11-20 02:06:59 +00002568 safe_strerror(errno), VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002569 return CMD_WARNING;
2570 }
2571
Christian Frankef7f740f2013-01-24 14:04:48 +00002572 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
Christian Franke02b48052013-01-24 14:04:49 +00002573 /* This information will be propagated to the zclients when the
2574 * kernel notification is received. */
paul718e3742002-12-13 20:15:29 +00002575 return CMD_SUCCESS;
2576}
2577
2578DEFUN (ipv6_address,
2579 ipv6_address_cmd,
2580 "ipv6 address X:X::X:X/M",
hassoe23949c2004-03-11 15:54:02 +00002581 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00002582 "Set the IP address of an interface\n"
2583 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2584{
2585 return ipv6_address_install (vty, vty->index, argv[0], NULL, NULL, 0);
2586}
2587
2588DEFUN (no_ipv6_address,
2589 no_ipv6_address_cmd,
2590 "no ipv6 address X:X::X:X/M",
2591 NO_STR
hassoe23949c2004-03-11 15:54:02 +00002592 "Interface IPv6 config commands\n"
paul718e3742002-12-13 20:15:29 +00002593 "Set the IP address of an interface\n"
2594 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2595{
2596 return ipv6_address_uninstall (vty, vty->index, argv[0], NULL, NULL, 0);
2597}
2598#endif /* HAVE_IPV6 */
2599
paula1ac18c2005-06-28 17:17:12 +00002600static int
Olivier Dugeon15773a82016-04-19 18:29:55 +02002601link_params_config_write (struct vty *vty, struct interface *ifp)
2602{
Paul Jakma3676cb02016-07-29 13:39:37 +01002603 int i;
2604
Olivier Dugeon15773a82016-04-19 18:29:55 +02002605 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2606 return -1;
2607
2608 struct if_link_params *iflp = ifp->link_params;
2609
2610 vty_out (vty, " link-params%s", VTY_NEWLINE);
2611 vty_out(vty, " enable%s", VTY_NEWLINE);
2612 if (IS_PARAM_SET(iflp, LP_TE))
2613 vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
2614 if (IS_PARAM_SET(iflp, LP_MAX_BW))
2615 vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
2616 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2617 vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
2618 if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
2619 {
Paul Jakma3676cb02016-07-29 13:39:37 +01002620 for (i = 0; i < 8; i++)
Olivier Dugeon15773a82016-04-19 18:29:55 +02002621 vty_out(vty, " unrsv-bw %d %g%s",
2622 i, iflp->unrsv_bw[i], VTY_NEWLINE);
2623 }
2624 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2625 vty_out(vty, " admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE);
2626 if (IS_PARAM_SET(iflp, LP_DELAY))
2627 {
2628 vty_out(vty, " delay %u", iflp->av_delay);
2629 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2630 {
2631 vty_out(vty, " min %u", iflp->min_delay);
2632 vty_out(vty, " max %u", iflp->max_delay);
2633 }
2634 vty_out(vty, "%s", VTY_NEWLINE);
2635 }
2636 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2637 vty_out(vty, " delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
2638 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2639 vty_out(vty, " packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
2640 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2641 vty_out(vty, " ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
2642 if (IS_PARAM_SET(iflp, LP_RES_BW))
2643 vty_out(vty, " res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
2644 if (IS_PARAM_SET(iflp, LP_USE_BW))
2645 vty_out(vty, " use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
2646 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2647 vty_out(vty, " neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
2648 iflp->rmt_as, VTY_NEWLINE);
Donald Sharp2c0adbf2016-11-18 15:42:41 -05002649 vty_out(vty, " exit-link-params%s", VTY_NEWLINE);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002650 return 0;
2651}
2652
2653static int
paul718e3742002-12-13 20:15:29 +00002654if_config_write (struct vty *vty)
2655{
hasso52dc7ee2004-09-23 19:18:23 +00002656 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002657 struct interface *ifp;
Feng Lu471ea392015-05-22 11:40:00 +02002658 vrf_iter_t iter;
paul718e3742002-12-13 20:15:29 +00002659
Feng Lu471ea392015-05-22 11:40:00 +02002660 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
2661 for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
paul718e3742002-12-13 20:15:29 +00002662 {
2663 struct zebra_if *if_data;
hasso52dc7ee2004-09-23 19:18:23 +00002664 struct listnode *addrnode;
paul718e3742002-12-13 20:15:29 +00002665 struct connected *ifc;
2666 struct prefix *p;
2667
paul718e3742002-12-13 20:15:29 +00002668 if_data = ifp->info;
Feng Lu471ea392015-05-22 11:40:00 +02002669
2670 if (ifp->vrf_id == VRF_DEFAULT)
2671 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2672 else
2673 vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
2674 VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002675
Christian Frankebfac8dc2013-01-24 14:04:50 +00002676 if (if_data)
2677 {
2678 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2679 vty_out (vty, " shutdown%s", VTY_NEWLINE);
2680 }
2681
paul718e3742002-12-13 20:15:29 +00002682 if (ifp->desc)
2683 vty_out (vty, " description %s%s", ifp->desc,
2684 VTY_NEWLINE);
2685
2686 /* Assign bandwidth here to avoid unnecessary interface flap
2687 while processing config script */
2688 if (ifp->bandwidth != 0)
2689 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002690
2691 switch (if_data->linkdetect)
2692 {
2693 case IF_LINKDETECT_ON:
2694 vty_out(vty, " link-detect%s", VTY_NEWLINE);
2695 break;
2696 case IF_LINKDETECT_OFF:
2697 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2698 break;
2699 default: break;
2700 }
2701
paul1eb8ef22005-04-07 07:30:20 +00002702 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
paul718e3742002-12-13 20:15:29 +00002703 {
paul718e3742002-12-13 20:15:29 +00002704 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2705 {
Stephen Hemminger81cce012009-04-28 14:28:00 -07002706 char buf[INET6_ADDRSTRLEN];
paul718e3742002-12-13 20:15:29 +00002707 p = ifc->address;
Timo Teräsbe6335d2015-05-23 11:08:41 +03002708 vty_out (vty, " ip%s address %s",
paul718e3742002-12-13 20:15:29 +00002709 p->family == AF_INET ? "" : "v6",
Timo Teräsbe6335d2015-05-23 11:08:41 +03002710 prefix2str (p, buf, sizeof(buf)));
paul718e3742002-12-13 20:15:29 +00002711
paul718e3742002-12-13 20:15:29 +00002712 if (ifc->label)
2713 vty_out (vty, " label %s", ifc->label);
2714
2715 vty_out (vty, "%s", VTY_NEWLINE);
2716 }
2717 }
2718
2719 if (if_data)
2720 {
paul718e3742002-12-13 20:15:29 +00002721 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2722 vty_out (vty, " %smulticast%s",
2723 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2724 VTY_NEWLINE);
2725 }
2726
Donald Sharp64257732015-11-20 08:33:30 -05002727#if defined (HAVE_RTADV)
paul718e3742002-12-13 20:15:29 +00002728 rtadv_config_write (vty, ifp);
Donald Sharp64257732015-11-20 08:33:30 -05002729#endif /* HAVE_RTADV */
paul718e3742002-12-13 20:15:29 +00002730
hassoca776982004-06-12 14:33:05 +00002731#ifdef HAVE_IRDP
2732 irdp_config_write (vty, ifp);
2733#endif /* IRDP */
2734
Olivier Dugeon15773a82016-04-19 18:29:55 +02002735 link_params_config_write (vty, ifp);
2736
paul718e3742002-12-13 20:15:29 +00002737 vty_out (vty, "!%s", VTY_NEWLINE);
2738 }
2739 return 0;
2740}
2741
Olivier Dugeon15773a82016-04-19 18:29:55 +02002742
paul718e3742002-12-13 20:15:29 +00002743/* Allocate and initialize interface vector. */
2744void
paula1ac18c2005-06-28 17:17:12 +00002745zebra_if_init (void)
paul718e3742002-12-13 20:15:29 +00002746{
2747 /* Initialize interface and new hook. */
paul718e3742002-12-13 20:15:29 +00002748 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2749 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2750
2751 /* Install configuration write function. */
2752 install_node (&interface_node, if_config_write);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002753
2754 install_node (&zebra_if_defaults_node, config_write_zebra_if_defaults);
paul718e3742002-12-13 20:15:29 +00002755
Olivier Dugeon15773a82016-04-19 18:29:55 +02002756 install_node (&link_params_node, NULL);
2757
paul718e3742002-12-13 20:15:29 +00002758 install_element (VIEW_NODE, &show_interface_cmd);
Feng Lua2854772015-05-22 11:40:01 +02002759 install_element (VIEW_NODE, &show_interface_vrf_cmd);
2760 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
2761 install_element (VIEW_NODE, &show_interface_name_cmd);
2762 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2763 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
paul718e3742002-12-13 20:15:29 +00002764 install_element (CONFIG_NODE, &zebra_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02002765 install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
paulbfc13532003-05-24 06:40:04 +00002766 install_element (CONFIG_NODE, &no_interface_cmd);
Feng Lu471ea392015-05-22 11:40:00 +02002767 install_element (CONFIG_NODE, &no_interface_vrf_cmd);
Paul Jakma8f4269d2015-09-18 11:50:33 +01002768 install_element (CONFIG_NODE, &default_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00002769 install_default (INTERFACE_NODE);
2770 install_element (INTERFACE_NODE, &interface_desc_cmd);
2771 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2772 install_element (INTERFACE_NODE, &multicast_cmd);
2773 install_element (INTERFACE_NODE, &no_multicast_cmd);
paul2e3b2e42002-12-13 21:03:13 +00002774 install_element (INTERFACE_NODE, &linkdetect_cmd);
2775 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
paul718e3742002-12-13 20:15:29 +00002776 install_element (INTERFACE_NODE, &shutdown_if_cmd);
2777 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2778 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2779 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
2780 install_element (INTERFACE_NODE, &no_bandwidth_if_val_cmd);
2781 install_element (INTERFACE_NODE, &ip_address_cmd);
2782 install_element (INTERFACE_NODE, &no_ip_address_cmd);
2783#ifdef HAVE_IPV6
2784 install_element (INTERFACE_NODE, &ipv6_address_cmd);
2785 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
2786#endif /* HAVE_IPV6 */
paul718e3742002-12-13 20:15:29 +00002787#ifdef HAVE_NETLINK
paul718e3742002-12-13 20:15:29 +00002788 install_element (INTERFACE_NODE, &ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00002789 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
paul718e3742002-12-13 20:15:29 +00002790#endif /* HAVE_NETLINK */
Olivier Dugeon15773a82016-04-19 18:29:55 +02002791 install_element(INTERFACE_NODE, &link_params_cmd);
2792 install_default(LINK_PARAMS_NODE);
2793 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2794 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2795 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
2796 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2797 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2798 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2799 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002800 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002801 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2802 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2803 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002804 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002805 install_element(LINK_PARAMS_NODE, &link_params_delay_mm_cmd);
2806 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002807 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002808 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002809 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002810 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002811 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002812 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002813 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
Olivier Dugeon15773a82016-04-19 18:29:55 +02002814 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
David Lamparterf2f44ea2016-11-12 17:43:15 +09002815 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
Donald Sharp2c0adbf2016-11-18 15:42:41 -05002816 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
paul718e3742002-12-13 20:15:29 +00002817}