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