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