]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
Merge pull request #531 from qlyoung/fix-stack-ref
[mirror_frr.git] / zebra / interface.c
CommitLineData
718e3744 1/*
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"
4a1ab8e4 31#include "zebra_memory.h"
718e3744 32#include "ioctl.h"
33#include "connected.h"
34#include "log.h"
35#include "zclient.h"
cd2a8a42 36#include "vrf.h"
718e3744 37
718e3744 38#include "zebra/rtadv.h"
7c551956 39#include "zebra_ns.h"
c1c747a8 40#include "zebra_vrf.h"
7c551956 41#include "zebra/interface.h"
718e3744 42#include "zebra/rib.h"
6b8a5694 43#include "zebra/rt.h"
718e3744 44#include "zebra/zserv.h"
45#include "zebra/redistribute.h"
46#include "zebra/debug.h"
ca776988 47#include "zebra/irdp.h"
244c1cdc 48#include "zebra/zebra_ptm.h"
5c610faf 49#include "zebra/rt_netlink.h"
88177fe3 50#include "zebra/interface.h"
244c1cdc
DS
51
52#define ZEBRA_PTM_SUPPORT
718e3744 53
8da4e946 54#if defined (HAVE_RTADV)
b60668d0
CC
55/* Order is intentional. Matches RFC4191. This array is also used for
56 command matching, so only modify with care. */
57const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
8da4e946 58#endif /* HAVE_RTADV */
718e3744 59
c8e264b6 60static void if_down_del_nbr_connected (struct interface *ifp);
61
58ac32e2
RW
62static void
63zebra_if_node_destroy (route_table_delegate_t *delegate,
64 struct route_table *table, struct route_node *node)
65{
66 if (node->info)
67 list_delete (node->info);
68 route_node_destroy (delegate, table, node);
69}
70
71route_table_delegate_t zebra_if_table_delegate = {
72 .create_node = route_node_create,
73 .destroy_node = zebra_if_node_destroy
74};
75
718e3744 76/* Called when new interface is added. */
a1ac18c4 77static int
718e3744 78if_zebra_new_hook (struct interface *ifp)
79{
80 struct zebra_if *zebra_if;
81
393deb9b 82 zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
718e3744 83
84 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
bfac8dcd 85 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
986aa00f 86 zebra_ptm_if_init(zebra_if);
718e3744 87
c8ed14dd 88 ifp->ptm_enable = zebra_ptm_get_enable_state();
8da4e946 89#if defined (HAVE_RTADV)
718e3744 90 {
91 /* Set default router advertise values. */
92 struct rtadvconf *rtadv;
93
94 rtadv = &zebra_if->rtadv;
95
96 rtadv->AdvSendAdvertisements = 0;
97 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
98 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
99 rtadv->AdvIntervalTimer = 0;
100 rtadv->AdvManagedFlag = 0;
101 rtadv->AdvOtherConfigFlag = 0;
7cee1bb1 102 rtadv->AdvHomeAgentFlag = 0;
718e3744 103 rtadv->AdvLinkMTU = 0;
104 rtadv->AdvReachableTime = 0;
105 rtadv->AdvRetransTimer = 0;
106 rtadv->AdvCurHopLimit = 0;
d660f698 107 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
7cee1bb1 108 rtadv->HomeAgentPreference = 0;
d660f698 109 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
7cee1bb1 110 rtadv->AdvIntervalOption = 0;
b60668d0 111 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
718e3744 112
113 rtadv->AdvPrefixList = list_new ();
114 }
8da4e946 115#endif /* HAVE_RTADV */
718e3744 116
eef1fe11 117 /* Initialize installed address chains tree. */
58ac32e2 118 zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate);
eef1fe11 119
718e3744 120 ifp->info = zebra_if;
a3d21ef3
DS
121
122 zebra_vrf_static_route_interface_fixup (ifp);
718e3744 123 return 0;
124}
125
126/* Called when interface is deleted. */
a1ac18c4 127static int
718e3744 128if_zebra_delete_hook (struct interface *ifp)
129{
eef1fe11 130 struct zebra_if *zebra_if;
131
718e3744 132 if (ifp->info)
eef1fe11 133 {
134 zebra_if = ifp->info;
135
136 /* Free installed address chains tree. */
137 if (zebra_if->ipv4_subnets)
138 route_table_finish (zebra_if->ipv4_subnets);
3f6d6a5d
DS
139 #if defined (HAVE_RTADV)
140
141 struct rtadvconf *rtadv;
142
143 rtadv = &zebra_if->rtadv;
144 list_free (rtadv->AdvPrefixList);
145 #endif /* HAVE_RTADV */
eef1fe11 146
147 XFREE (MTYPE_TMP, zebra_if);
148 }
149
150 return 0;
151}
152
12f6fb97
DS
153/* Build the table key */
154static void
155if_build_key (u_int32_t ifindex, struct prefix *p)
156{
157 p->family = AF_INET;
158 p->prefixlen = IPV4_MAX_BITLEN;
159 p->u.prefix4.s_addr = ifindex;
160}
161
162/* Link an interface in a per NS interface tree */
163struct interface *
164if_link_per_ns (struct zebra_ns *ns, struct interface *ifp)
165{
166 struct prefix p;
167 struct route_node *rn;
168
169 if (ifp->ifindex == IFINDEX_INTERNAL)
170 return NULL;
171
172 if_build_key (ifp->ifindex, &p);
173 rn = route_node_get (ns->if_table, &p);
174 if (rn->info)
175 {
176 ifp = (struct interface *)rn->info;
177 route_unlock_node (rn); /* get */
178 return ifp;
179 }
180
181 rn->info = ifp;
182 ifp->node = rn;
183
184 return ifp;
185}
186
187/* Delete a VRF. This is called in vrf_terminate(). */
188void
189if_unlink_per_ns (struct interface *ifp)
190{
191 ifp->node->info = NULL;
192 route_unlock_node(ifp->node);
ef04b192 193 ifp->node = NULL;
12f6fb97
DS
194}
195
196/* Look up an interface by identifier within a NS */
197struct interface *
198if_lookup_by_index_per_ns (struct zebra_ns *ns, u_int32_t ifindex)
199{
200 struct prefix p;
201 struct route_node *rn;
202 struct interface *ifp = NULL;
203
204 if_build_key (ifindex, &p);
205 rn = route_node_lookup (ns->if_table, &p);
206 if (rn)
207 {
208 ifp = (struct interface *)rn->info;
209 route_unlock_node (rn); /* lookup */
210 }
211 return ifp;
212}
213
b8af3fbb
RW
214/* Look up an interface by name within a NS */
215struct interface *
216if_lookup_by_name_per_ns (struct zebra_ns *ns, const char *ifname)
217{
218 struct route_node *rn;
219 struct interface *ifp;
220
221 for (rn = route_top (ns->if_table); rn; rn = route_next (rn))
222 {
223 ifp = (struct interface *)rn->info;
224 if (ifp && strcmp (ifp->name, ifname) == 0)
225 return (ifp);
226 }
227
228 return NULL;
229}
230
a815b788 231const char *
232ifindex2ifname_per_ns (struct zebra_ns *zns, unsigned int ifindex)
233{
234 struct interface *ifp;
235
236 return ((ifp = if_lookup_by_index_per_ns (zns, ifindex)) != NULL) ?
237 ifp->name : "unknown";
238}
12f6fb97 239
eef1fe11 240/* Tie an interface address to its derived subnet list of addresses. */
241int
242if_subnet_add (struct interface *ifp, struct connected *ifc)
243{
244 struct route_node *rn;
245 struct zebra_if *zebra_if;
246 struct prefix cp;
247 struct list *addr_list;
248
249 assert (ifp && ifp->info && ifc);
250 zebra_if = ifp->info;
251
252 /* Get address derived subnet node and associated address list, while marking
253 address secondary attribute appropriately. */
254 cp = *ifc->address;
255 apply_mask (&cp);
256 rn = route_node_get (zebra_if->ipv4_subnets, &cp);
257
258 if ((addr_list = rn->info))
259 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
260 else
261 {
262 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
263 rn->info = addr_list = list_new ();
264 route_lock_node (rn);
265 }
266
267 /* Tie address at the tail of address list. */
268 listnode_add (addr_list, ifc);
269
270 /* Return list element count. */
271 return (addr_list->count);
272}
273
274/* Untie an interface address from its derived subnet list of addresses. */
275int
276if_subnet_delete (struct interface *ifp, struct connected *ifc)
277{
278 struct route_node *rn;
279 struct zebra_if *zebra_if;
280 struct list *addr_list;
281
282 assert (ifp && ifp->info && ifc);
283 zebra_if = ifp->info;
284
285 /* Get address derived subnet node. */
286 rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
287 if (! (rn && rn->info))
9db047fc
CF
288 {
289 zlog_warn("Trying to remove an address from an unknown subnet."
290 " (please report this bug)");
291 return -1;
292 }
eef1fe11 293 route_unlock_node (rn);
294
295 /* Untie address from subnet's address list. */
296 addr_list = rn->info;
9db047fc
CF
297
298 /* Deleting an address that is not registered is a bug.
299 * In any case, we shouldn't decrement the lock counter if the address
300 * is unknown. */
301 if (!listnode_lookup(addr_list, ifc))
302 {
303 zlog_warn("Trying to remove an address from a subnet where it is not"
304 " currently registered. (please report this bug)");
305 return -1;
306 }
307
eef1fe11 308 listnode_delete (addr_list, ifc);
309 route_unlock_node (rn);
310
311 /* Return list element count, if not empty. */
312 if (addr_list->count)
313 {
314 /* If deleted address is primary, mark subsequent one as such and distribute. */
315 if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
316 {
16f1b9ee 317 ifc = listgetdata ((struct listnode *)listhead (addr_list));
eef1fe11 318 zebra_interface_address_delete_update (ifp, ifc);
319 UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
02b4805f
CF
320 /* XXX: Linux kernel removes all the secondary addresses when the primary
321 * address is removed. We could try to work around that, though this is
322 * non-trivial. */
eef1fe11 323 zebra_interface_address_add_update (ifp, ifc);
324 }
325
326 return addr_list->count;
327 }
328
329 /* Otherwise, free list and route node. */
330 list_free (addr_list);
331 rn->info = NULL;
332 route_unlock_node (rn);
333
718e3744 334 return 0;
335}
336
5c78b3d0 337/* if_flags_mangle: A place for hacks that require mangling
338 * or tweaking the interface flags.
339 *
340 * ******************** Solaris flags hacks **************************
341 *
342 * Solaris IFF_UP flag reflects only the primary interface as the
343 * routing socket only sends IFINFO for the primary interface. Hence
344 * ~IFF_UP does not per se imply all the logical interfaces are also
345 * down - which we only know of as addresses. Instead we must determine
346 * whether the interface really is up or not according to how many
347 * addresses are still attached. (Solaris always sends RTM_DELADDR if
348 * an interface, logical or not, goes ~IFF_UP).
349 *
350 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
351 * are addresses left in struct connected, not just the actual underlying
352 * IFF_UP flag.
353 *
354 * We must hence remember the real state of IFF_UP, which we do in
355 * struct zebra_if.primary_state.
356 *
357 * Setting IFF_UP within zebra to administratively shutdown the
358 * interface will affect only the primary interface/address on Solaris.
359 ************************End Solaris flags hacks ***********************
360 */
f63f06da 361static void
5c78b3d0 362if_flags_mangle (struct interface *ifp, uint64_t *newflags)
363{
364#ifdef SUNOS_5
365 struct zebra_if *zif = ifp->info;
366
367 zif->primary_state = *newflags & (IFF_UP & 0xff);
368
369 if (CHECK_FLAG (zif->primary_state, IFF_UP)
370 || listcount(ifp->connected) > 0)
371 SET_FLAG (*newflags, IFF_UP);
372 else
373 UNSET_FLAG (*newflags, IFF_UP);
374#endif /* SUNOS_5 */
375}
376
377/* Update the flags field of the ifp with the new flag set provided.
378 * Take whatever actions are required for any changes in flags we care
379 * about.
380 *
381 * newflags should be the raw value, as obtained from the OS.
382 */
383void
384if_flags_update (struct interface *ifp, uint64_t newflags)
385{
386 if_flags_mangle (ifp, &newflags);
387
244c1cdc 388 if (if_is_no_ptm_operative (ifp))
5c78b3d0 389 {
390 /* operative -> inoperative? */
391 ifp->flags = newflags;
392 if (!if_is_operative (ifp))
393 if_down (ifp);
394 }
395 else
396 {
397 /* inoperative -> operative? */
398 ifp->flags = newflags;
399 if (if_is_operative (ifp))
400 if_up (ifp);
401 }
402}
403
718e3744 404/* Wake up configured address if it is not in current kernel
405 address. */
a1ac18c4 406static void
718e3744 407if_addr_wakeup (struct interface *ifp)
408{
1eb8ef25 409 struct listnode *node, *nnode;
718e3744 410 struct connected *ifc;
411 struct prefix *p;
412 int ret;
413
1eb8ef25 414 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc))
718e3744 415 {
718e3744 416 p = ifc->address;
417
418 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)
f7f740fe 419 && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED))
718e3744 420 {
421 /* Address check. */
422 if (p->family == AF_INET)
423 {
424 if (! if_is_up (ifp))
425 {
02b4805f
CF
426 /* Assume zebra is configured like following:
427 *
428 * interface gre0
429 * ip addr 192.0.2.1/24
430 * !
431 *
432 * As soon as zebra becomes first aware that gre0 exists in the
433 * kernel, it will set gre0 up and configure its addresses.
434 *
435 * (This may happen at startup when the interface already exists
436 * or during runtime when the interface is added to the kernel)
437 *
438 * XXX: IRDP code is calling here via if_add_update - this seems
439 * somewhat weird.
440 * XXX: RUNNING is not a settable flag on any system
441 * I (paulj) am aware of.
442 */
718e3744 443 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
444 if_refresh (ifp);
445 }
446
447 ret = if_set_prefix (ifp, ifc);
448 if (ret < 0)
449 {
450 zlog_warn ("Can't set interface's address: %s",
6099b3b5 451 safe_strerror(errno));
718e3744 452 continue;
453 }
eef1fe11 454
f7f740fe 455 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
456 /* The address will be advertised to zebra clients when the notification
457 * from the kernel has been received.
458 * It will also be added to the interface's subnet list then. */
718e3744 459 }
718e3744 460 if (p->family == AF_INET6)
461 {
462 if (! if_is_up (ifp))
463 {
02b4805f 464 /* See long comment above */
718e3744 465 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
466 if_refresh (ifp);
467 }
468
469 ret = if_prefix_add_ipv6 (ifp, ifc);
470 if (ret < 0)
471 {
472 zlog_warn ("Can't set interface's address: %s",
6099b3b5 473 safe_strerror(errno));
718e3744 474 continue;
475 }
718e3744 476
02b4805f
CF
477 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
478 /* The address will be advertised to zebra clients when the notification
479 * from the kernel has been received. */
718e3744 480 }
718e3744 481 }
482 }
483}
484
485/* Handle interface addition */
486void
487if_add_update (struct interface *ifp)
488{
48b33aaf 489 struct zebra_if *if_data;
490
fe18ee2d 491 if_link_per_ns(zebra_ns_lookup (NS_DEFAULT), ifp);
12f6fb97 492
48b33aaf 493 if_data = ifp->info;
06b420a4
MS
494 assert(if_data);
495
48b33aaf 496 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
497 if_set_flags (ifp, IFF_MULTICAST);
498 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
499 if_unset_flags (ifp, IFF_MULTICAST);
500
986aa00f 501 zebra_ptm_if_set_ptm_state(ifp, if_data);
502
718e3744 503 zebra_interface_add_update (ifp);
504
505 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
506 {
507 SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
508
bfac8dcd
CF
509 if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
510 {
511 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
512 zlog_debug ("interface %s vrf %u index %d is shutdown. "
513 "Won't wake it up.",
514 ifp->name, ifp->vrf_id, ifp->ifindex);
bfac8dcd
CF
515 return;
516 }
517
718e3744 518 if_addr_wakeup (ifp);
519
520 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
521 zlog_debug ("interface %s vrf %u index %d becomes active.",
522 ifp->name, ifp->vrf_id, ifp->ifindex);
718e3744 523 }
524 else
525 {
526 if (IS_ZEBRA_DEBUG_KERNEL)
3968dbf8
FL
527 zlog_debug ("interface %s vrf %u index %d is added.",
528 ifp->name, ifp->vrf_id, ifp->ifindex);
718e3744 529 }
530}
531
c8e264b6 532/* Install connected routes corresponding to an interface. */
533static void
534if_install_connected (struct interface *ifp)
718e3744 535{
c8e264b6 536 struct listnode *node;
537 struct listnode *next;
718e3744 538 struct connected *ifc;
539 struct prefix *p;
eef1fe11 540
c8e264b6 541 if (ifp->connected)
542 {
543 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
544 {
aa86a160
CF
545 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
546 zebra_interface_address_add_update (ifp, ifc);
718e3744 547
aa86a160 548 p = ifc->address;
c8e264b6 549 if (p->family == AF_INET)
550 connected_up_ipv4 (ifp, ifc);
551 else if (p->family == AF_INET6)
552 connected_up_ipv6 (ifp, ifc);
553 }
554 }
555}
556
557/* Uninstall connected routes corresponding to an interface. */
558static void
559if_uninstall_connected (struct interface *ifp)
560{
561 struct listnode *node;
562 struct listnode *next;
563 struct connected *ifc;
564 struct prefix *p;
565
566 if (ifp->connected)
718e3744 567 {
c8e264b6 568 for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
569 {
570 p = ifc->address;
99ffac18 571 zebra_interface_address_delete_update (ifp, ifc);
c8e264b6 572
573 if (p->family == AF_INET)
574 connected_down_ipv4 (ifp, ifc);
575 else if (p->family == AF_INET6)
576 connected_down_ipv6 (ifp, ifc);
577 }
718e3744 578 }
c8e264b6 579}
718e3744 580
c8e264b6 581/* Uninstall and delete connected routes corresponding to an interface. */
582/* TODO - Check why IPv4 handling here is different from install or if_down */
583static void
584if_delete_connected (struct interface *ifp)
585{
586 struct connected *ifc;
587 struct prefix *p;
588 struct route_node *rn;
589 struct zebra_if *zebra_if;
590
591 zebra_if = ifp->info;
718e3744 592
718e3744 593 if (ifp->connected)
594 {
d9a18f11
PJ
595 struct listnode *node;
596 struct listnode *last = NULL;
597
eef1fe11 598 while ((node = (last ? last->next : listhead (ifp->connected))))
718e3744 599 {
1eb8ef25 600 ifc = listgetdata (node);
718e3744 601 p = ifc->address;
eef1fe11 602
beb56336
PJ
603 if (p->family == AF_INET
604 && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
eef1fe11 605 {
d9a18f11
PJ
606 struct listnode *anode;
607 struct listnode *next;
608 struct listnode *first;
609 struct list *addr_list;
610
eef1fe11 611 route_unlock_node (rn);
612 addr_list = (struct list *) rn->info;
613
614 /* Remove addresses, secondaries first. */
615 first = listhead (addr_list);
d9a18f11 616 for (anode = first->next; anode || first; anode = next)
eef1fe11 617 {
d9a18f11 618 if (!anode)
eef1fe11 619 {
d9a18f11 620 anode = first;
eef1fe11 621 first = NULL;
622 }
d9a18f11 623 next = anode->next;
eef1fe11 624
d9a18f11 625 ifc = listgetdata (anode);
eef1fe11 626 connected_down_ipv4 (ifp, ifc);
627
02b4805f
CF
628 /* XXX: We have to send notifications here explicitly, because we destroy
629 * the ifc before receiving the notification about the address being deleted.
630 */
eef1fe11 631 zebra_interface_address_delete_update (ifp, ifc);
632
633 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 634 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 635
636 /* Remove from subnet chain. */
d9a18f11 637 list_delete_node (addr_list, anode);
eef1fe11 638 route_unlock_node (rn);
639
640 /* Remove from interface address list (unconditionally). */
d9a18f11
PJ
641 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
642 {
643 listnode_delete (ifp->connected, ifc);
644 connected_free (ifc);
645 }
646 else
647 last = node;
eef1fe11 648 }
649
650 /* Free chain list and respective route node. */
651 list_delete (addr_list);
652 rn->info = NULL;
653 route_unlock_node (rn);
654 }
718e3744 655 else if (p->family == AF_INET6)
eef1fe11 656 {
657 connected_down_ipv6 (ifp, ifc);
718e3744 658
eef1fe11 659 zebra_interface_address_delete_update (ifp, ifc);
718e3744 660
eef1fe11 661 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
f7f740fe 662 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
eef1fe11 663
664 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
665 last = node;
666 else
667 {
668 listnode_delete (ifp->connected, ifc);
669 connected_free (ifc);
670 }
718e3744 671 }
e26873fd
RHA
672 else
673 {
674 last = node;
675 }
718e3744 676 }
677 }
c8e264b6 678}
679
680/* Handle an interface delete event */
681void
682if_delete_update (struct interface *ifp)
683{
684 if (if_is_up(ifp))
685 {
686 zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
687 ifp->name, ifp->vrf_id, ifp->ifindex);
688 return;
689 }
690
691 /* Mark interface as inactive */
692 UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
693
694 if (IS_ZEBRA_DEBUG_KERNEL)
695 zlog_debug ("interface %s vrf %u index %d is now inactive.",
696 ifp->name, ifp->vrf_id, ifp->ifindex);
697
698 /* Delete connected routes from the kernel. */
699 if_delete_connected (ifp);
700
701 /* Send out notification on interface delete. */
718e3744 702 zebra_interface_delete_update (ifp);
d2fc8896 703
12f6fb97
DS
704 if_unlink_per_ns(ifp);
705
d2fc8896 706 /* Update ifindex after distributing the delete message. This is in
707 case any client needs to have the old value of ifindex available
708 while processing the deletion. Each client daemon is responsible
709 for setting ifindex to IFINDEX_INTERNAL after processing the
710 interface deletion message. */
711 ifp->ifindex = IFINDEX_INTERNAL;
ef015491 712 ifp->node = NULL;
718e3744 713}
714
c8e264b6 715/* VRF change for an interface */
716void
717if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
718{
719 vrf_id_t old_vrf_id;
720
721 old_vrf_id = ifp->vrf_id;
722
723 /* Uninstall connected routes. */
724 if_uninstall_connected (ifp);
725
726 /* Delete any IPv4 neighbors created to implement RFC 5549 */
727 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
728
729 /* Delete all neighbor addresses learnt through IPv6 RA */
730 if_down_del_nbr_connected (ifp);
731
c8e264b6 732 /* Send out notification on interface VRF change. */
733 /* This is to issue an UPDATE or a DELETE, as appropriate. */
734 zebra_interface_vrf_update_del (ifp, vrf_id);
735
736 /* update VRF */
f15dd9a4 737 if_update (ifp, ifp->name, strlen (ifp->name), vrf_id);
c8e264b6 738
739 /* Send out notification on interface VRF change. */
740 /* This is to issue an ADD, if needed. */
741 zebra_interface_vrf_update_add (ifp, old_vrf_id);
742
743 /* Install connected routes (in new VRF). */
744 if_install_connected (ifp);
745
c8e264b6 746 /* Due to connected route change, schedule RIB processing for both old
747 * and new VRF.
748 */
749 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
750 zlog_debug ("%u: IF %s VRF change, scheduling RIB processing",
751 ifp->vrf_id, ifp->name);
752 rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE);
753 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
fb148af4
DS
754
755 zebra_vrf_static_route_interface_fixup (ifp);
c8e264b6 756}
757
88177fe3 758static void
5c610faf
DS
759ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac)
760{
eb4b1830 761 mac[0] = address->s6_addr[8] ^ 0x02;
5c610faf
DS
762 mac[1] = address->s6_addr[9];
763 mac[2] = address->s6_addr[10];
764 mac[3] = address->s6_addr[13];
765 mac[4] = address->s6_addr[14];
766 mac[5] = address->s6_addr[15];
767}
768
769void
770if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
771 struct in6_addr *address,
772 int add)
773{
774 char buf[16] = "169.254.0.1";
775 struct in_addr ipv4_ll;
88177fe3 776 char mac[6];
5c610faf
DS
777
778 inet_pton (AF_INET, buf, &ipv4_ll);
779
88177fe3 780 ipv6_ll_address_to_mac(address, (u_char *)mac);
6b8a5694 781 kernel_neigh_update (add, ifp->ifindex, ipv4_ll.s_addr, mac, 6);
5c610faf
DS
782}
783
88177fe3 784static void
5c610faf
DS
785if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp)
786{
787 if (listhead(ifp->nbr_connected))
788 {
789 struct nbr_connected *nbr_connected;
790 struct listnode *node;
791
792 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
793 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
794 &nbr_connected->address->u.prefix6,
795 1);
796 }
797}
798
799void
800if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp)
801{
802 if (listhead(ifp->nbr_connected))
803 {
804 struct nbr_connected *nbr_connected;
805 struct listnode *node;
806
807 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
808 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
809 &nbr_connected->address->u.prefix6,
810 0);
811 }
812}
813
88177fe3 814static void
a197c47c
DS
815if_down_del_nbr_connected (struct interface *ifp)
816{
817 struct nbr_connected *nbr_connected;
818 struct listnode *node, *nnode;
819
820 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nbr_connected))
821 {
822 listnode_delete (ifp->nbr_connected, nbr_connected);
823 nbr_connected_free (nbr_connected);
824 }
825}
826
718e3744 827/* Interface is up. */
828void
829if_up (struct interface *ifp)
830{
55ce4d3a
CF
831 struct zebra_if *zif;
832
833 zif = ifp->info;
834 zif->up_count++;
835 quagga_timestamp (2, zif->up_last, sizeof (zif->up_last));
836
718e3744 837 /* Notify the protocol daemons. */
950bd436 838 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
244c1cdc
DS
839 zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
840 ifp->name);
841 return;
842 }
718e3744 843 zebra_interface_up_update (ifp);
844
5c610faf 845 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
244c1cdc 846
6c9678b4
DD
847 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
848 if (zif->rtadv.AdvSendAdvertisements &&
849 (zif->rtadv.MaxRtrAdvInterval >= 1000))
850 {
851 zif->rtadv.inFastRexmit = 1;
852 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
853 }
854
718e3744 855 /* Install connected routes to the kernel. */
c8e264b6 856 if_install_connected (ifp);
718e3744 857
41ec9222 858 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1c848137 859 zlog_debug ("%u: IF %s up, scheduling RIB processing",
860 ifp->vrf_id, ifp->name);
861 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
a3d21ef3
DS
862
863 zebra_vrf_static_route_interface_fixup (ifp);
718e3744 864}
865
866/* Interface goes down. We have to manage different behavior of based
867 OS. */
868void
869if_down (struct interface *ifp)
870{
55ce4d3a
CF
871 struct zebra_if *zif;
872
873 zif = ifp->info;
874 zif->down_count++;
875 quagga_timestamp (2, zif->down_last, sizeof (zif->down_last));
876
718e3744 877 /* Notify to the protocol daemons. */
878 zebra_interface_down_update (ifp);
879
c8e264b6 880 /* Uninstall connected routes from the kernel. */
881 if_uninstall_connected (ifp);
718e3744 882
41ec9222 883 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1c848137 884 zlog_debug ("%u: IF %s down, scheduling RIB processing",
885 ifp->vrf_id, ifp->name);
886 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
5c610faf
DS
887
888 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
a197c47c
DS
889
890 /* Delete all neighbor addresses learnt through IPv6 RA */
891 if_down_del_nbr_connected (ifp);
718e3744 892}
893
894void
895if_refresh (struct interface *ifp)
896{
5c78b3d0 897 if_get_flags (ifp);
718e3744 898}
899
d5a5c8f0 900
718e3744 901/* Output prefix string to vty. */
a1ac18c4 902static int
718e3744 903prefix_vty_out (struct vty *vty, struct prefix *p)
904{
905 char str[INET6_ADDRSTRLEN];
906
907 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
908 vty_out (vty, "%s", str);
909 return strlen (str);
910}
911
912/* Dump if address information to vty. */
a1ac18c4 913static void
718e3744 914connected_dump_vty (struct vty *vty, struct connected *connected)
915{
916 struct prefix *p;
718e3744 917
918 /* Print interface address. */
919 p = connected->address;
920 vty_out (vty, " %s ", prefix_family_str (p));
921 prefix_vty_out (vty, p);
922 vty_out (vty, "/%d", p->prefixlen);
923
924 /* If there is destination address, print it. */
e4529636 925 if (connected->destination)
718e3744 926 {
e4529636
AS
927 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
928 prefix_vty_out (vty, connected->destination);
718e3744 929 }
930
931 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
932 vty_out (vty, " secondary");
933
525c1839
DS
934 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED))
935 vty_out (vty, " unnumbered");
936
718e3744 937 if (connected->label)
938 vty_out (vty, " %s", connected->label);
939
940 vty_out (vty, "%s", VTY_NEWLINE);
941}
942
a80beece
DS
943/* Dump interface neighbor address information to vty. */
944static void
945nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected)
946{
947 struct prefix *p;
948
949 /* Print interface address. */
950 p = connected->address;
951 vty_out (vty, " %s ", prefix_family_str (p));
952 prefix_vty_out (vty, p);
953 vty_out (vty, "/%d", p->prefixlen);
954
955 vty_out (vty, "%s", VTY_NEWLINE);
956}
957
8da4e946 958#if defined (HAVE_RTADV)
718e3744 959/* Dump interface ND information to vty. */
a1ac18c4 960static void
718e3744 961nd_dump_vty (struct vty *vty, struct interface *ifp)
962{
963 struct zebra_if *zif;
964 struct rtadvconf *rtadv;
7cee1bb1 965 int interval;
718e3744 966
967 zif = (struct zebra_if *) ifp->info;
968 rtadv = &zif->rtadv;
969
970 if (rtadv->AdvSendAdvertisements)
971 {
972 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
973 rtadv->AdvReachableTime, VTY_NEWLINE);
974 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
975 rtadv->AdvRetransTimer, VTY_NEWLINE);
795b5abf
QY
976 vty_out (vty, " ND router advertisements sent: %d rcvd: %d%s",
977 zif->ra_sent, zif->ra_rcvd, VTY_NEWLINE);
7cee1bb1 978 interval = rtadv->MaxRtrAdvInterval;
979 if (interval % 1000)
980 vty_out (vty, " ND router advertisements are sent every "
981 "%d milliseconds%s", interval,
982 VTY_NEWLINE);
983 else
984 vty_out (vty, " ND router advertisements are sent every "
985 "%d seconds%s", interval / 1000,
986 VTY_NEWLINE);
d660f698
DO
987 if (rtadv->AdvDefaultLifetime != -1)
988 vty_out (vty, " ND router advertisements live for %d seconds%s",
989 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
990 else
991 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
992 VTY_NEWLINE);
b60668d0
CC
993 vty_out (vty, " ND router advertisement default router preference is "
994 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
995 VTY_NEWLINE);
718e3744 996 if (rtadv->AdvManagedFlag)
997 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
998 VTY_NEWLINE);
999 else
1000 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
1001 VTY_NEWLINE);
7cee1bb1 1002 if (rtadv->AdvHomeAgentFlag)
d660f698 1003 {
7cee1bb1 1004 vty_out (vty, " ND router advertisements with "
1005 "Home Agent flag bit set.%s",
1006 VTY_NEWLINE);
d660f698
DO
1007 if (rtadv->HomeAgentLifetime != -1)
1008 vty_out (vty, " Home Agent lifetime is %u seconds%s",
1009 rtadv->HomeAgentLifetime, VTY_NEWLINE);
1010 else
1011 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
1012 VTY_NEWLINE);
1013 vty_out (vty, " Home Agent preference is %u%s",
1014 rtadv->HomeAgentPreference, VTY_NEWLINE);
1015 }
7cee1bb1 1016 if (rtadv->AdvIntervalOption)
1017 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
1018 VTY_NEWLINE);
718e3744 1019 }
1020}
8da4e946 1021#endif /* HAVE_RTADV */
718e3744 1022
1023/* Interface's information print out to vty interface. */
a1ac18c4 1024static void
718e3744 1025if_dump_vty (struct vty *vty, struct interface *ifp)
1026{
718e3744 1027 struct connected *connected;
a80beece 1028 struct nbr_connected *nbr_connected;
52dc7ee6 1029 struct listnode *node;
eef1fe11 1030 struct route_node *rn;
1031 struct zebra_if *zebra_if;
e6a59b35 1032 struct vrf *vrf;
eef1fe11 1033
1034 zebra_if = ifp->info;
718e3744 1035
2e3b2e47 1036 vty_out (vty, "Interface %s is ", ifp->name);
1037 if (if_is_up(ifp)) {
1038 vty_out (vty, "up, line protocol ");
1039
1040 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1041 if (if_is_running(ifp))
1042 vty_out (vty, "is up%s", VTY_NEWLINE);
1043 else
1044 vty_out (vty, "is down%s", VTY_NEWLINE);
1045 } else {
1046 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
1047 }
1048 } else {
1049 vty_out (vty, "down%s", VTY_NEWLINE);
1050 }
1051
55ce4d3a
CF
1052 vty_out (vty, " Link ups: %5u last: %s%s", zebra_if->up_count,
1053 zebra_if->up_last[0] ? zebra_if->up_last : "(never)", VTY_NEWLINE);
1054 vty_out (vty, " Link downs: %5u last: %s%s", zebra_if->down_count,
1055 zebra_if->down_last[0] ? zebra_if->down_last : "(never)", VTY_NEWLINE);
1056
950bd436 1057 zebra_ptm_show_status(vty, ifp);
244c1cdc 1058
5f3d1bdf 1059 vrf = vrf_lookup_by_id (ifp->vrf_id);
e6a59b35 1060 vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
3968dbf8 1061
718e3744 1062 if (ifp->desc)
1063 vty_out (vty, " Description: %s%s", ifp->desc,
1064 VTY_NEWLINE);
d2fc8896 1065 if (ifp->ifindex == IFINDEX_INTERNAL)
718e3744 1066 {
d2fc8896 1067 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
718e3744 1068 return;
1069 }
1070 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1071 {
1072 vty_out(vty, " index %d inactive interface%s",
1073 ifp->ifindex,
1074 VTY_NEWLINE);
1075 return;
1076 }
1077
97d2cd8d 1078 vty_out (vty, " index %d metric %d mtu %d speed %u ",
6f4c7f74 1079 ifp->ifindex, ifp->metric, ifp->mtu, ifp->speed);
44145db3 1080 if (ifp->mtu6 != ifp->mtu)
1081 vty_out (vty, "mtu6 %d ", ifp->mtu6);
630c97ce
PJ
1082 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
1083 if_flag_dump (ifp->flags), VTY_NEWLINE);
3a570c8b 1084
718e3744 1085 /* Hardware address. */
8ccc7e80 1086 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
718e3744 1087 if (ifp->hw_addr_len != 0)
1088 {
1089 int i;
1090
1091 vty_out (vty, " HWaddr: ");
1092 for (i = 0; i < ifp->hw_addr_len; i++)
1093 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
1094 vty_out (vty, "%s", VTY_NEWLINE);
1095 }
718e3744 1096
70bd3c43 1097 /* Bandwidth in Mbps */
718e3744 1098 if (ifp->bandwidth != 0)
1099 {
70bd3c43 1100 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
718e3744 1101 vty_out(vty, "%s", VTY_NEWLINE);
1102 }
1103
eef1fe11 1104 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
718e3744 1105 {
eef1fe11 1106 if (! rn->info)
1107 continue;
16f1b9ee 1108
1eb8ef25 1109 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
1110 connected_dump_vty (vty, connected);
718e3744 1111 }
1112
1eb8ef25 1113 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
39db97e4 1114 {
39db97e4 1115 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
1116 (connected->address->family == AF_INET6))
1117 connected_dump_vty (vty, connected);
1118 }
1119
16f1b9ee
OD
1120 if (HAS_LINK_PARAMS(ifp))
1121 {
1122 int i;
1123 struct if_link_params *iflp = ifp->link_params;
1124 vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
daf0a4d2 1125 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
16f1b9ee
OD
1126 vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
1127 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1128 vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
1129 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1130 vty_out(vty, " Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
1131 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1132 vty_out(vty, " Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
1133 for (i = 0; i < MAX_CLASS_TYPE; i+=2)
1134 vty_out(vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
1135 i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
1136 }
1137
1138 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1139 vty_out(vty, " Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
1140 if (IS_PARAM_SET(iflp, LP_DELAY))
1141 {
1142 vty_out(vty, " Link Delay Average: %u (micro-sec.)", iflp->av_delay);
1143 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
1144 {
1145 vty_out(vty, " Min: %u (micro-sec.)", iflp->min_delay);
1146 vty_out(vty, " Max: %u (micro-sec.)", iflp->max_delay);
1147 }
1148 vty_out(vty, "%s", VTY_NEWLINE);
1149 }
1150 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1151 vty_out(vty, " Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
1152 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1153 vty_out(vty, " Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
1154 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1155 vty_out(vty, " Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
1156 if (IS_PARAM_SET(iflp, LP_RES_BW))
1157 vty_out(vty, " Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
1158 if (IS_PARAM_SET(iflp, LP_USE_BW))
1159 vty_out(vty, " Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
1160 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1161 vty_out(vty, " Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
1162 }
1163
1164 #ifdef RTADV
1165 nd_dump_vty (vty, ifp);
1166 #endif /* RTADV */
8da4e946 1167#if defined (HAVE_RTADV)
718e3744 1168 nd_dump_vty (vty, ifp);
8da4e946 1169#endif /* HAVE_RTADV */
a80beece
DS
1170 if (listhead(ifp->nbr_connected))
1171 vty_out (vty, " Neighbor address(s):%s", VTY_NEWLINE);
1172 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
1173 nbr_connected_dump_vty (vty, nbr_connected);
718e3744 1174
1175#ifdef HAVE_PROC_NET_DEV
1176 /* Statistics print out using proc file system. */
6f2c27af 1177 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
1178 "%lu dropped%s",
1179 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1180 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
718e3744 1181
6f2c27af 1182 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
3452d475 1183 " %lu CRC, %lu frame%s",
718e3744 1184 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1185 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
6f2c27af 1186 ifp->stats.rx_frame_errors, VTY_NEWLINE);
1187
1188 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
718e3744 1189 ifp->stats.rx_missed_errors, VTY_NEWLINE);
1190
6f2c27af 1191 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
718e3744 1192 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1193 ifp->stats.tx_dropped, VTY_NEWLINE);
1194
6f2c27af 1195 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
1196 " %lu fifo, %lu heartbeat%s",
718e3744 1197 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1198 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
6f2c27af 1199 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
718e3744 1200
6f2c27af 1201 vty_out (vty, " %lu window, %lu collisions%s",
1202 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
718e3744 1203#endif /* HAVE_PROC_NET_DEV */
1204
1205#ifdef HAVE_NET_RT_IFLIST
1206#if defined (__bsdi__) || defined (__NetBSD__)
1207 /* Statistics print out using sysctl (). */
24b46333
DL
1208 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
1209 " multicast packets %llu%s",
1210 (unsigned long long)ifp->stats.ifi_ipackets,
1211 (unsigned long long)ifp->stats.ifi_ibytes,
1212 (unsigned long long)ifp->stats.ifi_iqdrops,
1213 (unsigned long long)ifp->stats.ifi_imcasts,
1214 VTY_NEWLINE);
1215
1216 vty_out (vty, " input errors %llu%s",
1217 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
1218
1219 vty_out (vty, " output packets %llu, bytes %llu,"
1220 " multicast packets %llu%s",
1221 (unsigned long long)ifp->stats.ifi_opackets,
1222 (unsigned long long)ifp->stats.ifi_obytes,
1223 (unsigned long long)ifp->stats.ifi_omcasts,
1224 VTY_NEWLINE);
1225
1226 vty_out (vty, " output errors %llu%s",
1227 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
1228
1229 vty_out (vty, " collisions %llu%s",
1230 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
718e3744 1231#else
1232 /* Statistics print out using sysctl (). */
1233 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
1234 " multicast packets %lu%s",
1235 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1236 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1237 VTY_NEWLINE);
1238
1239 vty_out (vty, " input errors %lu%s",
1240 ifp->stats.ifi_ierrors, VTY_NEWLINE);
1241
1242 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
1243 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1244 ifp->stats.ifi_omcasts, VTY_NEWLINE);
1245
1246 vty_out (vty, " output errors %lu%s",
1247 ifp->stats.ifi_oerrors, VTY_NEWLINE);
1248
1249 vty_out (vty, " collisions %lu%s",
1250 ifp->stats.ifi_collisions, VTY_NEWLINE);
1251#endif /* __bsdi__ || __NetBSD__ */
1252#endif /* HAVE_NET_RT_IFLIST */
1253}
1254
78860b9f
DS
1255static void
1256interface_update_stats (void)
1257{
1258#ifdef HAVE_PROC_NET_DEV
1259 /* If system has interface statistics via proc file system, update
1260 statistics. */
1261 ifstat_update_proc ();
1262#endif /* HAVE_PROC_NET_DEV */
1263#ifdef HAVE_NET_RT_IFLIST
1264 ifstat_update_sysctl ();
1265#endif /* HAVE_NET_RT_IFLIST */
1266}
1267
718e3744 1268struct cmd_node interface_node =
1269{
1270 INTERFACE_NODE,
1271 "%s(config-if)# ",
1272 1
1273};
1274
8b87bdf4 1275/* Show all interfaces to vty. */
8b3f0677
DW
1276DEFUN (show_interface,
1277 show_interface_cmd,
b62ecea5 1278 "show interface [vrf NAME]",
8b87bdf4 1279 SHOW_STR
b62ecea5
QY
1280 "Interface status and configuration\n"
1281 VRF_CMD_HELP_STR)
8b87bdf4
FL
1282{
1283 struct listnode *node;
1284 struct interface *ifp;
1285 vrf_id_t vrf_id = VRF_DEFAULT;
1286
78860b9f 1287 interface_update_stats ();
8b87bdf4 1288
b62ecea5
QY
1289 if (argc > 2)
1290 VRF_GET_ID (vrf_id, argv[3]->arg);
8b87bdf4
FL
1291
1292 /* All interface print. */
1293 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1294 if_dump_vty (vty, ifp);
1295
1296 return CMD_SUCCESS;
1297}
1298
8b87bdf4
FL
1299
1300/* Show all interfaces to vty. */
8b3f0677
DW
1301DEFUN (show_interface_vrf_all,
1302 show_interface_vrf_all_cmd,
9ccf14f7 1303 "show interface vrf all",
8b87bdf4
FL
1304 SHOW_STR
1305 "Interface status and configuration\n"
1306 VRF_ALL_CMD_HELP_STR)
718e3744 1307{
1a1a7065 1308 struct vrf *vrf;
52dc7ee6 1309 struct listnode *node;
718e3744 1310 struct interface *ifp;
8b87bdf4 1311
78860b9f 1312 interface_update_stats ();
718e3744 1313
8b87bdf4 1314 /* All interface print. */
a62c4901 1315 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 1316 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
8b87bdf4
FL
1317 if_dump_vty (vty, ifp);
1318
1319 return CMD_SUCCESS;
1320}
1321
1322/* Show specified interface to vty. */
1721646e
DS
1323
1324DEFUN (show_interface_name_vrf,
1325 show_interface_name_vrf_cmd,
9ccf14f7 1326 "show interface IFNAME vrf NAME",
8b87bdf4
FL
1327 SHOW_STR
1328 "Interface status and configuration\n"
1721646e
DS
1329 "Interface name\n"
1330 VRF_CMD_HELP_STR)
8b87bdf4 1331{
7c022376
DW
1332 int idx_ifname = 2;
1333 int idx_name = 4;
8b87bdf4
FL
1334 struct interface *ifp;
1335 vrf_id_t vrf_id = VRF_DEFAULT;
1336
78860b9f 1337 interface_update_stats ();
8b87bdf4 1338
00d7d2d3 1339 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
8b87bdf4 1340
718e3744 1341 /* Specified interface print. */
1306c09a 1342 ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf_id);
8b87bdf4 1343 if (ifp == NULL)
718e3744 1344 {
7c022376 1345 vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg,
8b87bdf4
FL
1346 VTY_NEWLINE);
1347 return CMD_WARNING;
718e3744 1348 }
8b87bdf4 1349 if_dump_vty (vty, ifp);
718e3744 1350
1351 return CMD_SUCCESS;
1352}
1353
8b87bdf4 1354/* Show specified interface to vty. */
8b3f0677
DW
1355DEFUN (show_interface_name_vrf_all,
1356 show_interface_name_vrf_all_cmd,
b62ecea5 1357 "show interface IFNAME [vrf all]",
8b87bdf4
FL
1358 SHOW_STR
1359 "Interface status and configuration\n"
1721646e 1360 "Interface name\n"
8b87bdf4
FL
1361 VRF_ALL_CMD_HELP_STR)
1362{
7c022376 1363 int idx_ifname = 2;
1a1a7065 1364 struct vrf *vrf;
8b87bdf4 1365 struct interface *ifp;
8b87bdf4
FL
1366 int found = 0;
1367
78860b9f 1368 interface_update_stats ();
8b87bdf4
FL
1369
1370 /* All interface print. */
a62c4901 1371 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8b87bdf4
FL
1372 {
1373 /* Specified interface print. */
1306c09a 1374 ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf->vrf_id);
8b87bdf4
FL
1375 if (ifp)
1376 {
1377 if_dump_vty (vty, ifp);
1378 found++;
1379 }
1380 }
1381
1382 if (!found)
1383 {
7c022376 1384 vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg, VTY_NEWLINE);
8b87bdf4
FL
1385 return CMD_WARNING;
1386 }
1387
1388 return CMD_SUCCESS;
1389}
1390
1721646e 1391
8b87bdf4
FL
1392static void
1393if_show_description (struct vty *vty, vrf_id_t vrf_id)
ed9bb6d5 1394{
1395 struct listnode *node;
1396 struct interface *ifp;
1397
1398 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
8b87bdf4 1399 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
ed9bb6d5 1400 {
1401 int len;
ed9bb6d5 1402
1403 len = vty_out (vty, "%s", ifp->name);
1404 vty_out (vty, "%*s", (16 - len), " ");
1405
1406 if (if_is_up(ifp))
1407 {
1408 vty_out (vty, "up ");
1409 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1410 {
1411 if (if_is_running(ifp))
1412 vty_out (vty, "up ");
1413 else
1414 vty_out (vty, "down ");
1415 }
1416 else
1417 {
1418 vty_out (vty, "unknown ");
1419 }
1420 }
1421 else
1422 {
1423 vty_out (vty, "down down ");
1424 }
1425
1426 if (ifp->desc)
1427 vty_out (vty, "%s", ifp->desc);
1428 vty_out (vty, "%s", VTY_NEWLINE);
1429 }
8b87bdf4
FL
1430}
1431
1432DEFUN (show_interface_desc,
1433 show_interface_desc_cmd,
b62ecea5 1434 "show interface description [vrf NAME]",
8b87bdf4
FL
1435 SHOW_STR
1436 "Interface status and configuration\n"
b62ecea5
QY
1437 "Interface description\n"
1438 VRF_CMD_HELP_STR)
8b87bdf4
FL
1439{
1440 vrf_id_t vrf_id = VRF_DEFAULT;
1441
b62ecea5
QY
1442 if (argc > 3)
1443 VRF_GET_ID (vrf_id, argv[4]->arg);
8b87bdf4
FL
1444
1445 if_show_description (vty, vrf_id);
1446
1447 return CMD_SUCCESS;
1448}
1449
8b87bdf4
FL
1450
1451DEFUN (show_interface_desc_vrf_all,
1452 show_interface_desc_vrf_all_cmd,
9ccf14f7 1453 "show interface description vrf all",
8b87bdf4
FL
1454 SHOW_STR
1455 "Interface status and configuration\n"
1456 "Interface description\n"
1457 VRF_ALL_CMD_HELP_STR)
1458{
1a1a7065 1459 struct vrf *vrf;
8b87bdf4 1460
a62c4901 1461 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 1462 if (!list_isempty (vrf->iflist))
8b87bdf4 1463 {
1a1a7065
RW
1464 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id,
1465 VTY_NEWLINE, VTY_NEWLINE);
1466 if_show_description (vty, vrf->vrf_id);
8b87bdf4
FL
1467 }
1468
ed9bb6d5 1469 return CMD_SUCCESS;
1470}
1471
718e3744 1472DEFUN (multicast,
1473 multicast_cmd,
1474 "multicast",
1475 "Set multicast flag to interface\n")
1476{
3ddccf18 1477 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1478 int ret;
718e3744 1479 struct zebra_if *if_data;
1480
48b33aaf 1481 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1482 {
48b33aaf 1483 ret = if_set_flags (ifp, IFF_MULTICAST);
1484 if (ret < 0)
1485 {
1486 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1487 return CMD_WARNING;
1488 }
1489 if_refresh (ifp);
718e3744 1490 }
718e3744 1491 if_data = ifp->info;
1492 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1493
718e3744 1494 return CMD_SUCCESS;
1495}
1496
1497DEFUN (no_multicast,
1498 no_multicast_cmd,
1499 "no multicast",
1500 NO_STR
1501 "Unset multicast flag to interface\n")
1502{
3ddccf18 1503 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1504 int ret;
718e3744 1505 struct zebra_if *if_data;
1506
48b33aaf 1507 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
718e3744 1508 {
48b33aaf 1509 ret = if_unset_flags (ifp, IFF_MULTICAST);
1510 if (ret < 0)
1511 {
1512 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1513 return CMD_WARNING;
1514 }
1515 if_refresh (ifp);
718e3744 1516 }
718e3744 1517 if_data = ifp->info;
1518 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1519
1520 return CMD_SUCCESS;
1521}
1522
2e3b2e47 1523DEFUN (linkdetect,
1524 linkdetect_cmd,
1525 "link-detect",
1526 "Enable link detection on interface\n")
1527{
3ddccf18 1528 VTY_DECLVAR_CONTEXT (interface, ifp);
2e3b2e47 1529 int if_was_operative;
1530
244c1cdc 1531 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1532 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1533
1534 /* When linkdetection is enabled, if might come down */
244c1cdc 1535 if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp);
2e3b2e47 1536
1537 /* FIXME: Will defer status change forwarding if interface
1538 does not come down! */
1539
1540 return CMD_SUCCESS;
1541}
1542
1543
1544DEFUN (no_linkdetect,
1545 no_linkdetect_cmd,
1546 "no link-detect",
1547 NO_STR
1548 "Disable link detection on interface\n")
1549{
3ddccf18 1550 VTY_DECLVAR_CONTEXT (interface, ifp);
2e3b2e47 1551 int if_was_operative;
1552
244c1cdc 1553 if_was_operative = if_is_no_ptm_operative(ifp);
2e3b2e47 1554 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1555
1556 /* Interface may come up after disabling link detection */
1557 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1558
1559 /* FIXME: see linkdetect_cmd */
1560
1561 return CMD_SUCCESS;
1562}
1563
718e3744 1564DEFUN (shutdown_if,
1565 shutdown_if_cmd,
1566 "shutdown",
1567 "Shutdown the selected interface\n")
1568{
3ddccf18 1569 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1570 int ret;
718e3744 1571 struct zebra_if *if_data;
1572
bfac8dcd 1573 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1574 {
bfac8dcd
CF
1575 ret = if_unset_flags (ifp, IFF_UP);
1576 if (ret < 0)
1577 {
1578 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1579 return CMD_WARNING;
1580 }
1581 if_refresh (ifp);
718e3744 1582 }
718e3744 1583 if_data = ifp->info;
1584 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1585
1586 return CMD_SUCCESS;
1587}
1588
1589DEFUN (no_shutdown_if,
1590 no_shutdown_if_cmd,
1591 "no shutdown",
1592 NO_STR
1593 "Shutdown the selected interface\n")
1594{
3ddccf18 1595 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1596 int ret;
718e3744 1597 struct zebra_if *if_data;
1598
bfac8dcd 1599 if (ifp->ifindex != IFINDEX_INTERNAL)
718e3744 1600 {
bfac8dcd
CF
1601 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1602 if (ret < 0)
1603 {
1604 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1605 return CMD_WARNING;
1606 }
1607 if_refresh (ifp);
1608
1609 /* Some addresses (in particular, IPv6 addresses on Linux) get
1610 * removed when the interface goes down. They need to be readded.
1611 */
1612 if_addr_wakeup(ifp);
718e3744 1613 }
bfac8dcd 1614
718e3744 1615 if_data = ifp->info;
1616 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1617
1618 return CMD_SUCCESS;
1619}
1620
1621DEFUN (bandwidth_if,
1622 bandwidth_if_cmd,
6147e2c6 1623 "bandwidth (1-100000)",
718e3744 1624 "Set bandwidth informational parameter\n"
70bd3c43 1625 "Bandwidth in megabits\n")
718e3744 1626{
7c022376 1627 int idx_number = 1;
3ddccf18 1628 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1629 unsigned int bandwidth;
1630
7c022376 1631 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
718e3744 1632
70bd3c43
DS
1633 /* bandwidth range is <1-100000> */
1634 if (bandwidth < 1 || bandwidth > 100000)
718e3744 1635 {
1636 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1637 return CMD_WARNING;
1638 }
1639
1640 ifp->bandwidth = bandwidth;
1641
1642 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1643 if (if_is_operative (ifp))
718e3744 1644 zebra_interface_up_update (ifp);
1645
1646 return CMD_SUCCESS;
1647}
1648
1649DEFUN (no_bandwidth_if,
1650 no_bandwidth_if_cmd,
b62ecea5 1651 "no bandwidth [(1-100000)]",
718e3744 1652 NO_STR
b62ecea5
QY
1653 "Set bandwidth informational parameter\n"
1654 "Bandwidth in megabits\n")
718e3744 1655{
3ddccf18 1656 VTY_DECLVAR_CONTEXT (interface, ifp);
718e3744 1657
1658 ifp->bandwidth = 0;
1659
1660 /* force protocols to recalculate routes due to cost change */
2e3b2e47 1661 if (if_is_operative (ifp))
718e3744 1662 zebra_interface_up_update (ifp);
1663
1664 return CMD_SUCCESS;
1665}
1666
6b0655a2 1667
16f1b9ee
OD
1668struct cmd_node link_params_node =
1669{
1670 LINK_PARAMS_NODE,
1671 "%s(config-link-params)# ",
1672 1,
1673};
1674
1675static void
1676link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field,
1677 uint32_t type, uint32_t value)
1678{
1679 /* Update field as needed */
1680 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1681 {
1682 *field = value;
1683 SET_PARAM(ifp->link_params, type);
1684
1685 /* force protocols to update LINK STATE due to parameters change */
1686 if (if_is_operative (ifp))
1687 zebra_interface_parameters_update (ifp);
1688 }
1689}
1690static void
1691link_param_cmd_set_float (struct interface *ifp, float *field,
1692 uint32_t type, float value)
1693{
1694
1695 /* Update field as needed */
1696 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1697 {
1698 *field = value;
1699 SET_PARAM(ifp->link_params, type);
1700
1701 /* force protocols to update LINK STATE due to parameters change */
1702 if (if_is_operative (ifp))
1703 zebra_interface_parameters_update (ifp);
1704 }
1705}
1706
1707static void
1708link_param_cmd_unset (struct interface *ifp, uint32_t type)
1709{
313605cb
RW
1710 if (ifp->link_params == NULL)
1711 return;
16f1b9ee
OD
1712
1713 /* Unset field */
1714 UNSET_PARAM(ifp->link_params, type);
1715
1716 /* force protocols to update LINK STATE due to parameters change */
1717 if (if_is_operative (ifp))
1718 zebra_interface_parameters_update (ifp);
1719}
1720
505e5056 1721DEFUN_NOSH (link_params,
16f1b9ee
OD
1722 link_params_cmd,
1723 "link-params",
1724 LINK_PARAMS_STR)
1725{
3ddccf18 1726 /* vty->qobj_index stays the same @ interface pointer */
16f1b9ee
OD
1727 vty->node = LINK_PARAMS_NODE;
1728
1729 return CMD_SUCCESS;
1730}
1731
505e5056 1732DEFUN_NOSH (exit_link_params,
03f99d9a
DS
1733 exit_link_params_cmd,
1734 "exit-link-params",
1735 "Exit from Link Params configuration mode\n")
1736{
1737 if (vty->node == LINK_PARAMS_NODE)
1738 vty->node = INTERFACE_NODE;
1739 return CMD_SUCCESS;
1740}
1741
16f1b9ee
OD
1742/* Specific Traffic Engineering parameters commands */
1743DEFUN (link_params_enable,
1744 link_params_enable_cmd,
1745 "enable",
1746 "Activate link parameters on this interface\n")
1747{
3ddccf18 1748 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1749
1750 /* This command could be issue at startup, when activate MPLS TE */
1751 /* on a new interface or after a ON / OFF / ON toggle */
1752 /* In all case, TE parameters are reset to their default factory */
1753 if (IS_ZEBRA_DEBUG_EVENT)
1754 zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
1755
1756 if (!if_link_params_get (ifp))
1757 {
1758 if (IS_ZEBRA_DEBUG_EVENT)
1759 zlog_debug ("Link-params: failed to init TE link parameters %s", ifp->name);
1760
1761 return CMD_WARNING;
1762 }
1763
1764 /* force protocols to update LINK STATE due to parameters change */
1765 if (if_is_operative (ifp))
1766 zebra_interface_parameters_update (ifp);
1767
1768 return CMD_SUCCESS;
1769}
1770
1771DEFUN (no_link_params_enable,
1772 no_link_params_enable_cmd,
1773 "no enable",
1774 NO_STR
1775 "Disable link parameters on this interface\n")
1776{
3ddccf18 1777 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1778
1779 zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
1780
1781 if_link_params_free (ifp);
1782
1783 /* force protocols to update LINK STATE due to parameters change */
1784 if (if_is_operative (ifp))
1785 zebra_interface_parameters_update (ifp);
1786
1787 return CMD_SUCCESS;
1788}
1789
1790/* STANDARD TE metrics */
1791DEFUN (link_params_metric,
1792 link_params_metric_cmd,
6147e2c6 1793 "metric (0-4294967295)",
16f1b9ee
OD
1794 "Link metric for MPLS-TE purpose\n"
1795 "Metric value in decimal\n")
1796{
7c022376 1797 int idx_number = 1;
3ddccf18 1798 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1799 struct if_link_params *iflp = if_link_params_get (ifp);
1800 u_int32_t metric;
1801
7c022376 1802 VTY_GET_ULONG("metric", metric, argv[idx_number]->arg);
16f1b9ee
OD
1803
1804 /* Update TE metric if needed */
daf0a4d2 1805 link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee
OD
1806
1807 return CMD_SUCCESS;
1808}
1809
1810DEFUN (no_link_params_metric,
1811 no_link_params_metric_cmd,
1812 "no metric",
1813 NO_STR
3ddccf18 1814 "Disable Link Metric on this interface\n")
16f1b9ee 1815{
3ddccf18 1816 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1817
1818 /* Unset TE Metric */
daf0a4d2 1819 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee
OD
1820
1821 return CMD_SUCCESS;
1822}
1823
1824DEFUN (link_params_maxbw,
1825 link_params_maxbw_cmd,
1826 "max-bw BANDWIDTH",
1827 "Maximum bandwidth that can be used\n"
1828 "Bytes/second (IEEE floating point format)\n")
1829{
7c022376 1830 int idx_bandwidth = 1;
3ddccf18 1831 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1832 struct if_link_params *iflp = if_link_params_get (ifp);
1833
1834 float bw;
1835
7c022376 1836 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
1837 {
1838 vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
1839 VTY_NEWLINE);
1840 return CMD_WARNING;
1841 }
1842
1843 /* Check that Maximum bandwidth is not lower than other bandwidth parameters */
1844 if ((bw <= iflp->max_rsv_bw)
1845 || (bw <= iflp->unrsv_bw[0])
1846 || (bw <= iflp->unrsv_bw[1])
1847 || (bw <= iflp->unrsv_bw[2])
1848 || (bw <= iflp->unrsv_bw[3])
1849 || (bw <= iflp->unrsv_bw[4])
1850 || (bw <= iflp->unrsv_bw[5])
1851 || (bw <= iflp->unrsv_bw[6])
1852 || (bw <= iflp->unrsv_bw[7])
1853 || (bw <= iflp->ava_bw)
1854 || (bw <= iflp->res_bw)
1855 || (bw <= iflp->use_bw))
1856 {
1857 vty_out (vty,
1858 "Maximum Bandwidth could not be lower than others bandwidth%s",
1859 VTY_NEWLINE);
1860 return CMD_WARNING;
1861 }
1862
1863 /* Update Maximum Bandwidth if needed */
1864 link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
1865
1866 return CMD_SUCCESS;
1867}
1868
1869DEFUN (link_params_max_rsv_bw,
1870 link_params_max_rsv_bw_cmd,
1871 "max-rsv-bw BANDWIDTH",
1872 "Maximum bandwidth that may be reserved\n"
1873 "Bytes/second (IEEE floating point format)\n")
1874{
7c022376 1875 int idx_bandwidth = 1;
3ddccf18 1876 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1877 struct if_link_params *iflp = if_link_params_get (ifp);
1878 float bw;
1879
7c022376 1880 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
1881 {
1882 vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
1883 VTY_NEWLINE);
1884 return CMD_WARNING;
1885 }
1886
1887 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1888 if (bw > iflp->max_bw)
1889 {
1890 vty_out (vty,
1891 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1892 iflp->max_bw, VTY_NEWLINE);
1893 return CMD_WARNING;
1894 }
1895
1896 /* Update Maximum Reservable Bandwidth if needed */
1897 link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
1898
1899 return CMD_SUCCESS;
1900}
1901
1902DEFUN (link_params_unrsv_bw,
1903 link_params_unrsv_bw_cmd,
6147e2c6 1904 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
1905 "Unreserved bandwidth at each priority level\n"
1906 "Priority\n"
1907 "Bytes/second (IEEE floating point format)\n")
1908{
7c022376
DW
1909 int idx_number = 1;
1910 int idx_bandwidth = 2;
3ddccf18 1911 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1912 struct if_link_params *iflp = if_link_params_get (ifp);
1913 int priority;
1914 float bw;
1915
1916 /* We don't have to consider about range check here. */
7c022376 1917 if (sscanf (argv[idx_number]->arg, "%d", &priority) != 1)
16f1b9ee
OD
1918 {
1919 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1920 VTY_NEWLINE);
1921 return CMD_WARNING;
1922 }
1923
7c022376 1924 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
1925 {
1926 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1927 VTY_NEWLINE);
1928 return CMD_WARNING;
1929 }
1930
1931 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1932 if (bw > iflp->max_bw)
1933 {
1934 vty_out (vty,
1935 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1936 iflp->max_bw, VTY_NEWLINE);
1937 return CMD_WARNING;
1938 }
1939
1940 /* Update Unreserved Bandwidth if needed */
1941 link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
1942
1943 return CMD_SUCCESS;
1944}
1945
1946DEFUN (link_params_admin_grp,
1947 link_params_admin_grp_cmd,
1948 "admin-grp BITPATTERN",
1949 "Administrative group membership\n"
1950 "32-bit Hexadecimal value (e.g. 0xa1)\n")
1951{
7c022376 1952 int idx_bitpattern = 1;
3ddccf18 1953 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1954 struct if_link_params *iflp = if_link_params_get (ifp);
1955 unsigned long value;
1956
7c022376 1957 if (sscanf (argv[idx_bitpattern]->arg, "0x%lx", &value) != 1)
16f1b9ee
OD
1958 {
1959 vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
1960 safe_strerror (errno), VTY_NEWLINE);
1961 return CMD_WARNING;
1962 }
1963
1964 /* Update Administrative Group if needed */
1965 link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
1966
1967 return CMD_SUCCESS;
1968}
1969
1970DEFUN (no_link_params_admin_grp,
1971 no_link_params_admin_grp_cmd,
1972 "no admin-grp",
1973 NO_STR
3ddccf18 1974 "Disable Administrative group membership on this interface\n")
16f1b9ee 1975{
3ddccf18 1976 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1977
1978 /* Unset Admin Group */
1979 link_param_cmd_unset(ifp, LP_ADM_GRP);
1980
1981 return CMD_SUCCESS;
1982}
1983
1984/* RFC5392 & RFC5316: INTER-AS */
1985DEFUN (link_params_inter_as,
1986 link_params_inter_as_cmd,
6147e2c6 1987 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
1988 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
1989 "Remote IP address in dot decimal A.B.C.D\n"
1990 "Remote AS number\n"
1991 "AS number in the range <1-4294967295>\n")
1992{
7c022376
DW
1993 int idx_ipv4 = 1;
1994 int idx_number = 3;
16f1b9ee 1995
3ddccf18 1996 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
1997 struct if_link_params *iflp = if_link_params_get (ifp);
1998 struct in_addr addr;
1999 u_int32_t as;
2000
7c022376 2001 if (!inet_aton (argv[idx_ipv4]->arg, &addr))
16f1b9ee
OD
2002 {
2003 vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
2004 return CMD_WARNING;
2005 }
2006
7c022376 2007 VTY_GET_ULONG("AS number", as, argv[idx_number]->arg);
16f1b9ee
OD
2008
2009 /* Update Remote IP and Remote AS fields if needed */
2010 if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
2011 || iflp->rmt_as != as
2012 || iflp->rmt_ip.s_addr != addr.s_addr)
2013 {
2014
2015 iflp->rmt_as = as;
2016 iflp->rmt_ip.s_addr = addr.s_addr;
2017 SET_PARAM(iflp, LP_RMT_AS);
2018
2019 /* force protocols to update LINK STATE due to parameters change */
2020 if (if_is_operative (ifp))
2021 zebra_interface_parameters_update (ifp);
2022 }
2023 return CMD_SUCCESS;
2024}
2025
2026DEFUN (no_link_params_inter_as,
2027 no_link_params_inter_as_cmd,
2028 "no neighbor",
2029 NO_STR
2030 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2031{
3ddccf18 2032 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2033 struct if_link_params *iflp = if_link_params_get (ifp);
2034
2035 /* Reset Remote IP and AS neighbor */
2036 iflp->rmt_as = 0;
2037 iflp->rmt_ip.s_addr = 0;
2038 UNSET_PARAM(iflp, LP_RMT_AS);
2039
2040 /* force protocols to update LINK STATE due to parameters change */
2041 if (if_is_operative (ifp))
2042 zebra_interface_parameters_update (ifp);
2043
2044 return CMD_SUCCESS;
2045}
2046
2047/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
2048DEFUN (link_params_delay,
2049 link_params_delay_cmd,
b62ecea5 2050 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 2051 "Unidirectional Average Link Delay\n"
b62ecea5
QY
2052 "Average delay in micro-second as decimal (0...16777215)\n"
2053 "Minimum delay\n"
2054 "Minimum delay in micro-second as decimal (0...16777215)\n"
2055 "Maximum delay\n"
2056 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 2057{
b62ecea5
QY
2058 /* Get and Check new delay values */
2059 u_int32_t delay = 0, low = 0, high = 0;
2060 VTY_GET_ULONG("delay", delay, argv[1]->arg);
2061 if (argc == 6)
2062 {
2063 VTY_GET_ULONG("minimum delay", low, argv[3]->arg);
2064 VTY_GET_ULONG("maximum delay", high, argv[5]->arg);
2065 }
16f1b9ee 2066
3ddccf18 2067 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee 2068 struct if_link_params *iflp = if_link_params_get (ifp);
16f1b9ee
OD
2069 u_int8_t update = 0;
2070
b62ecea5
QY
2071 if (argc == 2)
2072 {
2073 /* Check new delay value against old Min and Max delays if set */
2074 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2075 && (delay <= iflp->min_delay || delay >= iflp->max_delay))
2076 {
2077 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
2078 iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
2079 return CMD_WARNING;
2080 }
2081 /* Update delay if value is not set or change */
2082 if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
2083 {
2084 iflp->av_delay = delay;
2085 SET_PARAM(iflp, LP_DELAY);
2086 update = 1;
2087 }
2088 /* Unset Min and Max delays if already set */
2089 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2090 {
2091 iflp->min_delay = 0;
2092 iflp->max_delay = 0;
2093 UNSET_PARAM(iflp, LP_MM_DELAY);
2094 update = 1;
2095 }
2096 }
2097 else
2098 {
2099 /* Check new delays value coherency */
2100 if (delay <= low || delay >= high)
2101 {
2102 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
2103 low, high, VTY_NEWLINE);
2104 return CMD_WARNING;
2105 }
2106 /* Update Delays if needed */
2107 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2108 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2109 || iflp->av_delay != delay
2110 || iflp->min_delay != low
2111 || iflp->max_delay != high)
2112 {
2113 iflp->av_delay = delay;
2114 SET_PARAM(iflp, LP_DELAY);
2115 iflp->min_delay = low;
2116 iflp->max_delay = high;
2117 SET_PARAM(iflp, LP_MM_DELAY);
2118 update = 1;
2119 }
2120 }
16f1b9ee
OD
2121
2122 /* force protocols to update LINK STATE due to parameters change */
2123 if (update == 1 && if_is_operative (ifp))
2124 zebra_interface_parameters_update (ifp);
2125
2126 return CMD_SUCCESS;
2127}
2128
16f1b9ee
OD
2129DEFUN (no_link_params_delay,
2130 no_link_params_delay_cmd,
2131 "no delay",
2132 NO_STR
3ddccf18 2133 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 2134{
3ddccf18 2135 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2136 struct if_link_params *iflp = if_link_params_get (ifp);
2137
2138 /* Unset Delays */
2139 iflp->av_delay = 0;
2140 UNSET_PARAM(iflp, LP_DELAY);
2141 iflp->min_delay = 0;
2142 iflp->max_delay = 0;
2143 UNSET_PARAM(iflp, LP_MM_DELAY);
2144
2145 /* force protocols to update LINK STATE due to parameters change */
2146 if (if_is_operative (ifp))
2147 zebra_interface_parameters_update (ifp);
2148
2149 return CMD_SUCCESS;
2150}
2151
2152DEFUN (link_params_delay_var,
2153 link_params_delay_var_cmd,
6147e2c6 2154 "delay-variation (0-16777215)",
16f1b9ee
OD
2155 "Unidirectional Link Delay Variation\n"
2156 "delay variation in micro-second as decimal (0...16777215)\n")
2157{
7c022376 2158 int idx_number = 1;
3ddccf18 2159 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2160 struct if_link_params *iflp = if_link_params_get (ifp);
2161 u_int32_t value;
2162
7c022376 2163 VTY_GET_ULONG("delay variation", value, argv[idx_number]->arg);
16f1b9ee
OD
2164
2165 /* Update Delay Variation if needed */
2166 link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2167
2168 return CMD_SUCCESS;
2169}
2170
2171DEFUN (no_link_params_delay_var,
2172 no_link_params_delay_var_cmd,
2173 "no delay-variation",
2174 NO_STR
3ddccf18 2175 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 2176{
3ddccf18 2177 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2178
2179 /* Unset Delay Variation */
2180 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2181
2182 return CMD_SUCCESS;
2183}
2184
2185DEFUN (link_params_pkt_loss,
2186 link_params_pkt_loss_cmd,
2187 "packet-loss PERCENTAGE",
2188 "Unidirectional Link Packet Loss\n"
2189 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2190{
7c022376 2191 int idx_percentage = 1;
3ddccf18 2192 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2193 struct if_link_params *iflp = if_link_params_get (ifp);
2194 float fval;
2195
7c022376 2196 if (sscanf (argv[idx_percentage]->arg, "%g", &fval) != 1)
16f1b9ee
OD
2197 {
2198 vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
2199 VTY_NEWLINE);
2200 return CMD_WARNING;
2201 }
2202
2203 if (fval > MAX_PKT_LOSS)
2204 fval = MAX_PKT_LOSS;
2205
2206 /* Update Packet Loss if needed */
2207 link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2208
2209 return CMD_SUCCESS;
2210}
2211
2212DEFUN (no_link_params_pkt_loss,
2213 no_link_params_pkt_loss_cmd,
2214 "no packet-loss",
2215 NO_STR
3ddccf18 2216 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 2217{
3ddccf18 2218 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2219
2220 /* Unset Packet Loss */
2221 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2222
2223 return CMD_SUCCESS;
2224}
2225
2226DEFUN (link_params_res_bw,
2227 link_params_res_bw_cmd,
2228 "res-bw BANDWIDTH",
2229 "Unidirectional Residual Bandwidth\n"
2230 "Bytes/second (IEEE floating point format)\n")
2231{
7c022376 2232 int idx_bandwidth = 1;
3ddccf18 2233 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2234 struct if_link_params *iflp = if_link_params_get (ifp);
2235 float bw;
2236
7c022376 2237 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
2238 {
2239 vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
2240 VTY_NEWLINE);
2241 return CMD_WARNING;
2242 }
2243
2244 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2245 if (bw > iflp->max_bw)
2246 {
2247 vty_out (vty,
2248 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2249 iflp->max_bw, VTY_NEWLINE);
2250 return CMD_WARNING;
2251 }
2252
2253 /* Update Residual Bandwidth if needed */
2254 link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
2255
2256 return CMD_SUCCESS;
2257}
2258
2259DEFUN (no_link_params_res_bw,
2260 no_link_params_res_bw_cmd,
2261 "no res-bw",
2262 NO_STR
3ddccf18 2263 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 2264{
3ddccf18 2265 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2266
2267 /* Unset Residual Bandwidth */
2268 link_param_cmd_unset(ifp, LP_RES_BW);
2269
2270 return CMD_SUCCESS;
2271}
2272
2273DEFUN (link_params_ava_bw,
2274 link_params_ava_bw_cmd,
2275 "ava-bw BANDWIDTH",
2276 "Unidirectional Available Bandwidth\n"
2277 "Bytes/second (IEEE floating point format)\n")
2278{
7c022376 2279 int idx_bandwidth = 1;
3ddccf18 2280 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2281 struct if_link_params *iflp = if_link_params_get (ifp);
2282 float bw;
2283
7c022376 2284 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
2285 {
2286 vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
2287 VTY_NEWLINE);
2288 return CMD_WARNING;
2289 }
2290
2291 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2292 if (bw > iflp->max_bw)
2293 {
2294 vty_out (vty,
2295 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2296 iflp->max_bw, VTY_NEWLINE);
2297 return CMD_WARNING;
2298 }
2299
2300 /* Update Residual Bandwidth if needed */
2301 link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2302
2303 return CMD_SUCCESS;
2304}
2305
2306DEFUN (no_link_params_ava_bw,
2307 no_link_params_ava_bw_cmd,
2308 "no ava-bw",
2309 NO_STR
3ddccf18 2310 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 2311{
3ddccf18 2312 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2313
2314 /* Unset Available Bandwidth */
2315 link_param_cmd_unset(ifp, LP_AVA_BW);
2316
2317 return CMD_SUCCESS;
2318}
2319
2320DEFUN (link_params_use_bw,
2321 link_params_use_bw_cmd,
2322 "use-bw BANDWIDTH",
2323 "Unidirectional Utilised Bandwidth\n"
2324 "Bytes/second (IEEE floating point format)\n")
2325{
7c022376 2326 int idx_bandwidth = 1;
3ddccf18 2327 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2328 struct if_link_params *iflp = if_link_params_get (ifp);
2329 float bw;
2330
7c022376 2331 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
16f1b9ee
OD
2332 {
2333 vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
2334 VTY_NEWLINE);
2335 return CMD_WARNING;
2336 }
2337
2338 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2339 if (bw > iflp->max_bw)
2340 {
2341 vty_out (vty,
2342 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2343 iflp->max_bw, VTY_NEWLINE);
2344 return CMD_WARNING;
2345 }
2346
2347 /* Update Utilized Bandwidth if needed */
2348 link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
2349
2350 return CMD_SUCCESS;
2351}
2352
2353DEFUN (no_link_params_use_bw,
2354 no_link_params_use_bw_cmd,
2355 "no use-bw",
2356 NO_STR
3ddccf18 2357 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 2358{
3ddccf18 2359 VTY_DECLVAR_CONTEXT (interface, ifp);
16f1b9ee
OD
2360
2361 /* Unset Utilised Bandwidth */
2362 link_param_cmd_unset(ifp, LP_USE_BW);
2363
2364 return CMD_SUCCESS;
2365}
2366
a1ac18c4 2367static int
39db97e4 2368ip_address_install (struct vty *vty, struct interface *ifp,
2369 const char *addr_str, const char *peer_str,
2370 const char *label)
718e3744 2371{
bfac8dcd 2372 struct zebra_if *if_data;
718e3744 2373 struct prefix_ipv4 cp;
2374 struct connected *ifc;
2375 struct prefix_ipv4 *p;
718e3744 2376 int ret;
2377
bfac8dcd
CF
2378 if_data = ifp->info;
2379
718e3744 2380 ret = str2prefix_ipv4 (addr_str, &cp);
2381 if (ret <= 0)
2382 {
2383 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2384 return CMD_WARNING;
2385 }
2386
d914d5ff
DS
2387 if (ipv4_martian(&cp.prefix))
2388 {
2389 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
2390 return CMD_WARNING;
2391 }
2392
ca16218d 2393 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 2394 if (! ifc)
2395 {
2396 ifc = connected_new ();
2397 ifc->ifp = ifp;
2398
2399 /* Address. */
2400 p = prefix_ipv4_new ();
2401 *p = cp;
2402 ifc->address = (struct prefix *) p;
2403
2404 /* Broadcast. */
3fb9cd6e 2405 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
718e3744 2406 {
2407 p = prefix_ipv4_new ();
2408 *p = cp;
3fb9cd6e 2409 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
718e3744 2410 ifc->destination = (struct prefix *) p;
2411 }
2412
718e3744 2413 /* Label. */
2414 if (label)
0752ef0b 2415 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 2416
2417 /* Add to linked list. */
2418 listnode_add (ifp->connected, ifc);
2419 }
2420
2421 /* This address is configured from zebra. */
2422 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2423 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2424
2425 /* In case of this route need to install kernel. */
f7f740fe 2426 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
2427 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2428 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 2429 {
2430 /* Some system need to up the interface to set IP address. */
2431 if (! if_is_up (ifp))
2432 {
2433 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2434 if_refresh (ifp);
2435 }
2436
2437 ret = if_set_prefix (ifp, ifc);
2438 if (ret < 0)
2439 {
2440 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 2441 safe_strerror(errno), VTY_NEWLINE);
718e3744 2442 return CMD_WARNING;
2443 }
2444
f7f740fe 2445 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
2446 /* The address will be advertised to zebra clients when the notification
2447 * from the kernel has been received.
2448 * It will also be added to the subnet chain list, then. */
718e3744 2449 }
2450
2451 return CMD_SUCCESS;
2452}
2453
a1ac18c4 2454static int
39db97e4 2455ip_address_uninstall (struct vty *vty, struct interface *ifp,
2456 const char *addr_str, const char *peer_str,
2457 const char *label)
718e3744 2458{
2459 struct prefix_ipv4 cp;
2460 struct connected *ifc;
2461 int ret;
2462
2463 /* Convert to prefix structure. */
2464 ret = str2prefix_ipv4 (addr_str, &cp);
2465 if (ret <= 0)
2466 {
2467 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2468 return CMD_WARNING;
2469 }
2470
2471 /* Check current interface address. */
ca16218d 2472 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 2473 if (! ifc)
2474 {
2475 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2476 return CMD_WARNING;
2477 }
2478
2479 /* This is not configured address. */
2480 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2481 return CMD_WARNING;
2482
74ecdc9e
PJ
2483 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2484
718e3744 2485 /* This is not real address or interface is not active. */
f7f740fe 2486 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 2487 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2488 {
2489 listnode_delete (ifp->connected, ifc);
2490 connected_free (ifc);
2491 return CMD_WARNING;
2492 }
2493
2494 /* This is real route. */
2495 ret = if_unset_prefix (ifp, ifc);
2496 if (ret < 0)
2497 {
2498 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 2499 safe_strerror(errno), VTY_NEWLINE);
718e3744 2500 return CMD_WARNING;
2501 }
f7f740fe 2502 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
2503 /* we will receive a kernel notification about this route being removed.
2504 * this will trigger its removal from the connected list. */
718e3744 2505 return CMD_SUCCESS;
2506}
2507
2508DEFUN (ip_address,
2509 ip_address_cmd,
2510 "ip address A.B.C.D/M",
2511 "Interface Internet Protocol config commands\n"
2512 "Set the IP address of an interface\n"
2513 "IP address (e.g. 10.0.0.1/8)\n")
2514{
7c022376 2515 int idx_ipv4_prefixlen = 2;
3ddccf18 2516 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2517 return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
718e3744 2518}
2519
2520DEFUN (no_ip_address,
2521 no_ip_address_cmd,
2522 "no ip address A.B.C.D/M",
2523 NO_STR
2524 "Interface Internet Protocol config commands\n"
2525 "Set the IP address of an interface\n"
2526 "IP Address (e.g. 10.0.0.1/8)")
2527{
7c022376 2528 int idx_ipv4_prefixlen = 3;
3ddccf18 2529 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2530 return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
718e3744 2531}
2532
986aa00f 2533
718e3744 2534#ifdef HAVE_NETLINK
718e3744 2535DEFUN (ip_address_label,
2536 ip_address_label_cmd,
2537 "ip address A.B.C.D/M label LINE",
2538 "Interface Internet Protocol config commands\n"
2539 "Set the IP address of an interface\n"
2540 "IP address (e.g. 10.0.0.1/8)\n"
2541 "Label of this address\n"
2542 "Label\n")
2543{
7c022376
DW
2544 int idx_ipv4_prefixlen = 2;
2545 int idx_line = 4;
3ddccf18 2546 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2547 return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
718e3744 2548}
2549
2550DEFUN (no_ip_address_label,
2551 no_ip_address_label_cmd,
2552 "no ip address A.B.C.D/M label LINE",
2553 NO_STR
2554 "Interface Internet Protocol config commands\n"
2555 "Set the IP address of an interface\n"
2556 "IP address (e.g. 10.0.0.1/8)\n"
2557 "Label of this address\n"
2558 "Label\n")
2559{
7c022376
DW
2560 int idx_ipv4_prefixlen = 3;
2561 int idx_line = 5;
3ddccf18 2562 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2563 return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
718e3744 2564}
2565#endif /* HAVE_NETLINK */
2566
a1ac18c4 2567static int
39db97e4 2568ipv6_address_install (struct vty *vty, struct interface *ifp,
2569 const char *addr_str, const char *peer_str,
2570 const char *label, int secondary)
718e3744 2571{
bfac8dcd 2572 struct zebra_if *if_data;
718e3744 2573 struct prefix_ipv6 cp;
2574 struct connected *ifc;
2575 struct prefix_ipv6 *p;
2576 int ret;
2577
bfac8dcd
CF
2578 if_data = ifp->info;
2579
718e3744 2580 ret = str2prefix_ipv6 (addr_str, &cp);
2581 if (ret <= 0)
2582 {
2583 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2584 return CMD_WARNING;
2585 }
2586
d914d5ff
DS
2587 if (ipv6_martian(&cp.prefix))
2588 {
2589 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
2590 return CMD_WARNING;
2591 }
2592
ca16218d 2593 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 2594 if (! ifc)
2595 {
2596 ifc = connected_new ();
2597 ifc->ifp = ifp;
2598
2599 /* Address. */
2600 p = prefix_ipv6_new ();
2601 *p = cp;
2602 ifc->address = (struct prefix *) p;
2603
2604 /* Secondary. */
2605 if (secondary)
2606 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
2607
2608 /* Label. */
2609 if (label)
0752ef0b 2610 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
718e3744 2611
2612 /* Add to linked list. */
2613 listnode_add (ifp->connected, ifc);
2614 }
2615
2616 /* This address is configured from zebra. */
2617 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2618 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2619
2620 /* In case of this route need to install kernel. */
f7f740fe 2621 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
bfac8dcd
CF
2622 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2623 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
718e3744 2624 {
2625 /* Some system need to up the interface to set IP address. */
2626 if (! if_is_up (ifp))
2627 {
2628 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2629 if_refresh (ifp);
2630 }
2631
2632 ret = if_prefix_add_ipv6 (ifp, ifc);
2633
2634 if (ret < 0)
2635 {
2636 vty_out (vty, "%% Can't set interface IP address: %s.%s",
6099b3b5 2637 safe_strerror(errno), VTY_NEWLINE);
718e3744 2638 return CMD_WARNING;
2639 }
2640
f7f740fe 2641 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
2642 /* The address will be advertised to zebra clients when the notification
2643 * from the kernel has been received. */
718e3744 2644 }
2645
2646 return CMD_SUCCESS;
2647}
2648
b6120505
DW
2649/* Return true if an ipv6 address is configured on ifp */
2650int
2651ipv6_address_configured (struct interface *ifp)
2652{
2653 struct connected *connected;
2654 struct listnode *node;
2655
2656 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
2657 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && (connected->address->family == AF_INET6))
2658 return 1;
2659
2660 return 0;
2661}
2662
a1ac18c4 2663static int
39db97e4 2664ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
2665 const char *addr_str, const char *peer_str,
2666 const char *label, int secondry)
718e3744 2667{
2668 struct prefix_ipv6 cp;
2669 struct connected *ifc;
2670 int ret;
2671
2672 /* Convert to prefix structure. */
2673 ret = str2prefix_ipv6 (addr_str, &cp);
2674 if (ret <= 0)
2675 {
2676 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2677 return CMD_WARNING;
2678 }
2679
2680 /* Check current interface address. */
ca16218d 2681 ifc = connected_check (ifp, (struct prefix *) &cp);
718e3744 2682 if (! ifc)
2683 {
2684 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2685 return CMD_WARNING;
2686 }
2687
2688 /* This is not configured address. */
2689 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2690 return CMD_WARNING;
2691
676e1a01
CF
2692 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2693
718e3744 2694 /* This is not real address or interface is not active. */
f7f740fe 2695 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
718e3744 2696 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2697 {
2698 listnode_delete (ifp->connected, ifc);
2699 connected_free (ifc);
2700 return CMD_WARNING;
2701 }
2702
2703 /* This is real route. */
2704 ret = if_prefix_delete_ipv6 (ifp, ifc);
2705 if (ret < 0)
2706 {
2707 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
6099b3b5 2708 safe_strerror(errno), VTY_NEWLINE);
718e3744 2709 return CMD_WARNING;
2710 }
2711
f7f740fe 2712 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
02b4805f
CF
2713 /* This information will be propagated to the zclients when the
2714 * kernel notification is received. */
718e3744 2715 return CMD_SUCCESS;
2716}
2717
2718DEFUN (ipv6_address,
2719 ipv6_address_cmd,
2720 "ipv6 address X:X::X:X/M",
e23949c0 2721 "Interface IPv6 config commands\n"
718e3744 2722 "Set the IP address of an interface\n"
2723 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2724{
7c022376 2725 int idx_ipv6_prefixlen = 2;
3ddccf18 2726 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2727 return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
718e3744 2728}
2729
2730DEFUN (no_ipv6_address,
2731 no_ipv6_address_cmd,
2732 "no ipv6 address X:X::X:X/M",
2733 NO_STR
e23949c0 2734 "Interface IPv6 config commands\n"
718e3744 2735 "Set the IP address of an interface\n"
2736 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2737{
7c022376 2738 int idx_ipv6_prefixlen = 3;
3ddccf18 2739 VTY_DECLVAR_CONTEXT (interface, ifp);
e52702f2 2740 return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
718e3744 2741}
718e3744 2742
16f1b9ee
OD
2743static int
2744link_params_config_write (struct vty *vty, struct interface *ifp)
2745{
2746 int i;
2747
2748 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2749 return -1;
2750
2751 struct if_link_params *iflp = ifp->link_params;
2752
2753 vty_out (vty, " link-params%s", VTY_NEWLINE);
2754 vty_out(vty, " enable%s", VTY_NEWLINE);
daf0a4d2 2755 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
16f1b9ee 2756 vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
b6a9e7b4 2757 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
16f1b9ee 2758 vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
b6a9e7b4 2759 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) && iflp->max_rsv_bw != iflp->default_bw)
16f1b9ee
OD
2760 vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
2761 if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
2762 {
2763 for (i = 0; i < 8; i++)
b6a9e7b4
DS
2764 if (iflp->unrsv_bw[i] != iflp->default_bw)
2765 vty_out(vty, " unrsv-bw %d %g%s",
2766 i, iflp->unrsv_bw[i], VTY_NEWLINE);
16f1b9ee
OD
2767 }
2768 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
b6a9e7b4 2769 vty_out(vty, " admin-grp 0x%x%s", iflp->admin_grp, VTY_NEWLINE);
16f1b9ee
OD
2770 if (IS_PARAM_SET(iflp, LP_DELAY))
2771 {
2772 vty_out(vty, " delay %u", iflp->av_delay);
2773 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2774 {
2775 vty_out(vty, " min %u", iflp->min_delay);
2776 vty_out(vty, " max %u", iflp->max_delay);
2777 }
2778 vty_out(vty, "%s", VTY_NEWLINE);
2779 }
2780 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2781 vty_out(vty, " delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
2782 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2783 vty_out(vty, " packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
2784 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2785 vty_out(vty, " ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
2786 if (IS_PARAM_SET(iflp, LP_RES_BW))
2787 vty_out(vty, " res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
2788 if (IS_PARAM_SET(iflp, LP_USE_BW))
2789 vty_out(vty, " use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
2790 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2791 vty_out(vty, " neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
2792 iflp->rmt_as, VTY_NEWLINE);
03f99d9a 2793 vty_out(vty, " exit-link-params%s", VTY_NEWLINE);
16f1b9ee
OD
2794 return 0;
2795}
2796
a1ac18c4 2797static int
718e3744 2798if_config_write (struct vty *vty)
2799{
1a1a7065 2800 struct vrf *vrf;
52dc7ee6 2801 struct listnode *node;
718e3744 2802 struct interface *ifp;
718e3744 2803
244c1cdc
DS
2804 zebra_ptm_write (vty);
2805
a62c4901 2806 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1a1a7065 2807 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
718e3744 2808 {
2809 struct zebra_if *if_data;
52dc7ee6 2810 struct listnode *addrnode;
718e3744 2811 struct connected *ifc;
2812 struct prefix *p;
12f6fb97 2813 struct vrf *vrf;
718e3744 2814
718e3744 2815 if_data = ifp->info;
5f3d1bdf 2816 vrf = vrf_lookup_by_id (ifp->vrf_id);
cd2a8a42
FL
2817
2818 if (ifp->vrf_id == VRF_DEFAULT)
2819 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2820 else
12f6fb97 2821 vty_out (vty, "interface %s vrf %s%s", ifp->name, vrf->name,
cd2a8a42 2822 VTY_NEWLINE);
718e3744 2823
bfac8dcd
CF
2824 if (if_data)
2825 {
2826 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2827 vty_out (vty, " shutdown%s", VTY_NEWLINE);
986aa00f 2828
2829 zebra_ptm_if_write(vty, if_data);
bfac8dcd
CF
2830 }
2831
718e3744 2832 if (ifp->desc)
2833 vty_out (vty, " description %s%s", ifp->desc,
2834 VTY_NEWLINE);
2835
2836 /* Assign bandwidth here to avoid unnecessary interface flap
2837 while processing config script */
2838 if (ifp->bandwidth != 0)
2839 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
2840
07fc1596
DD
2841 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
2842 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2e3b2e47 2843
1eb8ef25 2844 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
718e3744 2845 {
718e3744 2846 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2847 {
81cce018 2848 char buf[INET6_ADDRSTRLEN];
718e3744 2849 p = ifc->address;
35d921cc 2850 vty_out (vty, " ip%s address %s",
718e3744 2851 p->family == AF_INET ? "" : "v6",
35d921cc 2852 prefix2str (p, buf, sizeof(buf)));
718e3744 2853
718e3744 2854 if (ifc->label)
2855 vty_out (vty, " label %s", ifc->label);
2856
2857 vty_out (vty, "%s", VTY_NEWLINE);
2858 }
2859 }
2860
2861 if (if_data)
2862 {
718e3744 2863 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2864 vty_out (vty, " %smulticast%s",
2865 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2866 VTY_NEWLINE);
2867 }
2868
8da4e946 2869#if defined (HAVE_RTADV)
718e3744 2870 rtadv_config_write (vty, ifp);
8da4e946 2871#endif /* HAVE_RTADV */
718e3744 2872
ca776988 2873#ifdef HAVE_IRDP
2874 irdp_config_write (vty, ifp);
2875#endif /* IRDP */
2876
16f1b9ee
OD
2877 link_params_config_write (vty, ifp);
2878
718e3744 2879 vty_out (vty, "!%s", VTY_NEWLINE);
2880 }
2881 return 0;
2882}
2883
2884/* Allocate and initialize interface vector. */
2885void
a1ac18c4 2886zebra_if_init (void)
718e3744 2887{
2888 /* Initialize interface and new hook. */
718e3744 2889 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2890 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2891
2892 /* Install configuration write function. */
2893 install_node (&interface_node, if_config_write);
16f1b9ee 2894 install_node (&link_params_node, NULL);
0b84f294 2895 if_cmd_init ();
718e3744 2896
2897 install_element (VIEW_NODE, &show_interface_cmd);
8b87bdf4 2898 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
8b87bdf4
FL
2899 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2900 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
e52702f2 2901
ed9bb6d5 2902 install_element (ENABLE_NODE, &show_interface_desc_cmd);
8b87bdf4 2903 install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
718e3744 2904 install_element (INTERFACE_NODE, &multicast_cmd);
2905 install_element (INTERFACE_NODE, &no_multicast_cmd);
2e3b2e47 2906 install_element (INTERFACE_NODE, &linkdetect_cmd);
2907 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
718e3744 2908 install_element (INTERFACE_NODE, &shutdown_if_cmd);
2909 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2910 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2911 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
718e3744 2912 install_element (INTERFACE_NODE, &ip_address_cmd);
2913 install_element (INTERFACE_NODE, &no_ip_address_cmd);
718e3744 2914 install_element (INTERFACE_NODE, &ipv6_address_cmd);
2915 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 2916#ifdef HAVE_NETLINK
718e3744 2917 install_element (INTERFACE_NODE, &ip_address_label_cmd);
718e3744 2918 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
2919#endif /* HAVE_NETLINK */
16f1b9ee
OD
2920 install_element(INTERFACE_NODE, &link_params_cmd);
2921 install_default(LINK_PARAMS_NODE);
2922 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2923 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2924 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
d7d73ffc 2925 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
16f1b9ee
OD
2926 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2927 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2928 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2929 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
95c2af68 2930 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
16f1b9ee
OD
2931 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2932 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2933 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
95c2af68 2934 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
16f1b9ee 2935 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
95c2af68 2936 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
16f1b9ee 2937 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
95c2af68 2938 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
16f1b9ee 2939 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
95c2af68 2940 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
16f1b9ee 2941 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
95c2af68 2942 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
16f1b9ee 2943 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
95c2af68 2944 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
03f99d9a 2945 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
718e3744 2946}