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