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