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