]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
Merge pull request #10447 from ton31337/fix/json_with_whitespaces
[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"
4d43f68a 25#include "lib_errors.h"
718e3744 26#include "vty.h"
27#include "sockunion.h"
28#include "prefix.h"
29#include "command.h"
30#include "memory.h"
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"
3801e764 43#include "zebra/zebra_router.h"
718e3744 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"
c3bd894e 49#include "zebra/if_netlink.h"
88177fe3 50#include "zebra/interface.h"
13d60d35 51#include "zebra/zebra_vxlan.h"
9df414fe 52#include "zebra/zebra_errors.h"
ce5160c0 53#include "zebra/zebra_evpn_mh.h"
244c1cdc 54
bf8d3d6a 55DEFINE_MTYPE_STATIC(ZEBRA, ZINFO, "Zebra Interface Information");
8e59a402 56
244c1cdc 57#define ZEBRA_PTM_SUPPORT
718e3744 58
996c9314 59DEFINE_HOOK(zebra_if_extra_info, (struct vty * vty, struct interface *ifp),
8451921b 60 (vty, ifp));
996c9314 61DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
8451921b 62 (vty, ifp));
718e3744 63
dc7b3cae 64
d62a17ae 65static void if_down_del_nbr_connected(struct interface *ifp);
c8e264b6 66
cc9f21da 67static void if_zebra_speed_update(struct thread *thread)
dc7b3cae
DS
68{
69 struct interface *ifp = THREAD_ARG(thread);
70 struct zebra_if *zif = ifp->info;
71 uint32_t new_speed;
8f08b1cc 72 bool changed = false;
594c2878 73 int error = 0;
dc7b3cae 74
594c2878
JF
75 new_speed = kernel_get_speed(ifp, &error);
76
77 /* error may indicate vrf not available or
78 * interfaces not available.
79 * note that loopback & virtual interfaces can return 0 as speed
80 */
81 if (error < 0)
cc9f21da 82 return;
594c2878 83
dc7b3cae 84 if (new_speed != ifp->speed) {
15569c58
DA
85 zlog_info("%s: %s old speed: %u new speed: %u", __func__,
86 ifp->name, ifp->speed, new_speed);
dc7b3cae
DS
87 ifp->speed = new_speed;
88 if_add_update(ifp);
8f08b1cc 89 changed = true;
dc7b3cae
DS
90 }
91
e8b3a2f7 92 if (changed || new_speed == UINT32_MAX) {
fbc83b9a
DS
93#define SPEED_UPDATE_SLEEP_TIME 5
94#define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME)
95 /*
96 * Some interfaces never actually have an associated speed
97 * with them ( I am looking at you bridges ).
98 * So instead of iterating forever, let's give the
99 * system 4 minutes to try to figure out the speed
100 * if after that it it's probably never going to become
101 * useful.
102 * Since I don't know all the wonderful types of interfaces
103 * that may come into existence in the future I am going
104 * to not update the system to keep track of that. This
105 * is far simpler to just stop trying after 4 minutes
106 */
107 if (new_speed == UINT32_MAX &&
108 zif->speed_update_count == SPEED_UPDATE_COUNT_MAX)
109 return;
110
111 zif->speed_update_count++;
112 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp,
113 SPEED_UPDATE_SLEEP_TIME, &zif->speed_update);
e8b3a2f7
DS
114 thread_ignore_late_timer(zif->speed_update);
115 }
dc7b3cae
DS
116}
117
d62a17ae 118static void zebra_if_node_destroy(route_table_delegate_t *delegate,
119 struct route_table *table,
120 struct route_node *node)
58ac32e2 121{
d62a17ae 122 if (node->info)
6a154c88 123 list_delete((struct list **)&node->info);
d62a17ae 124 route_node_destroy(delegate, table, node);
58ac32e2
RW
125}
126
fe593b78
SW
127static void zebra_if_nhg_dependents_free(struct zebra_if *zebra_if)
128{
37c6708b 129 nhg_connected_tree_free(&zebra_if->nhg_dependents);
fe593b78
SW
130}
131
132static void zebra_if_nhg_dependents_init(struct zebra_if *zebra_if)
133{
37c6708b 134 nhg_connected_tree_init(&zebra_if->nhg_dependents);
fe593b78
SW
135}
136
137
58ac32e2 138route_table_delegate_t zebra_if_table_delegate = {
d62a17ae 139 .create_node = route_node_create,
140 .destroy_node = zebra_if_node_destroy};
58ac32e2 141
718e3744 142/* Called when new interface is added. */
d62a17ae 143static int if_zebra_new_hook(struct interface *ifp)
144{
145 struct zebra_if *zebra_if;
146
8e59a402 147 zebra_if = XCALLOC(MTYPE_ZINFO, sizeof(struct zebra_if));
ce5160c0 148 zebra_if->ifp = ifp;
d62a17ae 149
150 zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
151 zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
602fea61 152
fe593b78 153 zebra_if_nhg_dependents_init(zebra_if);
602fea61 154
d62a17ae 155 zebra_ptm_if_init(zebra_if);
156
157 ifp->ptm_enable = zebra_ptm_get_enable_state();
158#if defined(HAVE_RTADV)
159 {
160 /* Set default router advertise values. */
161 struct rtadvconf *rtadv;
162
163 rtadv = &zebra_if->rtadv;
164
165 rtadv->AdvSendAdvertisements = 0;
166 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
167 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
168 rtadv->AdvIntervalTimer = 0;
169 rtadv->AdvManagedFlag = 0;
170 rtadv->AdvOtherConfigFlag = 0;
171 rtadv->AdvHomeAgentFlag = 0;
172 rtadv->AdvLinkMTU = 0;
173 rtadv->AdvReachableTime = 0;
174 rtadv->AdvRetransTimer = 0;
fae01935 175 rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
637f95bf
DS
176 memset(&rtadv->lastadvcurhoplimit, 0,
177 sizeof(rtadv->lastadvcurhoplimit));
178 memset(&rtadv->lastadvmanagedflag, 0,
179 sizeof(rtadv->lastadvmanagedflag));
180 memset(&rtadv->lastadvotherconfigflag, 0,
181 sizeof(rtadv->lastadvotherconfigflag));
182 memset(&rtadv->lastadvreachabletime, 0,
183 sizeof(rtadv->lastadvreachabletime));
184 memset(&rtadv->lastadvretranstimer, 0,
185 sizeof(rtadv->lastadvretranstimer));
d62a17ae 186 rtadv->AdvDefaultLifetime =
187 -1; /* derive from MaxRtrAdvInterval */
188 rtadv->HomeAgentPreference = 0;
189 rtadv->HomeAgentLifetime =
190 -1; /* derive from AdvDefaultLifetime */
191 rtadv->AdvIntervalOption = 0;
adee8f21 192 rtadv->UseFastRexmit = true;
d62a17ae 193 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
194
195 rtadv->AdvPrefixList = list_new();
3eb4fbb0
LS
196 rtadv->AdvRDNSSList = list_new();
197 rtadv->AdvDNSSLList = list_new();
d62a17ae 198 }
8da4e946 199#endif /* HAVE_RTADV */
718e3744 200
ee98d1f1
DS
201 memset(&zebra_if->neigh_mac[0], 0, 6);
202
d62a17ae 203 /* Initialize installed address chains tree. */
204 zebra_if->ipv4_subnets =
205 route_table_init_with_delegate(&zebra_if_table_delegate);
eef1fe11 206
d62a17ae 207 ifp->info = zebra_if;
dc7b3cae
DS
208
209 /*
210 * Some platforms are telling us that the interface is
211 * up and ready to go. When we check the speed we
212 * sometimes get the wrong value. Wait a couple
213 * of seconds and ask again. Hopefully it's all settled
214 * down upon startup.
215 */
fbc83b9a 216 zebra_if->speed_update_count = 0;
3801e764 217 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15,
996c9314 218 &zebra_if->speed_update);
e8b3a2f7
DS
219 thread_ignore_late_timer(zebra_if->speed_update);
220
d62a17ae 221 return 0;
718e3744 222}
223
80286aa5 224static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
e22e8001 225{
80286aa5 226 zebra_nhg_check_valid(nhe);
2472d3e8
MS
227 if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) {
228 /* If we're in shutdown, this interface event needs to clean
229 * up installed NHGs, so don't clear that flag directly.
230 */
231 if (!zrouter.in_shutdown)
232 UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
233 }
80286aa5 234}
e22e8001 235
80286aa5
SW
236static void if_down_nhg_dependents(const struct interface *ifp)
237{
238 struct nhg_connected *rb_node_dep = NULL;
239 struct zebra_if *zif = (struct zebra_if *)ifp->info;
240
241 frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep)
242 if_nhg_dependents_check_valid(rb_node_dep->nhe);
243}
244
245static void if_nhg_dependents_release(const struct interface *ifp)
246{
247 struct nhg_connected *rb_node_dep = NULL;
248 struct zebra_if *zif = (struct zebra_if *)ifp->info;
249
250 frr_each(nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
251 rb_node_dep->nhe->ifp = NULL; /* Null it out */
252 if_nhg_dependents_check_valid(rb_node_dep->nhe);
e22e8001
SW
253 }
254}
255
718e3744 256/* Called when interface is deleted. */
d62a17ae 257static int if_zebra_delete_hook(struct interface *ifp)
718e3744 258{
d62a17ae 259 struct zebra_if *zebra_if;
eef1fe11 260
d62a17ae 261 if (ifp->info) {
262 zebra_if = ifp->info;
3f6d6a5d 263
d62a17ae 264 /* Free installed address chains tree. */
265 if (zebra_if->ipv4_subnets)
266 route_table_finish(zebra_if->ipv4_subnets);
267#if defined(HAVE_RTADV)
3f6d6a5d 268
d62a17ae 269 struct rtadvconf *rtadv;
eef1fe11 270
d62a17ae 271 rtadv = &zebra_if->rtadv;
6a154c88 272 list_delete(&rtadv->AdvPrefixList);
3eb4fbb0
LS
273 list_delete(&rtadv->AdvRDNSSList);
274 list_delete(&rtadv->AdvDNSSLList);
d62a17ae 275#endif /* HAVE_RTADV */
eef1fe11 276
ce5160c0 277 zebra_evpn_if_cleanup(zebra_if);
8b07f173 278 zebra_evpn_mac_ifp_del(ifp);
ce5160c0 279
e22e8001 280 if_nhg_dependents_release(ifp);
fe593b78 281 zebra_if_nhg_dependents_free(zebra_if);
602fea61 282
ba5165ec 283 XFREE(MTYPE_TMP, zebra_if->desc);
fe593b78 284
dc7b3cae
DS
285 THREAD_OFF(zebra_if->speed_update);
286
8e59a402 287 XFREE(MTYPE_ZINFO, zebra_if);
d62a17ae 288 }
289
290 return 0;
eef1fe11 291}
292
12f6fb97 293/* Build the table key */
d7c0a89a 294static void if_build_key(uint32_t ifindex, struct prefix *p)
12f6fb97 295{
d62a17ae 296 p->family = AF_INET;
297 p->prefixlen = IPV4_MAX_BITLEN;
298 p->u.prefix4.s_addr = ifindex;
12f6fb97
DS
299}
300
301/* Link an interface in a per NS interface tree */
d62a17ae 302struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
12f6fb97 303{
d62a17ae 304 struct prefix p;
305 struct route_node *rn;
12f6fb97 306
d62a17ae 307 if (ifp->ifindex == IFINDEX_INTERNAL)
308 return NULL;
12f6fb97 309
d62a17ae 310 if_build_key(ifp->ifindex, &p);
311 rn = route_node_get(ns->if_table, &p);
312 if (rn->info) {
313 ifp = (struct interface *)rn->info;
314 route_unlock_node(rn); /* get */
315 return ifp;
316 }
12f6fb97 317
d62a17ae 318 rn->info = ifp;
319 ifp->node = rn;
12f6fb97 320
d62a17ae 321 return ifp;
12f6fb97
DS
322}
323
324/* Delete a VRF. This is called in vrf_terminate(). */
d62a17ae 325void if_unlink_per_ns(struct interface *ifp)
12f6fb97 326{
d62a17ae 327 ifp->node->info = NULL;
328 route_unlock_node(ifp->node);
329 ifp->node = NULL;
12f6fb97
DS
330}
331
332/* Look up an interface by identifier within a NS */
d62a17ae 333struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns,
d7c0a89a 334 uint32_t ifindex)
d62a17ae 335{
336 struct prefix p;
337 struct route_node *rn;
338 struct interface *ifp = NULL;
339
340 if_build_key(ifindex, &p);
341 rn = route_node_lookup(ns->if_table, &p);
342 if (rn) {
343 ifp = (struct interface *)rn->info;
344 route_unlock_node(rn); /* lookup */
345 }
346 return ifp;
12f6fb97
DS
347}
348
b8af3fbb 349/* Look up an interface by name within a NS */
d62a17ae 350struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns,
351 const char *ifname)
b8af3fbb 352{
d62a17ae 353 struct route_node *rn;
354 struct interface *ifp;
b8af3fbb 355
d62a17ae 356 for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
357 ifp = (struct interface *)rn->info;
fc341a97
PG
358 if (ifp && strcmp(ifp->name, ifname) == 0) {
359 route_unlock_node(rn);
d62a17ae 360 return (ifp);
fc341a97 361 }
d62a17ae 362 }
b8af3fbb 363
d62a17ae 364 return NULL;
b8af3fbb
RW
365}
366
d62a17ae 367const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)
a815b788 368{
d62a17ae 369 struct interface *ifp;
a815b788 370
d62a17ae 371 return ((ifp = if_lookup_by_index_per_ns(zns, ifindex)) != NULL)
372 ? ifp->name
373 : "unknown";
a815b788 374}
12f6fb97 375
eef1fe11 376/* Tie an interface address to its derived subnet list of addresses. */
d62a17ae 377int if_subnet_add(struct interface *ifp, struct connected *ifc)
378{
379 struct route_node *rn;
380 struct zebra_if *zebra_if;
381 struct prefix cp;
382 struct list *addr_list;
383
384 assert(ifp && ifp->info && ifc);
385 zebra_if = ifp->info;
386
387 /* Get address derived subnet node and associated address list, while
388 marking
389 address secondary attribute appropriately. */
abffde07 390 cp = *CONNECTED_PREFIX(ifc);
d62a17ae 391 apply_mask(&cp);
392 rn = route_node_get(zebra_if->ipv4_subnets, &cp);
393
394 if ((addr_list = rn->info))
395 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
396 else {
397 UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
398 rn->info = addr_list = list_new();
399 route_lock_node(rn);
400 }
401
402 /* Tie address at the tail of address list. */
403 listnode_add(addr_list, ifc);
404
405 /* Return list element count. */
406 return (addr_list->count);
eef1fe11 407}
408
409/* Untie an interface address from its derived subnet list of addresses. */
d62a17ae 410int if_subnet_delete(struct interface *ifp, struct connected *ifc)
411{
412 struct route_node *rn;
413 struct zebra_if *zebra_if;
414 struct list *addr_list;
abffde07 415 struct prefix cp;
d62a17ae 416
417 assert(ifp && ifp->info && ifc);
418 zebra_if = ifp->info;
419
abffde07
DL
420 cp = *CONNECTED_PREFIX(ifc);
421 apply_mask(&cp);
422
d62a17ae 423 /* Get address derived subnet node. */
abffde07 424 rn = route_node_lookup(zebra_if->ipv4_subnets, &cp);
d62a17ae 425 if (!(rn && rn->info)) {
e914ccbe 426 flog_warn(EC_ZEBRA_REMOVE_ADDR_UNKNOWN_SUBNET,
3efd0893 427 "Trying to remove an address from an unknown subnet. (please report this bug)");
d62a17ae 428 return -1;
429 }
430 route_unlock_node(rn);
431
432 /* Untie address from subnet's address list. */
433 addr_list = rn->info;
434
435 /* Deleting an address that is not registered is a bug.
436 * In any case, we shouldn't decrement the lock counter if the address
437 * is unknown. */
438 if (!listnode_lookup(addr_list, ifc)) {
9df414fe 439 flog_warn(
e914ccbe 440 EC_ZEBRA_REMOVE_UNREGISTERED_ADDR,
3efd0893 441 "Trying to remove an address from a subnet where it is not currently registered. (please report this bug)");
d62a17ae 442 return -1;
443 }
444
445 listnode_delete(addr_list, ifc);
446 route_unlock_node(rn);
447
448 /* Return list element count, if not empty. */
449 if (addr_list->count) {
450 /* If deleted address is primary, mark subsequent one as such
451 * and distribute. */
452 if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) {
453 ifc = listgetdata(
454 (struct listnode *)listhead(addr_list));
455 zebra_interface_address_delete_update(ifp, ifc);
456 UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
457 /* XXX: Linux kernel removes all the secondary addresses
458 * when the primary
459 * address is removed. We could try to work around that,
460 * though this is
461 * non-trivial. */
462 zebra_interface_address_add_update(ifp, ifc);
463 }
464
465 return addr_list->count;
466 }
467
468 /* Otherwise, free list and route node. */
6a154c88 469 list_delete(&addr_list);
d62a17ae 470 rn->info = NULL;
471 route_unlock_node(rn);
472
473 return 0;
718e3744 474}
475
5c78b3d0 476/* if_flags_mangle: A place for hacks that require mangling
477 * or tweaking the interface flags.
478 *
479 * ******************** Solaris flags hacks **************************
480 *
481 * Solaris IFF_UP flag reflects only the primary interface as the
d62a17ae 482 * routing socket only sends IFINFO for the primary interface. Hence
483 * ~IFF_UP does not per se imply all the logical interfaces are also
5c78b3d0 484 * down - which we only know of as addresses. Instead we must determine
d62a17ae 485 * whether the interface really is up or not according to how many
5c78b3d0 486 * addresses are still attached. (Solaris always sends RTM_DELADDR if
487 * an interface, logical or not, goes ~IFF_UP).
488 *
489 * Ie, we mangle IFF_UP to *additionally* reflect whether or not there
490 * are addresses left in struct connected, not just the actual underlying
491 * IFF_UP flag.
492 *
493 * We must hence remember the real state of IFF_UP, which we do in
494 * struct zebra_if.primary_state.
495 *
496 * Setting IFF_UP within zebra to administratively shutdown the
497 * interface will affect only the primary interface/address on Solaris.
498 ************************End Solaris flags hacks ***********************
499 */
d62a17ae 500static void if_flags_mangle(struct interface *ifp, uint64_t *newflags)
5c78b3d0 501{
cae8bc96 502 return;
5c78b3d0 503}
504
505/* Update the flags field of the ifp with the new flag set provided.
506 * Take whatever actions are required for any changes in flags we care
507 * about.
508 *
509 * newflags should be the raw value, as obtained from the OS.
510 */
d62a17ae 511void if_flags_update(struct interface *ifp, uint64_t newflags)
512{
513 if_flags_mangle(ifp, &newflags);
514
515 if (if_is_no_ptm_operative(ifp)) {
516 /* operative -> inoperative? */
517 ifp->flags = newflags;
518 if (!if_is_operative(ifp))
519 if_down(ifp);
520 } else {
521 /* inoperative -> operative? */
522 ifp->flags = newflags;
523 if (if_is_operative(ifp))
8b48cdb9 524 if_up(ifp, true);
d62a17ae 525 }
5c78b3d0 526}
527
718e3744 528/* Wake up configured address if it is not in current kernel
529 address. */
09268680 530void if_addr_wakeup(struct interface *ifp)
d62a17ae 531{
532 struct listnode *node, *nnode;
533 struct connected *ifc;
534 struct prefix *p;
64168803 535 enum zebra_dplane_result dplane_res;
eef1fe11 536
d62a17ae 537 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
538 p = ifc->address;
718e3744 539
d62a17ae 540 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)
541 && !CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)) {
542 /* Address check. */
543 if (p->family == AF_INET) {
544 if (!if_is_up(ifp)) {
545 /* Assume zebra is configured like
546 * following:
547 *
548 * interface gre0
549 * ip addr 192.0.2.1/24
550 * !
551 *
552 * As soon as zebra becomes first aware
553 * that gre0 exists in the
554 * kernel, it will set gre0 up and
555 * configure its addresses.
556 *
557 * (This may happen at startup when the
558 * interface already exists
559 * or during runtime when the interface
560 * is added to the kernel)
561 *
562 * XXX: IRDP code is calling here via
563 * if_add_update - this seems
564 * somewhat weird.
565 * XXX: RUNNING is not a settable flag
566 * on any system
567 * I (paulj) am aware of.
9d303b37 568 */
d62a17ae 569 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
570 if_refresh(ifp);
571 }
572
64168803
MS
573 dplane_res = dplane_intf_addr_set(ifp, ifc);
574 if (dplane_res ==
575 ZEBRA_DPLANE_REQUEST_FAILURE) {
9df414fe 576 flog_err_sys(
e914ccbe 577 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
d62a17ae 578 "Can't set interface's address: %s",
64168803 579 dplane_res2str(dplane_res));
d62a17ae 580 continue;
581 }
582
583 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
584 /* The address will be advertised to zebra
585 * clients when the notification
586 * from the kernel has been received.
587 * It will also be added to the interface's
588 * subnet list then. */
589 }
590 if (p->family == AF_INET6) {
591 if (!if_is_up(ifp)) {
592 /* See long comment above */
593 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
594 if_refresh(ifp);
595 }
596
0f1f6ce4
MS
597
598 dplane_res = dplane_intf_addr_set(ifp, ifc);
599 if (dplane_res ==
600 ZEBRA_DPLANE_REQUEST_FAILURE) {
9df414fe 601 flog_err_sys(
e914ccbe 602 EC_ZEBRA_IFACE_ADDR_ADD_FAILED,
d62a17ae 603 "Can't set interface's address: %s",
0f1f6ce4 604 dplane_res2str(dplane_res));
d62a17ae 605 continue;
606 }
607
608 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
609 /* The address will be advertised to zebra
610 * clients when the notification
611 * from the kernel has been received. */
612 }
718e3744 613 }
718e3744 614 }
718e3744 615}
616
617/* Handle interface addition */
d62a17ae 618void if_add_update(struct interface *ifp)
718e3744 619{
d62a17ae 620 struct zebra_if *if_data;
fe533c56 621 struct zebra_ns *zns;
096f7609 622 struct zebra_vrf *zvrf = ifp->vrf->info;
48b33aaf 623
009f8ad5
PG
624 /* case interface populate before vrf enabled */
625 if (zvrf->zns)
626 zns = zvrf->zns;
fe533c56
PG
627 else
628 zns = zebra_ns_lookup(NS_DEFAULT);
629 if_link_per_ns(zns, ifp);
d62a17ae 630 if_data = ifp->info;
631 assert(if_data);
06b420a4 632
d62a17ae 633 if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
634 if_set_flags(ifp, IFF_MULTICAST);
635 else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF)
636 if_unset_flags(ifp, IFF_MULTICAST);
48b33aaf 637
d62a17ae 638 zebra_ptm_if_set_ptm_state(ifp, if_data);
986aa00f 639
d62a17ae 640 zebra_interface_add_update(ifp);
718e3744 641
d62a17ae 642 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
643 SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
718e3744 644
0af35d90 645 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) {
c479e756 646 if (IS_ZEBRA_DEBUG_KERNEL) {
d62a17ae 647 zlog_debug(
3efd0893 648 "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.",
096f7609
IR
649 ifp->name, ifp->vrf->name,
650 ifp->vrf->vrf_id, ifp->ifindex);
c479e756
DS
651 }
652
d62a17ae 653 return;
654 }
bfac8dcd 655
d62a17ae 656 if_addr_wakeup(ifp);
718e3744 657
d62a17ae 658 if (IS_ZEBRA_DEBUG_KERNEL)
659 zlog_debug(
c479e756 660 "interface %s vrf %s(%u) index %d becomes active.",
096f7609 661 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
c479e756 662 ifp->ifindex);
c3c04063 663
d62a17ae 664 } else {
665 if (IS_ZEBRA_DEBUG_KERNEL)
c479e756 666 zlog_debug("interface %s vrf %s(%u) index %d is added.",
096f7609
IR
667 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
668 ifp->ifindex);
d62a17ae 669 }
718e3744 670}
671
c8e264b6 672/* Install connected routes corresponding to an interface. */
d62a17ae 673static void if_install_connected(struct interface *ifp)
674{
675 struct listnode *node;
676 struct listnode *next;
677 struct connected *ifc;
d62a17ae 678
679 if (ifp->connected) {
680 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
681 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
682 zebra_interface_address_add_update(ifp, ifc);
683
ae87977c 684 connected_up(ifp, ifc);
d62a17ae 685 }
c8e264b6 686 }
c8e264b6 687}
688
689/* Uninstall connected routes corresponding to an interface. */
d62a17ae 690static void if_uninstall_connected(struct interface *ifp)
691{
692 struct listnode *node;
693 struct listnode *next;
694 struct connected *ifc;
d62a17ae 695
696 if (ifp->connected) {
697 for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) {
d62a17ae 698 zebra_interface_address_delete_update(ifp, ifc);
11461c63 699 connected_down(ifp, ifc);
d62a17ae 700 }
c8e264b6 701 }
c8e264b6 702}
718e3744 703
c8e264b6 704/* Uninstall and delete connected routes corresponding to an interface. */
705/* TODO - Check why IPv4 handling here is different from install or if_down */
d62a17ae 706static void if_delete_connected(struct interface *ifp)
707{
708 struct connected *ifc;
a3008857 709 struct prefix cp;
d62a17ae 710 struct route_node *rn;
711 struct zebra_if *zebra_if;
070b4959
DS
712 struct listnode *node;
713 struct listnode *last = NULL;
d62a17ae 714
715 zebra_if = ifp->info;
716
070b4959
DS
717 if (!ifp->connected)
718 return;
d62a17ae 719
996c9314 720 while ((node = (last ? last->next : listhead(ifp->connected)))) {
070b4959 721 ifc = listgetdata(node);
d62a17ae 722
070b4959
DS
723 cp = *CONNECTED_PREFIX(ifc);
724 apply_mask(&cp);
a3008857 725
070b4959 726 if (cp.family == AF_INET
996c9314 727 && (rn = route_node_lookup(zebra_if->ipv4_subnets, &cp))) {
070b4959
DS
728 struct listnode *anode;
729 struct listnode *next;
730 struct listnode *first;
731 struct list *addr_list;
d62a17ae 732
070b4959
DS
733 route_unlock_node(rn);
734 addr_list = (struct list *)rn->info;
d62a17ae 735
070b4959
DS
736 /* Remove addresses, secondaries first. */
737 first = listhead(addr_list);
738 if (first)
d62a17ae 739 for (anode = first->next; anode || first;
740 anode = next) {
741 if (!anode) {
742 anode = first;
743 first = NULL;
744 }
745 next = anode->next;
746
747 ifc = listgetdata(anode);
11461c63 748 connected_down(ifp, ifc);
d62a17ae 749
750 /* XXX: We have to send notifications
751 * here explicitly, because we destroy
752 * the ifc before receiving the
753 * notification about the address being
754 * deleted.
755 */
756 zebra_interface_address_delete_update(
757 ifp, ifc);
758
759 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
760 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
761
762 /* Remove from subnet chain. */
763 list_delete_node(addr_list, anode);
764 route_unlock_node(rn);
765
766 /* Remove from interface address list
767 * (unconditionally). */
768 if (!CHECK_FLAG(ifc->conf,
769 ZEBRA_IFC_CONFIGURED)) {
770 listnode_delete(ifp->connected,
771 ifc);
721c0857 772 connected_free(&ifc);
d62a17ae 773 } else
774 last = node;
775 }
776
070b4959 777 /* Free chain list and respective route node. */
6a154c88 778 list_delete(&addr_list);
070b4959
DS
779 rn->info = NULL;
780 route_unlock_node(rn);
781 } else if (cp.family == AF_INET6) {
782 connected_down(ifp, ifc);
d62a17ae 783
070b4959 784 zebra_interface_address_delete_update(ifp, ifc);
d62a17ae 785
070b4959
DS
786 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
787 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
d62a17ae 788
070b4959 789 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
d62a17ae 790 last = node;
070b4959
DS
791 else {
792 listnode_delete(ifp->connected, ifc);
721c0857 793 connected_free(&ifc);
d62a17ae 794 }
070b4959
DS
795 } else {
796 last = node;
eef1fe11 797 }
718e3744 798 }
c8e264b6 799}
800
801/* Handle an interface delete event */
d62a17ae 802void if_delete_update(struct interface *ifp)
c8e264b6 803{
d62a17ae 804 struct zebra_if *zif;
d2fc8896 805
d62a17ae 806 if (if_is_up(ifp)) {
af4c2728 807 flog_err(
450971aa 808 EC_LIB_INTERFACE,
c479e756 809 "interface %s vrf %s(%u) index %d is still up while being deleted.",
096f7609
IR
810 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
811 ifp->ifindex);
d62a17ae 812 return;
813 }
6675513d 814
7befff57
PG
815 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
816 return;
817
d62a17ae 818 /* Mark interface as inactive */
819 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE);
820
096f7609 821 if (IS_ZEBRA_DEBUG_KERNEL)
c479e756 822 zlog_debug("interface %s vrf %s(%u) index %d is now inactive.",
096f7609 823 ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
c479e756 824 ifp->ifindex);
d62a17ae 825
826 /* Delete connected routes from the kernel. */
827 if_delete_connected(ifp);
828
829 /* Send out notification on interface delete. */
830 zebra_interface_delete_update(ifp);
831
832 if_unlink_per_ns(ifp);
833
834 /* Update ifindex after distributing the delete message. This is in
835 case any client needs to have the old value of ifindex available
836 while processing the deletion. Each client daemon is responsible
837 for setting ifindex to IFINDEX_INTERNAL after processing the
838 interface deletion message. */
ff880b78 839 if_set_index(ifp, IFINDEX_INTERNAL);
d62a17ae 840 ifp->node = NULL;
841
842 /* if the ifp is in a vrf, move it to default so vrf can be deleted if
ee2f2c23
TC
843 * desired. This operation is not done for netns implementation to avoid
844 * collision with interface with the same name in the default vrf (can
845 * occur with this implementation whereas it is not possible with
846 * vrf-lite).
847 */
096f7609 848 if (ifp->vrf->vrf_id && !vrf_is_backend_netns())
d62a17ae 849 if_handle_vrf_change(ifp, VRF_DEFAULT);
850
851 /* Reset some zebra interface params to default values. */
852 zif = ifp->info;
853 if (zif) {
854 zif->zif_type = ZEBRA_IF_OTHER;
855 zif->zif_slave_type = ZEBRA_IF_SLAVE_NONE;
856 memset(&zif->l2info, 0, sizeof(union zebra_l2if_info));
857 memset(&zif->brslave_info, 0,
858 sizeof(struct zebra_l2info_brslave));
ce5160c0 859 zebra_evpn_if_cleanup(zif);
8b07f173 860 zebra_evpn_mac_ifp_del(ifp);
d62a17ae 861 }
1d311a05
DS
862
863 if (!ifp->configured) {
864 if (IS_ZEBRA_DEBUG_KERNEL)
865 zlog_debug("interface %s is being deleted from the system",
866 ifp->name);
f609709a 867 if_delete(&ifp);
1d311a05 868 }
718e3744 869}
870
c8e264b6 871/* VRF change for an interface */
d62a17ae 872void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
c8e264b6 873{
d62a17ae 874 vrf_id_t old_vrf_id;
c8e264b6 875
096f7609 876 old_vrf_id = ifp->vrf->vrf_id;
c8e264b6 877
d62a17ae 878 /* Uninstall connected routes. */
879 if_uninstall_connected(ifp);
c8e264b6 880
d62a17ae 881 /* Delete any IPv4 neighbors created to implement RFC 5549 */
882 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
c8e264b6 883
d62a17ae 884 /* Delete all neighbor addresses learnt through IPv6 RA */
885 if_down_del_nbr_connected(ifp);
c8e264b6 886
d62a17ae 887 /* Send out notification on interface VRF change. */
888 /* This is to issue an UPDATE or a DELETE, as appropriate. */
889 zebra_interface_vrf_update_del(ifp, vrf_id);
c8e264b6 890
d62a17ae 891 /* update VRF */
a36898e7 892 if_update_to_new_vrf(ifp, vrf_id);
c8e264b6 893
d62a17ae 894 /* Send out notification on interface VRF change. */
895 /* This is to issue an ADD, if needed. */
896 zebra_interface_vrf_update_add(ifp, old_vrf_id);
c8e264b6 897
d62a17ae 898 /* Install connected routes (in new VRF). */
4030583f 899 if (if_is_operative(ifp))
900 if_install_connected(ifp);
c8e264b6 901}
902
d7c0a89a 903static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
5c610faf 904{
d62a17ae 905 mac[0] = address->s6_addr[8] ^ 0x02;
906 mac[1] = address->s6_addr[9];
907 mac[2] = address->s6_addr[10];
908 mac[3] = address->s6_addr[13];
909 mac[4] = address->s6_addr[14];
910 mac[5] = address->s6_addr[15];
5c610faf
DS
911}
912
ee98d1f1
DS
913void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
914 char mac[6],
915 struct in6_addr *address,
916 int add)
5c610faf 917{
096f7609 918 struct zebra_vrf *zvrf = ifp->vrf->info;
20089ae2 919 struct zebra_if *zif = ifp->info;
d62a17ae 920 char buf[16] = "169.254.0.1";
921 struct in_addr ipv4_ll;
5895d33f 922 ns_id_t ns_id;
5c610faf 923
d62a17ae 924 inet_pton(AF_INET, buf, &ipv4_ll);
5c610faf 925
009f8ad5 926 ns_id = zvrf->zns->ns_id;
d1479ec8 927
a8a4fa89 928 /*
2b6aabe0
QY
929 * Remove and re-add any existing neighbor entry for this address,
930 * since Netlink doesn't currently offer update message types.
f26bc773 931 */
05657ec2
PG
932 kernel_neigh_update(0, ifp->ifindex, (void *)&ipv4_ll.s_addr, mac, 6,
933 ns_id, AF_INET, true);
d1479ec8 934
2b6aabe0
QY
935 /* Add new neighbor entry.
936 *
937 * We force installation even if current neighbor entry is the same.
938 * Since this function is used to refresh our MAC entries after an
939 * interface flap, if we don't force in our custom entries with their
940 * state set to PERMANENT or REACHABLE then the kernel will attempt to
941 * resolve our leftover entries, fail, mark them unreachable and then
942 * they'll be useless to us.
943 */
944 if (add)
05657ec2
PG
945 kernel_neigh_update(add, ifp->ifindex, (void *)&ipv4_ll.s_addr,
946 mac, 6, ns_id, AF_INET, true);
d1479ec8 947
ee98d1f1 948 memcpy(&zif->neigh_mac[0], &mac[0], 6);
20089ae2
DS
949
950 /*
951 * We need to note whether or not we originated a v6
952 * neighbor entry for this interface. So that when
953 * someone unwisely accidently deletes this entry
954 * we can shove it back in.
955 */
956 zif->v6_2_v4_ll_neigh_entry = !!add;
957 memcpy(&zif->v6_2_v4_ll_addr6, address, sizeof(*address));
958
d62a17ae 959 zvrf->neigh_updates++;
5c610faf
DS
960}
961
ee98d1f1
DS
962void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
963 struct in6_addr *address, int add)
964{
965
966 char mac[6];
967
968 ipv6_ll_address_to_mac(address, (uint8_t *)mac);
969 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
970}
971
d62a17ae 972static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
5c610faf 973{
d62a17ae 974 if (listhead(ifp->nbr_connected)) {
975 struct nbr_connected *nbr_connected;
976 struct listnode *node;
5c610faf 977
d62a17ae 978 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
979 nbr_connected))
980 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
981 ifp, &nbr_connected->address->u.prefix6, 1);
982 }
5c610faf
DS
983}
984
d62a17ae 985void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)
5c610faf 986{
d62a17ae 987 if (listhead(ifp->nbr_connected)) {
988 struct nbr_connected *nbr_connected;
989 struct listnode *node;
5c610faf 990
d62a17ae 991 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
992 nbr_connected))
993 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
994 ifp, &nbr_connected->address->u.prefix6, 0);
995 }
5c610faf
DS
996}
997
d62a17ae 998static void if_down_del_nbr_connected(struct interface *ifp)
a197c47c 999{
d62a17ae 1000 struct nbr_connected *nbr_connected;
1001 struct listnode *node, *nnode;
a197c47c 1002
d62a17ae 1003 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode,
1004 nbr_connected)) {
1005 listnode_delete(ifp->nbr_connected, nbr_connected);
1006 nbr_connected_free(nbr_connected);
1007 }
a197c47c
DS
1008}
1009
fe593b78 1010void if_nhg_dependents_add(struct interface *ifp, struct nhg_hash_entry *nhe)
602fea61 1011{
fe593b78
SW
1012 if (ifp->info) {
1013 struct zebra_if *zif = (struct zebra_if *)ifp->info;
602fea61 1014
37c6708b 1015 nhg_connected_tree_add_nhe(&zif->nhg_dependents, nhe);
fe593b78
SW
1016 }
1017}
602fea61 1018
fe593b78
SW
1019void if_nhg_dependents_del(struct interface *ifp, struct nhg_hash_entry *nhe)
1020{
1021 if (ifp->info) {
1022 struct zebra_if *zif = (struct zebra_if *)ifp->info;
602fea61 1023
37c6708b 1024 nhg_connected_tree_del_nhe(&zif->nhg_dependents, nhe);
fe593b78 1025 }
602fea61
SW
1026}
1027
fe593b78 1028unsigned int if_nhg_dependents_count(const struct interface *ifp)
602fea61 1029{
fe593b78
SW
1030 if (ifp->info) {
1031 struct zebra_if *zif = (struct zebra_if *)ifp->info;
1032
37c6708b 1033 return nhg_connected_tree_count(&zif->nhg_dependents);
fe593b78
SW
1034 }
1035
1036 return 0;
1037}
1038
1039
1040bool if_nhg_dependents_is_empty(const struct interface *ifp)
1041{
1042 if (ifp->info) {
1043 struct zebra_if *zif = (struct zebra_if *)ifp->info;
1044
37c6708b 1045 return nhg_connected_tree_is_empty(&zif->nhg_dependents);
fe593b78
SW
1046 }
1047
1048 return false;
602fea61
SW
1049}
1050
718e3744 1051/* Interface is up. */
8b48cdb9 1052void if_up(struct interface *ifp, bool install_connected)
d62a17ae 1053{
1054 struct zebra_if *zif;
1055 struct interface *link_if;
096f7609 1056 struct zebra_vrf *zvrf = ifp->vrf->info;
d62a17ae 1057
1058 zif = ifp->info;
1059 zif->up_count++;
e36f61b5 1060 frr_timestamp(2, zif->up_last, sizeof(zif->up_last));
d62a17ae 1061
1062 /* Notify the protocol daemons. */
1063 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
e914ccbe 1064 flog_warn(EC_ZEBRA_PTM_NOT_READY,
1d5453d6 1065 "%s: interface %s hasn't passed ptm check",
d62a17ae 1066 __func__, ifp->name);
1067 return;
1068 }
1069 zebra_interface_up_update(ifp);
1070
1071 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
1072
1073#if defined(HAVE_RTADV)
1074 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
1075 if (zif->rtadv.AdvSendAdvertisements
adee8f21
DS
1076 && (zif->rtadv.MaxRtrAdvInterval >= 1000)
1077 && zif->rtadv.UseFastRexmit) {
d62a17ae 1078 zif->rtadv.inFastRexmit = 1;
1079 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
1080 }
9c3bf1ce 1081#endif
6c9678b4 1082
d62a17ae 1083 /* Install connected routes to the kernel. */
8b48cdb9
DS
1084 if (install_connected)
1085 if_install_connected(ifp);
d62a17ae 1086
d62a17ae 1087 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
1088 * are checked to see if (remote) neighbor entries need to be installed
1089 * on them for ARP suppression.
1090 */
1091 if (IS_ZEBRA_IF_VXLAN(ifp))
1092 zebra_vxlan_if_up(ifp);
1093 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1094 link_if = ifp;
1095 zebra_vxlan_svi_up(ifp, link_if);
1096 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
154a3944 1097 link_if = if_lookup_by_index_per_ns(zvrf->zns,
71349e03 1098 zif->link_ifindex);
d62a17ae 1099 if (link_if)
1100 zebra_vxlan_svi_up(ifp, link_if);
077c07cc 1101 } else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
0056f687 1102 zebra_vxlan_macvlan_up(ifp);
077c07cc 1103 }
0056f687 1104
ce5160c0
AK
1105 if (zif->es_info.es)
1106 zebra_evpn_es_if_oper_state_change(zif, true /*up*/);
c36e442c
AK
1107
1108 if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
1109 zebra_evpn_mh_uplink_oper_update(zif);
c490437e
DS
1110
1111 thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
1112 &zif->speed_update);
e8b3a2f7 1113 thread_ignore_late_timer(zif->speed_update);
718e3744 1114}
1115
1116/* Interface goes down. We have to manage different behavior of based
1117 OS. */
d62a17ae 1118void if_down(struct interface *ifp)
1119{
1120 struct zebra_if *zif;
1121 struct interface *link_if;
096f7609 1122 struct zebra_vrf *zvrf = ifp->vrf->info;
d62a17ae 1123
1124 zif = ifp->info;
1125 zif->down_count++;
e36f61b5 1126 frr_timestamp(2, zif->down_last, sizeof(zif->down_last));
d62a17ae 1127
f862383f
SW
1128 if_down_nhg_dependents(ifp);
1129
d62a17ae 1130 /* Handle interface down for specific types for EVPN. Non-VxLAN
1131 * interfaces
1132 * are checked to see if (remote) neighbor entries need to be purged
1133 * for ARP suppression.
1134 */
1135 if (IS_ZEBRA_IF_VXLAN(ifp))
1136 zebra_vxlan_if_down(ifp);
1137 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1138 link_if = ifp;
1139 zebra_vxlan_svi_down(ifp, link_if);
1140 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
154a3944 1141 link_if = if_lookup_by_index_per_ns(zvrf->zns,
71349e03 1142 zif->link_ifindex);
d62a17ae 1143 if (link_if)
1144 zebra_vxlan_svi_down(ifp, link_if);
077c07cc 1145 } else if (IS_ZEBRA_IF_MACVLAN(ifp)) {
0056f687 1146 zebra_vxlan_macvlan_down(ifp);
077c07cc 1147 }
2232a77c 1148
ce5160c0
AK
1149 if (zif->es_info.es)
1150 zebra_evpn_es_if_oper_state_change(zif, false /*up*/);
13d60d35 1151
c36e442c
AK
1152 if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
1153 zebra_evpn_mh_uplink_oper_update(zif);
1154
d62a17ae 1155 /* Notify to the protocol daemons. */
1156 zebra_interface_down_update(ifp);
718e3744 1157
d62a17ae 1158 /* Uninstall connected routes from the kernel. */
1159 if_uninstall_connected(ifp);
718e3744 1160
d62a17ae 1161 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
a197c47c 1162
d62a17ae 1163 /* Delete all neighbor addresses learnt through IPv6 RA */
1164 if_down_del_nbr_connected(ifp);
718e3744 1165}
1166
d62a17ae 1167void if_refresh(struct interface *ifp)
718e3744 1168{
d62a17ae 1169 if_get_flags(ifp);
718e3744 1170}
1171
680c278f
PG
1172void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1173 ns_id_t ns_id)
6675513d 1174{
d62a17ae 1175 struct zebra_if *zif;
6675513d 1176
0e4864ea
PG
1177 if (IS_ZEBRA_IF_VETH(ifp))
1178 return;
d62a17ae 1179 zif = (struct zebra_if *)ifp->info;
1180 zif->link_ifindex = link_ifindex;
680c278f 1181 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
d62a17ae 1182 link_ifindex);
6675513d 1183}
1184
98efddf1
DS
1185/*
1186 * during initial link dump kernel does not order lower devices before
1187 * upper devices so we need to fixup link dependencies at the end of dump
1188 */
357b150d 1189void zebra_if_update_all_links(struct zebra_ns *zns)
520ebf72
AK
1190{
1191 struct route_node *rn;
1192 struct interface *ifp;
1193 struct zebra_if *zif;
520ebf72
AK
1194
1195 if (IS_ZEBRA_DEBUG_KERNEL)
1196 zlog_info("fixup link dependencies");
1197
357b150d 1198 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
520ebf72
AK
1199 ifp = (struct interface *)rn->info;
1200 if (!ifp)
1201 continue;
1202 zif = ifp->info;
c36e442c
AK
1203 /* update bond-member to bond linkages */
1204 if ((IS_ZEBRA_IF_BOND_SLAVE(ifp))
1205 && (zif->bondslave_info.bond_ifindex != IFINDEX_INTERNAL)
1206 && !zif->bondslave_info.bond_if) {
1207 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
1208 zlog_debug("bond mbr %s map to bond %d",
1209 zif->ifp->name,
1210 zif->bondslave_info.bond_ifindex);
096f7609 1211 zebra_l2_map_slave_to_bond(zif, ifp->vrf->vrf_id);
c36e442c
AK
1212 }
1213
1214 /* update SVI linkages */
520ebf72 1215 if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
357b150d
PG
1216 zif->link = if_lookup_by_index_per_ns(
1217 zns, zif->link_ifindex);
520ebf72
AK
1218 if (IS_ZEBRA_DEBUG_KERNEL)
1219 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1220 ifp->name, ifp->ifindex,
1221 zif->link?zif->link->name:"unk",
1222 zif->link_ifindex);
1223 }
243b74ed
AK
1224
1225 /* Update VLAN<=>SVI map */
1226 if (IS_ZEBRA_IF_VLAN(ifp))
1227 zebra_evpn_acc_bd_svi_set(zif, NULL,
1228 !!if_is_operative(ifp));
520ebf72
AK
1229 }
1230}
1231
c3bd894e
QY
1232void zebra_if_set_protodown(struct interface *ifp, bool down)
1233{
d8d78e2c 1234#ifdef HAVE_NETLINK
c3bd894e 1235 netlink_protodown(ifp, down);
d8d78e2c
QY
1236#else
1237 zlog_warn("Protodown is not supported on this platform");
1238#endif
c3bd894e 1239}
d5a5c8f0 1240
c6f55fb2
MS
1241/*
1242 * Handle an interface addr event based on info in a dplane context object.
1243 * This runs in the main pthread, using the info in the context object to
1244 * modify an interface.
1245 */
d166308b
MS
1246void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx)
1247{
c6f55fb2
MS
1248 struct interface *ifp;
1249 uint8_t flags = 0;
1250 const char *label = NULL;
1251 ns_id_t ns_id;
1252 struct zebra_ns *zns;
1253 uint32_t metric = METRIC_MAX;
1254 ifindex_t ifindex;
1255 const struct prefix *addr, *dest = NULL;
1256 enum dplane_op_e op;
1257
1258 op = dplane_ctx_get_op(ctx);
1259 ns_id = dplane_ctx_get_ns_id(ctx);
1260
1261 zns = zebra_ns_lookup(ns_id);
1262 if (zns == NULL) {
1263 /* No ns - deleted maybe? */
1264 if (IS_ZEBRA_DEBUG_KERNEL)
1265 zlog_debug("%s: can't find zns id %u", __func__, ns_id);
1266 goto done;
1267 }
1268
1269 ifindex = dplane_ctx_get_ifindex(ctx);
1270
1271 ifp = if_lookup_by_index_per_ns(zns, ifindex);
1272 if (ifp == NULL) {
1273 if (IS_ZEBRA_DEBUG_KERNEL)
1274 zlog_debug("%s: can't find ifp at nsid %u index %d",
1275 __func__, ns_id, ifindex);
1276 goto done;
1277 }
1278
1279 addr = dplane_ctx_get_intf_addr(ctx);
1280
1281 if (IS_ZEBRA_DEBUG_KERNEL)
1282 zlog_debug("%s: %s: ifindex %u, addr %pFX", __func__,
1283 dplane_op2str(op), ifindex, addr);
1284
1285 /* Is there a peer or broadcast address? */
1286 dest = dplane_ctx_get_intf_dest(ctx);
1287 if (dest->prefixlen == 0)
1288 dest = NULL;
1289
1290 if (dplane_ctx_intf_is_connected(ctx))
1291 SET_FLAG(flags, ZEBRA_IFA_PEER);
1292
1293 /* Flags. */
1294 if (dplane_ctx_intf_is_secondary(ctx))
1295 SET_FLAG(flags, ZEBRA_IFA_SECONDARY);
1296
1297 /* Label? */
1298 if (dplane_ctx_intf_has_label(ctx))
1299 label = dplane_ctx_get_intf_label(ctx);
1300
1301 if (label && strcmp(ifp->name, label) == 0)
1302 label = NULL;
1303
1304 metric = dplane_ctx_get_intf_metric(ctx);
1305
1306 /* Register interface address to the interface. */
1307 if (addr->family == AF_INET) {
1308 if (op == DPLANE_OP_INTF_ADDR_ADD)
1309 connected_add_ipv4(
1310 ifp, flags, &addr->u.prefix4, addr->prefixlen,
1311 dest ? &dest->u.prefix4 : NULL, label, metric);
1312 else if (CHECK_FLAG(flags, ZEBRA_IFA_PEER)) {
1313 /* Delete with a peer address */
1314 connected_delete_ipv4(ifp, flags, &addr->u.prefix4,
1315 addr->prefixlen,
1316 &dest->u.prefix4);
1317 } else
1318 connected_delete_ipv4(ifp, flags, &addr->u.prefix4,
1319 addr->prefixlen, NULL);
1320 }
1321
1322 if (addr->family == AF_INET6) {
1323 if (op == DPLANE_OP_INTF_ADDR_ADD) {
1324 connected_add_ipv6(ifp, flags, &addr->u.prefix6,
1325 dest ? &dest->u.prefix6 : NULL,
1326 addr->prefixlen, label, metric);
1327 } else
1328 connected_delete_ipv6(ifp, &addr->u.prefix6, NULL,
1329 addr->prefixlen);
1330 }
1331
1332 /*
1333 * Linux kernel does not send route delete on interface down/addr del
1334 * so we have to re-process routes it owns (i.e. kernel routes)
1335 */
1336 if (op != DPLANE_OP_INTF_ADDR_ADD)
1337 rib_update(RIB_UPDATE_KERNEL);
1338
1339done:
1340 /* We're responsible for the ctx object */
d166308b 1341 dplane_ctx_fini(&ctx);
d166308b
MS
1342}
1343
cd787a8a
MS
1344/*
1345 * Handle netconf change from a dplane context object; runs in the main
1346 * pthread so it can update zebra data structs.
1347 */
1348int zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx)
1349{
1350 struct zebra_ns *zns;
1351 struct interface *ifp;
1352 struct zebra_if *zif;
1353 enum dplane_netconf_status_e mpls;
1354 int ret = 0;
1355
1356 zns = zebra_ns_lookup(dplane_ctx_get_netconf_ns_id(ctx));
1357 if (zns == NULL) {
1358 ret = -1;
1359 goto done;
1360 }
1361
1362 ifp = if_lookup_by_index_per_ns(zns,
1363 dplane_ctx_get_netconf_ifindex(ctx));
1364 if (ifp == NULL) {
1365 ret = -1;
1366 goto done;
1367 }
1368
1369 zif = ifp->info;
1370 if (zif == NULL) {
1371 ret = -1;
1372 goto done;
1373 }
1374
1375 mpls = dplane_ctx_get_netconf_mpls(ctx);
1376
1377 if (mpls == DPLANE_NETCONF_STATUS_ENABLED)
1378 zif->mpls = true;
1379 else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
1380 zif->mpls = false;
1381
1382 if (IS_ZEBRA_DEBUG_KERNEL)
1383 zlog_debug("%s: if %s, ifindex %d, mpls %s",
1384 __func__, ifp->name, ifp->ifindex,
1385 (zif->mpls ? "ON" : "OFF"));
1386
1387done:
1388 /* Free the context */
1389 dplane_ctx_fini(&ctx);
1390
1391 return ret;
1392}
1393
718e3744 1394/* Dump if address information to vty. */
c15dc24f
RW
1395static void connected_dump_vty(struct vty *vty, json_object *json,
1396 struct connected *connected)
718e3744 1397{
d62a17ae 1398 struct prefix *p;
c15dc24f 1399 json_object *json_addr = NULL;
718e3744 1400
d62a17ae 1401 /* Print interface address. */
1402 p = connected->address;
c15dc24f
RW
1403
1404 if (json) {
1405 json_addr = json_object_new_object();
1406 json_object_array_add(json, json_addr);
44991dc1 1407 json_object_string_addf(json_addr, "address", "%pFX", p);
c15dc24f
RW
1408 } else {
1409 vty_out(vty, " %s %pFX", prefix_family_str(p), p);
1410 }
718e3744 1411
d62a17ae 1412 /* If there is destination address, print it. */
0f3af738 1413 if (CONNECTED_PEER(connected) && connected->destination) {
c15dc24f 1414 if (json) {
44991dc1
DA
1415 json_object_string_addf(json_addr, "peer", "%pFX",
1416 connected->destination);
c15dc24f
RW
1417 } else {
1418 vty_out(vty, " peer %pFX", connected->destination);
1419 }
d62a17ae 1420 }
718e3744 1421
c15dc24f
RW
1422 if (json)
1423 json_object_boolean_add(
1424 json_addr, "secondary",
1425 CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY));
1426 else if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
d62a17ae 1427 vty_out(vty, " secondary");
718e3744 1428
c15dc24f
RW
1429 if (json)
1430 json_object_boolean_add(
1431 json_addr, "unnumbered",
1432 CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED));
1433 else if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
d62a17ae 1434 vty_out(vty, " unnumbered");
525c1839 1435
c15dc24f
RW
1436 if (connected->label) {
1437 if (json)
1438 json_object_string_add(json_addr, "label",
1439 connected->label);
1440 else
1441 vty_out(vty, " %s", connected->label);
1442 }
718e3744 1443
c15dc24f
RW
1444 if (!json)
1445 vty_out(vty, "\n");
718e3744 1446}
1447
a80beece 1448/* Dump interface neighbor address information to vty. */
c15dc24f 1449static void nbr_connected_dump_vty(struct vty *vty, json_object *json,
d62a17ae 1450 struct nbr_connected *connected)
a80beece 1451{
d62a17ae 1452 struct prefix *p;
c15dc24f 1453 char buf[PREFIX2STR_BUFFER];
a80beece 1454
d62a17ae 1455 /* Print interface address. */
1456 p = connected->address;
c15dc24f
RW
1457 if (json)
1458 json_array_string_add(json, prefix2str(p, buf, sizeof(buf)));
1459 else
1460 vty_out(vty, " %s %pFX\n", prefix_family_str(p), p);
a80beece
DS
1461}
1462
a81982fa
DS
1463static const char *
1464zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type)
d0738ba2
PG
1465{
1466 switch (zif_slave_type) {
1467 case ZEBRA_IF_SLAVE_BRIDGE:
1468 return "Bridge";
1469 case ZEBRA_IF_SLAVE_VRF:
1470 return "Vrf";
1471 case ZEBRA_IF_SLAVE_BOND:
1472 return "Bond";
1473 case ZEBRA_IF_SLAVE_OTHER:
1474 return "Other";
1475 case ZEBRA_IF_SLAVE_NONE:
1476 return "None";
1477 }
1478 return "None";
1479}
1480
e6f2bec0 1481static const char *zebra_ziftype_2str(enum zebra_iftype zif_type)
6675513d 1482{
d62a17ae 1483 switch (zif_type) {
1484 case ZEBRA_IF_OTHER:
1485 return "Other";
6675513d 1486
d62a17ae 1487 case ZEBRA_IF_BRIDGE:
1488 return "Bridge";
6675513d 1489
d62a17ae 1490 case ZEBRA_IF_VLAN:
1491 return "Vlan";
6675513d 1492
d62a17ae 1493 case ZEBRA_IF_VXLAN:
1494 return "Vxlan";
6675513d 1495
d62a17ae 1496 case ZEBRA_IF_VRF:
1497 return "VRF";
6675513d 1498
0e4864ea
PG
1499 case ZEBRA_IF_VETH:
1500 return "VETH";
0e4864ea 1501
b9368db9
DD
1502 case ZEBRA_IF_BOND:
1503 return "bond";
1504
1505 case ZEBRA_IF_BOND_SLAVE:
1506 return "bond_slave";
1507
1508 case ZEBRA_IF_MACVLAN:
1509 return "macvlan";
1510
077c07cc
PG
1511 case ZEBRA_IF_GRE:
1512 return "GRE";
1513
d62a17ae 1514 default:
1515 return "Unknown";
d62a17ae 1516 }
6675513d 1517}
1518
49548752
NS
1519/* Interface's brief information print out to vty interface. */
1520static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
1521{
1522 struct connected *connected;
1523 struct listnode *node;
1524 struct route_node *rn;
1525 struct zebra_if *zebra_if;
1526 struct prefix *p;
1527 struct interface *ifp;
1528 bool print_header = true;
1529
1530 FOR_ALL_INTERFACES (vrf, ifp) {
49548752
NS
1531 bool first_pfx_printed = false;
1532
1533 if (print_header) {
1534 vty_out(vty, "%-16s%-8s%-16s%s\n", "Interface",
1535 "Status", "VRF", "Addresses");
1536 vty_out(vty, "%-16s%-8s%-16s%s\n", "---------",
1537 "------", "---", "---------");
1538 print_header = false; /* We have at least 1 iface */
1539 }
1540 zebra_if = ifp->info;
1541
1542 vty_out(vty, "%-16s", ifp->name);
1543
1544 if (if_is_up(ifp))
1545 vty_out(vty, "%-8s", "up");
1546 else
1547 vty_out(vty, "%-8s", "down");
1548
1549 vty_out(vty, "%-16s", vrf->name);
1550
1551 for (rn = route_top(zebra_if->ipv4_subnets); rn;
1552 rn = route_next(rn)) {
1553 if (!rn->info)
1554 continue;
1555 uint32_t list_size = listcount((struct list *)rn->info);
1556
1557 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1558 connected)) {
1559 if (!CHECK_FLAG(connected->flags,
1560 ZEBRA_IFA_SECONDARY)) {
1561 p = connected->address;
49548752 1562 if (first_pfx_printed) {
2dbe669b
DA
1563 /* padding to prepare row only
1564 * for ip addr */
49548752
NS
1565 vty_out(vty, "%-40s", "");
1566 if (list_size > 1)
1567 vty_out(vty, "+ ");
2dbe669b 1568 vty_out(vty, "%pFX\n", p);
49548752
NS
1569 } else {
1570 if (list_size > 1)
1571 vty_out(vty, "+ ");
2dbe669b 1572 vty_out(vty, "%pFX\n", p);
49548752
NS
1573 }
1574 first_pfx_printed = true;
1575 break;
1576 }
1577 }
1578 }
1579
1580 uint32_t v6_list_size = 0;
1581 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1582 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1583 && (connected->address->family == AF_INET6))
1584 v6_list_size++;
1585 }
1586 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1587 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1588 && !CHECK_FLAG(connected->flags,
1589 ZEBRA_IFA_SECONDARY)
1590 && (connected->address->family == AF_INET6)) {
1591 p = connected->address;
1592 /* Don't print link local pfx */
1593 if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
49548752 1594 if (first_pfx_printed) {
2dbe669b
DA
1595 /* padding to prepare row only
1596 * for ip addr */
49548752
NS
1597 vty_out(vty, "%-40s", "");
1598 if (v6_list_size > 1)
1599 vty_out(vty, "+ ");
2dbe669b 1600 vty_out(vty, "%pFX\n", p);
49548752
NS
1601 } else {
1602 if (v6_list_size > 1)
1603 vty_out(vty, "+ ");
2dbe669b 1604 vty_out(vty, "%pFX\n", p);
49548752
NS
1605 }
1606 first_pfx_printed = true;
1607 break;
1608 }
1609 }
1610 }
1611 if (!first_pfx_printed)
1612 vty_out(vty, "\n");
1613 }
1614 vty_out(vty, "\n");
1615}
1616
c15dc24f
RW
1617static void ifs_dump_brief_vty_json(json_object *json, struct vrf *vrf)
1618{
1619 struct connected *connected;
1620 struct listnode *node;
1621 struct interface *ifp;
1622
1623 FOR_ALL_INTERFACES (vrf, ifp) {
1624 json_object *json_if;
1625 json_object *json_addrs;
1626
1627 json_if = json_object_new_object();
1628 json_object_object_add(json, ifp->name, json_if);
1629
1630 json_object_string_add(json_if, "status",
1631 if_is_up(ifp) ? "up" : "down");
1632 json_object_string_add(json_if, "vrfName", vrf->name);
1633
1634 json_addrs = json_object_new_array();
1635 json_object_object_add(json_if, "addresses", json_addrs);
1636 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1637 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1638 && !CHECK_FLAG(connected->flags,
1639 ZEBRA_IFA_SECONDARY)
1640 && !(connected->address->family == AF_INET6
1641 && IN6_IS_ADDR_LINKLOCAL(
1642 &connected->address->u.prefix6))) {
1643 char buf[PREFIX2STR_BUFFER];
1644
1645 json_array_string_add(
1646 json_addrs,
1647 prefix2str(connected->address, buf,
1648 sizeof(buf)));
1649 }
1650 }
1651 }
1652}
1653
904e9b05
MS
1654const char *zebra_protodown_rc_str(enum protodown_reasons protodown_rc,
1655 char *pd_buf, uint32_t pd_buf_len)
c36e442c
AK
1656{
1657 bool first = true;
1658
1659 pd_buf[0] = '\0';
1660
904e9b05 1661 strlcat(pd_buf, "(", pd_buf_len);
c36e442c
AK
1662
1663 if (protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY) {
1664 if (first)
1665 first = false;
1666 else
904e9b05
MS
1667 strlcat(pd_buf, ",", pd_buf_len);
1668 strlcat(pd_buf, "startup-delay", pd_buf_len);
c36e442c
AK
1669 }
1670
1671 if (protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN) {
904e9b05
MS
1672 if (!first)
1673 strlcat(pd_buf, ",", pd_buf_len);
1674 strlcat(pd_buf, "uplinks-down", pd_buf_len);
c36e442c
AK
1675 }
1676
904e9b05 1677 strlcat(pd_buf, ")", pd_buf_len);
c36e442c
AK
1678
1679 return pd_buf;
1680}
1681
26ba45e3
AK
1682static inline bool if_is_protodown_applicable(struct interface *ifp)
1683{
1684 if (IS_ZEBRA_IF_BOND(ifp))
1685 return false;
1686
1687 return true;
1688}
1689
718e3744 1690/* Interface's information print out to vty interface. */
d62a17ae 1691static void if_dump_vty(struct vty *vty, struct interface *ifp)
1692{
1693 struct connected *connected;
1694 struct nbr_connected *nbr_connected;
1695 struct listnode *node;
1696 struct route_node *rn;
1697 struct zebra_if *zebra_if;
c36e442c 1698 char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
d62a17ae 1699
1700 zebra_if = ifp->info;
1701
1702 vty_out(vty, "Interface %s is ", ifp->name);
1703 if (if_is_up(ifp)) {
1704 vty_out(vty, "up, line protocol ");
1705
1706 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1707 if (if_is_running(ifp))
1708 vty_out(vty, "is up\n");
1709 else
1710 vty_out(vty, "is down\n");
1711 } else {
1712 vty_out(vty, "detection is disabled\n");
1713 }
1714 } else {
1715 vty_out(vty, "down\n");
1716 }
1717
1718 vty_out(vty, " Link ups: %5u last: %s\n", zebra_if->up_count,
1719 zebra_if->up_last[0] ? zebra_if->up_last : "(never)");
1720 vty_out(vty, " Link downs: %5u last: %s\n", zebra_if->down_count,
1721 zebra_if->down_last[0] ? zebra_if->down_last : "(never)");
1722
c15dc24f 1723 zebra_ptm_show_status(vty, NULL, ifp);
d62a17ae 1724
f60a1188 1725 vty_out(vty, " vrf: %s\n", ifp->vrf->name);
d62a17ae 1726
1727 if (ifp->desc)
1728 vty_out(vty, " Description: %s\n", ifp->desc);
ba5165ec
DS
1729 if (zebra_if->desc)
1730 vty_out(vty, " OS Description: %s\n", zebra_if->desc);
1731
d62a17ae 1732 if (ifp->ifindex == IFINDEX_INTERNAL) {
1733 vty_out(vty, " pseudo interface\n");
1734 return;
1735 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1736 vty_out(vty, " index %d inactive interface\n", ifp->ifindex);
1737 return;
1738 }
1739
1740 vty_out(vty, " index %d metric %d mtu %d speed %u ", ifp->ifindex,
1741 ifp->metric, ifp->mtu, ifp->speed);
1742 if (ifp->mtu6 != ifp->mtu)
1743 vty_out(vty, "mtu6 %d ", ifp->mtu6);
1744 vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
1745
b6beb700
MS
1746 if (zebra_if->mpls)
1747 vty_out(vty, " MPLS enabled\n");
1748
d62a17ae 1749 /* Hardware address. */
1750 vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
1751 if (ifp->hw_addr_len != 0) {
1752 int i;
1753
1754 vty_out(vty, " HWaddr: ");
1755 for (i = 0; i < ifp->hw_addr_len; i++)
1756 vty_out(vty, "%s%02x", i == 0 ? "" : ":",
1757 ifp->hw_addr[i]);
1758 vty_out(vty, "\n");
1759 }
1760
1761 /* Bandwidth in Mbps */
1762 if (ifp->bandwidth != 0) {
1763 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1764 vty_out(vty, "\n");
1765 }
1766
1767 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
1768 if (!rn->info)
1769 continue;
1770
1771 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
1772 connected))
c15dc24f 1773 connected_dump_vty(vty, NULL, connected);
d62a17ae 1774 }
1775
1776 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
1777 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
1778 && (connected->address->family == AF_INET6))
c15dc24f 1779 connected_dump_vty(vty, NULL, connected);
d62a17ae 1780 }
1781
1782 vty_out(vty, " Interface Type %s\n",
1783 zebra_ziftype_2str(zebra_if->zif_type));
d0738ba2
PG
1784 vty_out(vty, " Interface Slave Type %s\n",
1785 zebra_zifslavetype_2str(zebra_if->zif_slave_type));
1786
d62a17ae 1787 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
1788 struct zebra_l2info_bridge *bridge_info;
1789
1790 bridge_info = &zebra_if->l2info.br;
1791 vty_out(vty, " Bridge VLAN-aware: %s\n",
1792 bridge_info->vlan_aware ? "yes" : "no");
1793 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
1794 struct zebra_l2info_vlan *vlan_info;
1795
1796 vlan_info = &zebra_if->l2info.vl;
1797 vty_out(vty, " VLAN Id %u\n", vlan_info->vid);
1798 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
1799 struct zebra_l2info_vxlan *vxlan_info;
1800
1801 vxlan_info = &zebra_if->l2info.vxl;
1802 vty_out(vty, " VxLAN Id %u", vxlan_info->vni);
1803 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
9bcef951
MS
1804 vty_out(vty, " VTEP IP: %pI4",
1805 &vxlan_info->vtep_ip);
d62a17ae 1806 if (vxlan_info->access_vlan)
aa0677b4 1807 vty_out(vty, " Access VLAN Id %u\n",
d62a17ae 1808 vxlan_info->access_vlan);
d7fe235c 1809 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
9bcef951
MS
1810 vty_out(vty, " Mcast Group %pI4",
1811 &vxlan_info->mcast_grp);
14ddb3d9
PG
1812 if (vxlan_info->ifindex_link &&
1813 (vxlan_info->link_nsid != NS_UNKNOWN)) {
1814 struct interface *ifp;
1815
1816 ifp = if_lookup_by_index_per_ns(
1817 zebra_ns_lookup(vxlan_info->link_nsid),
1818 vxlan_info->ifindex_link);
1819 vty_out(vty, " Link Interface %s",
1820 ifp == NULL ? "Unknown" :
1821 ifp->name);
1822 }
d62a17ae 1823 vty_out(vty, "\n");
077c07cc
PG
1824 } else if (IS_ZEBRA_IF_GRE(ifp)) {
1825 struct zebra_l2info_gre *gre_info;
1826
1827 gre_info = &zebra_if->l2info.gre;
1828 if (gre_info->vtep_ip.s_addr != INADDR_ANY) {
1829 vty_out(vty, " VTEP IP: %pI4", &gre_info->vtep_ip);
1830 if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY)
1831 vty_out(vty, " , remote %pI4",
1832 &gre_info->vtep_ip_remote);
1833 vty_out(vty, "\n");
1834 }
1835 if (gre_info->ifindex_link &&
1836 (gre_info->link_nsid != NS_UNKNOWN)) {
1837 struct interface *ifp;
1838
1839 ifp = if_lookup_by_index_per_ns(
1840 zebra_ns_lookup(gre_info->link_nsid),
1841 gre_info->ifindex_link);
1842 vty_out(vty, " Link Interface %s\n",
1843 ifp == NULL ? "Unknown" :
1844 ifp->name);
1845 }
d62a17ae 1846 }
1847
1848 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
1849 struct zebra_l2info_brslave *br_slave;
1850
1851 br_slave = &zebra_if->brslave_info;
eb4a93fb
DD
1852 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
1853 if (br_slave->br_if)
1854 vty_out(vty, " Master interface: %s\n",
1855 br_slave->br_if->name);
1856 else
1857 vty_out(vty, " Master ifindex: %u\n",
1858 br_slave->bridge_ifindex);
1859 }
d62a17ae 1860 }
1861
b9368db9
DD
1862 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
1863 struct zebra_l2info_bondslave *bond_slave;
1864
1865 bond_slave = &zebra_if->bondslave_info;
eb4a93fb
DD
1866 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
1867 if (bond_slave->bond_if)
1868 vty_out(vty, " Master interface: %s\n",
1869 bond_slave->bond_if->name);
1870 else
1871 vty_out(vty, " Master ifindex: %u\n",
1872 bond_slave->bond_ifindex);
1873 }
b9368db9
DD
1874 }
1875
00a7710c
AK
1876 if (zebra_if->flags & ZIF_FLAG_LACP_BYPASS)
1877 vty_out(vty, " LACP bypass: on\n");
1878
c15dc24f 1879 zebra_evpn_if_es_print(vty, NULL, zebra_if);
26ba45e3
AK
1880 vty_out(vty, " protodown: %s %s\n",
1881 (zebra_if->flags & ZIF_FLAG_PROTODOWN) ? "on" : "off",
1882 if_is_protodown_applicable(ifp) ? "" : "(n/a)");
c36e442c 1883 if (zebra_if->protodown_rc)
26ba45e3 1884 vty_out(vty, " protodown reasons: %s\n",
c36e442c
AK
1885 zebra_protodown_rc_str(zebra_if->protodown_rc, pd_buf,
1886 sizeof(pd_buf)));
ce5160c0 1887
8cb73ba4 1888 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
8cb73ba4 1889 if (zebra_if->link)
eb4a93fb 1890 vty_out(vty, " Parent interface: %s\n", zebra_if->link->name);
8cb73ba4 1891 else
eb4a93fb 1892 vty_out(vty, " Parent ifindex: %d\n", zebra_if->link_ifindex);
8cb73ba4 1893 }
d62a17ae 1894
1895 if (HAS_LINK_PARAMS(ifp)) {
1896 int i;
1897 struct if_link_params *iflp = ifp->link_params;
1898 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1899 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1900 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1901 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1902 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1903 iflp->max_bw);
1904 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1905 vty_out(vty,
1906 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1907 iflp->max_rsv_bw);
1908 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1909 vty_out(vty,
1910 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1911 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1912 vty_out(vty,
1913 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1914 i, iflp->unrsv_bw[i], i + 1,
1915 iflp->unrsv_bw[i + 1]);
1916 }
1917
1918 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1919 vty_out(vty, " Administrative Group:%u\n",
1920 iflp->admin_grp);
1921 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1922 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1923 iflp->av_delay);
1924 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1925 vty_out(vty, " Min: %u (micro-sec.)",
1926 iflp->min_delay);
1927 vty_out(vty, " Max: %u (micro-sec.)",
1928 iflp->max_delay);
1929 }
1930 vty_out(vty, "\n");
1931 }
1932 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1933 vty_out(vty,
1934 " Link Delay Variation %u (micro-sec.)\n",
1935 iflp->delay_var);
1936 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1937 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1938 iflp->pkt_loss);
1939 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1940 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1941 iflp->ava_bw);
1942 if (IS_PARAM_SET(iflp, LP_RES_BW))
1943 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1944 iflp->res_bw);
1945 if (IS_PARAM_SET(iflp, LP_USE_BW))
1946 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1947 iflp->use_bw);
1948 if (IS_PARAM_SET(iflp, LP_RMT_AS))
9bcef951
MS
1949 vty_out(vty, " Neighbor ASBR IP: %pI4 AS: %u \n",
1950 &iflp->rmt_ip, iflp->rmt_as);
d62a17ae 1951 }
1952
2eb27eec
DL
1953 hook_call(zebra_if_extra_info, vty, ifp);
1954
d62a17ae 1955 if (listhead(ifp->nbr_connected))
1956 vty_out(vty, " Neighbor address(s):\n");
1957 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
c15dc24f 1958 nbr_connected_dump_vty(vty, NULL, nbr_connected);
718e3744 1959
1960#ifdef HAVE_PROC_NET_DEV
d62a17ae 1961 /* Statistics print out using proc file system. */
1962 vty_out(vty,
3efd0893 1963 " %lu input packets (%lu multicast), %lu bytes, %lu dropped\n",
d62a17ae 1964 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1965 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1966
1967 vty_out(vty,
3efd0893 1968 " %lu input errors, %lu length, %lu overrun, %lu CRC, %lu frame\n",
d62a17ae 1969 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1970 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1971 ifp->stats.rx_frame_errors);
1972
1973 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1974 ifp->stats.rx_missed_errors);
1975
1976 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1977 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1978 ifp->stats.tx_dropped);
1979
1980 vty_out(vty,
3efd0893 1981 " %lu output errors, %lu aborted, %lu carrier, %lu fifo, %lu heartbeat\n",
d62a17ae 1982 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1983 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1984 ifp->stats.tx_heartbeat_errors);
1985
1986 vty_out(vty, " %lu window, %lu collisions\n",
1987 ifp->stats.tx_window_errors, ifp->stats.collisions);
718e3744 1988#endif /* HAVE_PROC_NET_DEV */
1989
1990#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1991 /* Statistics print out using sysctl (). */
1992 vty_out(vty,
3efd0893 1993 " input packets %llu, bytes %llu, dropped %llu, multicast packets %llu\n",
d62a17ae 1994 (unsigned long long)ifp->stats.ifi_ipackets,
1995 (unsigned long long)ifp->stats.ifi_ibytes,
1996 (unsigned long long)ifp->stats.ifi_iqdrops,
1997 (unsigned long long)ifp->stats.ifi_imcasts);
1998
1999 vty_out(vty, " input errors %llu\n",
2000 (unsigned long long)ifp->stats.ifi_ierrors);
2001
2002 vty_out(vty,
3efd0893 2003 " output packets %llu, bytes %llu, multicast packets %llu\n",
d62a17ae 2004 (unsigned long long)ifp->stats.ifi_opackets,
2005 (unsigned long long)ifp->stats.ifi_obytes,
2006 (unsigned long long)ifp->stats.ifi_omcasts);
2007
2008 vty_out(vty, " output errors %llu\n",
2009 (unsigned long long)ifp->stats.ifi_oerrors);
2010
2011 vty_out(vty, " collisions %llu\n",
2012 (unsigned long long)ifp->stats.ifi_collisions);
718e3744 2013#endif /* HAVE_NET_RT_IFLIST */
2014}
2015
c15dc24f
RW
2016static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
2017 json_object *json)
2018{
2019 struct connected *connected;
2020 struct nbr_connected *nbr_connected;
2021 struct listnode *node;
2022 struct route_node *rn;
2023 struct zebra_if *zebra_if;
c15dc24f
RW
2024 char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
2025 char buf[BUFSIZ];
2026 json_object *json_if;
2027 json_object *json_addrs;
2028
2029 json_if = json_object_new_object();
2030 json_object_object_add(json, ifp->name, json_if);
2031
2032 if (if_is_up(ifp)) {
2033 json_object_string_add(json_if, "administrativeStatus", "up");
2034
2035 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
2036 json_object_string_add(json_if, "operationalStatus",
2037 if_is_running(ifp) ? "up"
2038 : "down");
2039 json_object_boolean_add(json_if, "linkDetection", true);
2040 } else {
2041 json_object_boolean_add(json_if, "linkDetection",
2042 false);
2043 }
2044 } else {
2045 json_object_string_add(json_if, "administrativeStatus", "down");
2046 }
2047
2048 zebra_if = ifp->info;
2049
2050 json_object_int_add(json_if, "linkUps", zebra_if->up_count);
2051 json_object_int_add(json_if, "linkDowns", zebra_if->down_count);
2052 if (zebra_if->up_last[0])
2053 json_object_string_add(json_if, "lastLinkUp",
2054 zebra_if->up_last);
2055 if (zebra_if->down_last[0])
2056 json_object_string_add(json_if, "lastLinkDown",
2057 zebra_if->down_last);
2058
2059 zebra_ptm_show_status(vty, json, ifp);
2060
f60a1188 2061 json_object_string_add(json_if, "vrfName", ifp->vrf->name);
c15dc24f
RW
2062
2063 if (ifp->desc)
2064 json_object_string_add(json_if, "description", ifp->desc);
2065 if (zebra_if->desc)
2066 json_object_string_add(json_if, "OsDescription",
2067 zebra_if->desc);
2068
b6beb700
MS
2069 json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls);
2070
c15dc24f
RW
2071 if (ifp->ifindex == IFINDEX_INTERNAL) {
2072 json_object_boolean_add(json_if, "pseudoInterface", true);
2073 return;
2074 } else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2075 json_object_int_add(json_if, "index", ifp->ifindex);
2076 return;
2077 }
2078
2079 json_object_boolean_add(json_if, "pseudoInterface", false);
2080 json_object_int_add(json_if, "index", ifp->ifindex);
2081 json_object_int_add(json_if, "metric", ifp->metric);
2082 json_object_int_add(json_if, "mtu", ifp->mtu);
2083 if (ifp->mtu6 != ifp->mtu)
2084 json_object_int_add(json_if, "mtu6", ifp->mtu6);
2085 json_object_int_add(json_if, "speed", ifp->speed);
2086 json_object_string_add(json_if, "flags", if_flag_dump(ifp->flags));
2087
2088 /* Hardware address. */
2089 json_object_string_add(json_if, "type", if_link_type_str(ifp->ll_type));
2090 if (ifp->hw_addr_len != 0) {
2091 char hwbuf[BUFSIZ];
2092
2093 hwbuf[0] = '\0';
2094 for (int i = 0; i < ifp->hw_addr_len; i++) {
2095 snprintf(buf, sizeof(buf), "%s%02x", i == 0 ? "" : ":",
2096 ifp->hw_addr[i]);
2097 strlcat(hwbuf, buf, sizeof(hwbuf));
2098 }
2099 json_object_string_add(json_if, "hardwareAddress", hwbuf);
2100 }
2101
2102 /* Bandwidth in Mbps */
2103 if (ifp->bandwidth != 0)
2104 json_object_int_add(json_if, "bandwidth", ifp->bandwidth);
2105
2106
2107 /* IP addresses. */
2108 json_addrs = json_object_new_array();
2109 json_object_object_add(json_if, "ipAddresses", json_addrs);
2110
2111 for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) {
2112 if (!rn->info)
2113 continue;
2114
2115 for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node,
2116 connected))
2117 connected_dump_vty(vty, json_addrs, connected);
2118 }
2119
2120 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
2121 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2122 && (connected->address->family == AF_INET6))
2123 connected_dump_vty(vty, json_addrs, connected);
2124 }
2125
2126 json_object_string_add(json_if, "interfaceType",
2127 zebra_ziftype_2str(zebra_if->zif_type));
2128 json_object_string_add(
2129 json_if, "interfaceSlaveType",
2130 zebra_zifslavetype_2str(zebra_if->zif_slave_type));
2131
2132 if (IS_ZEBRA_IF_BRIDGE(ifp)) {
2133 struct zebra_l2info_bridge *bridge_info;
2134
2135 bridge_info = &zebra_if->l2info.br;
2136 json_object_boolean_add(json_if, "bridgeVlanAware",
2137 bridge_info->vlan_aware);
2138 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
2139 struct zebra_l2info_vlan *vlan_info;
2140
2141 vlan_info = &zebra_if->l2info.vl;
2142 json_object_int_add(json_if, "vlanId", vlan_info->vid);
2143 } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
2144 struct zebra_l2info_vxlan *vxlan_info;
2145
2146 vxlan_info = &zebra_if->l2info.vxl;
2147 json_object_int_add(json_if, "vxlanId", vxlan_info->vni);
2148 if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
08edf9c6
DA
2149 json_object_string_addf(json_if, "vtepIp", "%pI4",
2150 &vxlan_info->vtep_ip);
c15dc24f
RW
2151 if (vxlan_info->access_vlan)
2152 json_object_int_add(json_if, "accessVlanId",
2153 vxlan_info->access_vlan);
2154 if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
08edf9c6
DA
2155 json_object_string_addf(json_if, "mcastGroup", "%pI4",
2156 &vxlan_info->mcast_grp);
c15dc24f
RW
2157 if (vxlan_info->ifindex_link
2158 && (vxlan_info->link_nsid != NS_UNKNOWN)) {
2159 struct interface *ifp;
2160
2161 ifp = if_lookup_by_index_per_ns(
2162 zebra_ns_lookup(vxlan_info->link_nsid),
2163 vxlan_info->ifindex_link);
2164 json_object_string_add(json_if, "linkInterface",
2165 ifp == NULL ? "Unknown"
2166 : ifp->name);
2167 }
2168 } else if (IS_ZEBRA_IF_GRE(ifp)) {
2169 struct zebra_l2info_gre *gre_info;
2170
2171 gre_info = &zebra_if->l2info.gre;
2172 if (gre_info->vtep_ip.s_addr != INADDR_ANY) {
08edf9c6
DA
2173 json_object_string_addf(json_if, "vtepIp", "%pI4",
2174 &gre_info->vtep_ip);
c15dc24f 2175 if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY)
08edf9c6
DA
2176 json_object_string_addf(
2177 json_if, "vtepRemoteIp", "%pI4",
2178 &gre_info->vtep_ip_remote);
c15dc24f
RW
2179 }
2180 if (gre_info->ifindex_link
2181 && (gre_info->link_nsid != NS_UNKNOWN)) {
2182 struct interface *ifp;
2183
2184 ifp = if_lookup_by_index_per_ns(
2185 zebra_ns_lookup(gre_info->link_nsid),
2186 gre_info->ifindex_link);
2187 json_object_string_add(json_if, "linkInterface",
2188 ifp == NULL ? "Unknown"
2189 : ifp->name);
2190 }
2191 }
2192
2193 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
2194 struct zebra_l2info_brslave *br_slave;
2195
2196 br_slave = &zebra_if->brslave_info;
2197 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
2198 if (br_slave->br_if)
2199 json_object_string_add(json_if,
2200 "masterInterface",
2201 br_slave->br_if->name);
2202 else
2203 json_object_int_add(json_if, "masterIfindex",
2204 br_slave->bridge_ifindex);
2205 }
2206 }
2207
2208 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
2209 struct zebra_l2info_bondslave *bond_slave;
2210
2211 bond_slave = &zebra_if->bondslave_info;
2212 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
2213 if (bond_slave->bond_if)
2214 json_object_string_add(
2215 json_if, "masterInterface",
2216 bond_slave->bond_if->name);
2217 else
2218 json_object_int_add(json_if, "masterIfindex",
2219 bond_slave->bond_ifindex);
2220 }
2221 }
2222
2223 json_object_boolean_add(
2224 json_if, "lacpBypass",
2225 CHECK_FLAG(zebra_if->flags, ZIF_FLAG_LACP_BYPASS));
2226
2227 zebra_evpn_if_es_print(vty, json_if, zebra_if);
2228
2229 if (if_is_protodown_applicable(ifp)) {
2230 json_object_string_add(
2231 json_if, "protodown",
2232 (zebra_if->flags & ZIF_FLAG_PROTODOWN) ? "on" : "off");
2233 if (zebra_if->protodown_rc)
2234 json_object_string_add(
2235 json_if, "protodownReason",
2236 zebra_protodown_rc_str(zebra_if->protodown_rc,
2237 pd_buf, sizeof(pd_buf)));
2238 }
2239
2240 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
2241 if (zebra_if->link)
2242 json_object_string_add(json_if, "parentInterface",
2243 zebra_if->link->name);
2244 else
2245 json_object_int_add(json_if, "parentIfindex",
2246 zebra_if->link_ifindex);
2247 }
2248
2249 if (HAS_LINK_PARAMS(ifp)) {
2250 struct if_link_params *iflp = ifp->link_params;
2251 json_object *json_te;
2252
2253 json_te = json_object_new_object();
2254 json_object_object_add(
2255 json_if, "trafficEngineeringLinkParameters", json_te);
2256
2257 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
2258 json_object_int_add(json_te, "teMetric",
2259 iflp->te_metric);
2260 if (IS_PARAM_SET(iflp, LP_MAX_BW))
2261 json_object_double_add(json_te, "maximumBandwidth",
2262 iflp->max_bw);
2263 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
2264 json_object_double_add(json_te,
2265 "maximumReservableBandwidth",
2266 iflp->max_rsv_bw);
2267 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2268 json_object *json_bws;
2269
2270 json_bws = json_object_new_object();
2271 json_object_object_add(json_te, "unreservedBandwidth",
2272 json_bws);
2273 for (unsigned int i = 0; i < MAX_CLASS_TYPE; ++i) {
2274 char buf_ct[64];
2275
2276 snprintf(buf_ct, sizeof(buf_ct), "classType%u",
2277 i);
2278 json_object_double_add(json_bws, buf_ct,
2279 iflp->unrsv_bw[i]);
2280 }
2281 }
2282
2283 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2284 json_object_int_add(json_te, "administrativeGroup",
2285 iflp->admin_grp);
2286 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2287 json_object_int_add(json_te, "linkDelayAverage",
2288 iflp->av_delay);
2289 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2290 json_object_int_add(json_te, "linkDelayMinimum",
2291 iflp->min_delay);
2292 json_object_int_add(json_te, "linkDelayMaximum",
2293 iflp->max_delay);
2294 }
2295 }
2296 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2297 json_object_int_add(json_te, "linkDelayVariation",
2298 iflp->delay_var);
2299 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2300 json_object_double_add(json_te, "linkPacketLoss",
2301 iflp->pkt_loss);
2302 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2303 json_object_double_add(json_te, "availableBandwidth",
2304 iflp->ava_bw);
2305 if (IS_PARAM_SET(iflp, LP_RES_BW))
2306 json_object_double_add(json_te, "residualBandwidth",
2307 iflp->res_bw);
2308 if (IS_PARAM_SET(iflp, LP_USE_BW))
2309 json_object_double_add(json_te, "utilizedBandwidth",
2310 iflp->use_bw);
2311 if (IS_PARAM_SET(iflp, LP_RMT_AS))
08edf9c6
DA
2312 json_object_string_addf(json_te, "neighborAsbrIp",
2313 "%pI4", &iflp->rmt_ip);
c15dc24f
RW
2314 json_object_int_add(json_te, "neighborAsbrAs", iflp->rmt_as);
2315 }
2316
2317 if (listhead(ifp->nbr_connected)) {
2318 json_object *json_nbr_addrs;
2319
2320 json_nbr_addrs = json_object_new_array();
2321 json_object_object_add(json_if, "neighborIpAddresses",
2322 json_nbr_addrs);
2323
2324 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
2325 nbr_connected))
2326 nbr_connected_dump_vty(vty, json_nbr_addrs,
2327 nbr_connected);
2328 }
2329
2330#ifdef HAVE_PROC_NET_DEV
2331 json_object_int_add(json_if, "inputPackets", stats.rx_packets);
2332 json_object_int_add(json_if, "inputBytes", ifp->stats.rx_bytes);
2333 json_object_int_add(json_if, "inputDropped", ifp->stats.rx_dropped);
2334 json_object_int_add(json_if, "inputMulticastPackets",
2335 ifp->stats.rx_multicast);
2336 json_object_int_add(json_if, "inputErrors", ifp->stats.rx_errors);
2337 json_object_int_add(json_if, "inputLengthErrors",
2338 ifp->stats.rx_length_errors);
2339 json_object_int_add(json_if, "inputOverrunErrors",
2340 ifp->stats.rx_over_errors);
2341 json_object_int_add(json_if, "inputCrcErrors",
2342 ifp->stats.rx_crc_errors);
2343 json_object_int_add(json_if, "inputFrameErrors",
2344 ifp->stats.rx_frame_errors);
2345 json_object_int_add(json_if, "inputFifoErrors",
2346 ifp->stats.rx_fifo_errors);
2347 json_object_int_add(json_if, "inputMissedErrors",
2348 ifp->stats.rx_missed_errors);
2349 json_object_int_add(json_if, "outputPackets", ifp->stats.tx_packets);
2350 json_object_int_add(json_if, "outputBytes", ifp->stats.tx_bytes);
2351 json_object_int_add(json_if, "outputDroppedPackets",
2352 ifp->stats.tx_dropped);
2353 json_object_int_add(json_if, "outputErrors", ifp->stats.tx_errors);
2354 json_object_int_add(json_if, "outputAbortedErrors",
2355 ifp->stats.tx_aborted_errors);
2356 json_object_int_add(json_if, "outputCarrierErrors",
2357 ifp->stats.tx_carrier_errors);
2358 json_object_int_add(json_if, "outputFifoErrors",
2359 ifp->stats.tx_fifo_errors);
2360 json_object_int_add(json_if, "outputHeartbeatErrors",
2361 ifp->stats.tx_heartbeat_errors);
2362 json_object_int_add(json_if, "outputWindowErrors",
2363 ifp->stats.tx_window_errors);
2364 json_object_int_add(json_if, "collisions", ifp->stats.collisions);
2365#endif /* HAVE_PROC_NET_DEV */
2366
2367#ifdef HAVE_NET_RT_IFLIST
2368 json_object_int_add(json_if, "inputPackets", ifp->stats.ifi_ipackets);
2369 json_object_int_add(json_if, "inputBytes", ifp->stats.ifi_ibytes);
2370 json_object_int_add(json_if, "inputDropd", ifp->stats.ifi_iqdrops);
2371 json_object_int_add(json_if, "inputMulticastPackets",
2372 ifp->stats.ifi_imcasts);
2373 json_object_int_add(json_if, "inputErrors", ifp->stats.ifi_ierrors);
2374 json_object_int_add(json_if, "outputPackets", ifp->stats.ifi_opackets);
2375 json_object_int_add(json_if, "outputBytes", ifp->stats.ifi_obytes);
2376 json_object_int_add(json_if, "outputMulticastPackets",
2377 ifp->stats.ifi_omcasts);
2378 json_object_int_add(json_if, "outputErrors", ifp->stats.ifi_oerrors);
2379 json_object_int_add(json_if, "collisions", ifp->stats.ifi_collisions);
2380#endif /* HAVE_NET_RT_IFLIST */
2381}
2382
d62a17ae 2383static void interface_update_stats(void)
78860b9f
DS
2384{
2385#ifdef HAVE_PROC_NET_DEV
d62a17ae 2386 /* If system has interface statistics via proc file system, update
2387 statistics. */
2388 ifstat_update_proc();
78860b9f
DS
2389#endif /* HAVE_PROC_NET_DEV */
2390#ifdef HAVE_NET_RT_IFLIST
d62a17ae 2391 ifstat_update_sysctl();
78860b9f
DS
2392#endif /* HAVE_NET_RT_IFLIST */
2393}
2394
49548752
NS
2395#ifndef VTYSH_EXTRACT_PL
2396#include "zebra/interface_clippy.c"
2397#endif
8b87bdf4 2398/* Show all interfaces to vty. */
49548752 2399DEFPY(show_interface, show_interface_cmd,
c15dc24f 2400 "show interface vrf NAME$vrf_name [brief$brief] [json$uj]",
49548752
NS
2401 SHOW_STR
2402 "Interface status and configuration\n"
2403 VRF_CMD_HELP_STR
c15dc24f
RW
2404 "Interface status and configuration summary\n"
2405 JSON_STR)
8b87bdf4 2406{
a36898e7 2407 struct vrf *vrf;
d62a17ae 2408 struct interface *ifp;
c15dc24f 2409 json_object *json = NULL;
8b87bdf4 2410
d62a17ae 2411 interface_update_stats();
8b87bdf4 2412
a2719d0e
IR
2413 vrf = vrf_lookup_by_name(vrf_name);
2414 if (!vrf) {
c15dc24f
RW
2415 if (uj)
2416 vty_out(vty, "{}\n");
2417 else
2418 vty_out(vty, "%% VRF %s not found\n", vrf_name);
a2719d0e
IR
2419 return CMD_WARNING;
2420 }
8b87bdf4 2421
c15dc24f
RW
2422 if (uj)
2423 json = json_object_new_object();
2424
49548752 2425 if (brief) {
c15dc24f
RW
2426 if (json)
2427 ifs_dump_brief_vty_json(json, vrf);
2428 else
2429 ifs_dump_brief_vty(vty, vrf);
49548752
NS
2430 } else {
2431 FOR_ALL_INTERFACES (vrf, ifp) {
c15dc24f
RW
2432 if (json)
2433 if_dump_vty_json(vty, ifp, json);
2434 else
2435 if_dump_vty(vty, ifp);
49548752
NS
2436 }
2437 }
8b87bdf4 2438
c48349e3 2439 if (json)
962af8a8 2440 vty_json(vty, json);
c15dc24f 2441
d62a17ae 2442 return CMD_SUCCESS;
8b87bdf4
FL
2443}
2444
8b87bdf4
FL
2445
2446/* Show all interfaces to vty. */
a5c7809c 2447DEFPY (show_interface_vrf_all,
8b3f0677 2448 show_interface_vrf_all_cmd,
c15dc24f 2449 "show interface [vrf all] [brief$brief] [json$uj]",
8b87bdf4
FL
2450 SHOW_STR
2451 "Interface status and configuration\n"
a5c7809c 2452 VRF_ALL_CMD_HELP_STR
c15dc24f
RW
2453 "Interface status and configuration summary\n"
2454 JSON_STR)
718e3744 2455{
d62a17ae 2456 struct vrf *vrf;
d62a17ae 2457 struct interface *ifp;
c15dc24f 2458 json_object *json = NULL;
8b87bdf4 2459
d62a17ae 2460 interface_update_stats();
718e3744 2461
c15dc24f
RW
2462 if (uj)
2463 json = json_object_new_object();
2464
d62a17ae 2465 /* All interface print. */
a5c7809c
DS
2466 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2467 if (brief) {
c15dc24f
RW
2468 if (json)
2469 ifs_dump_brief_vty_json(json, vrf);
2470 else
2471 ifs_dump_brief_vty(vty, vrf);
a5c7809c 2472 } else {
c15dc24f
RW
2473 FOR_ALL_INTERFACES (vrf, ifp) {
2474 if (json)
2475 if_dump_vty_json(vty, ifp, json);
2476 else
2477 if_dump_vty(vty, ifp);
2478 }
a5c7809c
DS
2479 }
2480 }
8b87bdf4 2481
c48349e3 2482 if (json)
962af8a8 2483 vty_json(vty, json);
c15dc24f 2484
d62a17ae 2485 return CMD_SUCCESS;
8b87bdf4
FL
2486}
2487
2488/* Show specified interface to vty. */
1721646e 2489
c15dc24f 2490DEFPY (show_interface_name_vrf,
1721646e 2491 show_interface_name_vrf_cmd,
c15dc24f 2492 "show interface IFNAME$ifname vrf NAME$vrf_name [json$uj]",
8b87bdf4
FL
2493 SHOW_STR
2494 "Interface status and configuration\n"
1721646e 2495 "Interface name\n"
c15dc24f
RW
2496 VRF_CMD_HELP_STR
2497 JSON_STR)
8b87bdf4 2498{
d62a17ae 2499 struct interface *ifp;
a2719d0e 2500 struct vrf *vrf;
c15dc24f 2501 json_object *json = NULL;
8b87bdf4 2502
d62a17ae 2503 interface_update_stats();
8b87bdf4 2504
c15dc24f 2505 vrf = vrf_lookup_by_name(vrf_name);
a2719d0e 2506 if (!vrf) {
c15dc24f
RW
2507 if (uj)
2508 vty_out(vty, "{}\n");
2509 else
2510 vty_out(vty, "%% VRF %s not found\n", vrf_name);
a2719d0e
IR
2511 return CMD_WARNING;
2512 }
8b87bdf4 2513
c15dc24f 2514 ifp = if_lookup_by_name_vrf(ifname, vrf);
d62a17ae 2515 if (ifp == NULL) {
c15dc24f
RW
2516 if (uj)
2517 vty_out(vty, "{}\n");
2518 else
2519 vty_out(vty, "%% Can't find interface %s\n", ifname);
d62a17ae 2520 return CMD_WARNING;
2521 }
c15dc24f
RW
2522
2523 if (uj)
2524 json = json_object_new_object();
2525
2526 if (json)
2527 if_dump_vty_json(vty, ifp, json);
2528 else
2529 if_dump_vty(vty, ifp);
2530
c48349e3 2531 if (json)
962af8a8 2532 vty_json(vty, json);
718e3744 2533
d62a17ae 2534 return CMD_SUCCESS;
718e3744 2535}
2536
8b87bdf4 2537/* Show specified interface to vty. */
c15dc24f 2538DEFPY (show_interface_name_vrf_all,
8b3f0677 2539 show_interface_name_vrf_all_cmd,
c15dc24f 2540 "show interface IFNAME$ifname [vrf all] [json$uj]",
8b87bdf4
FL
2541 SHOW_STR
2542 "Interface status and configuration\n"
1721646e 2543 "Interface name\n"
c15dc24f
RW
2544 VRF_ALL_CMD_HELP_STR
2545 JSON_STR)
8b87bdf4 2546{
31eab818
IR
2547 struct interface *ifp = NULL;
2548 struct interface *ifptmp;
2549 struct vrf *vrf;
c15dc24f 2550 json_object *json = NULL;
31eab818 2551 int count = 0;
8b87bdf4 2552
d62a17ae 2553 interface_update_stats();
8b87bdf4 2554
31eab818
IR
2555 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2556 ifptmp = if_lookup_by_name_vrf(ifname, vrf);
2557 if (ifptmp) {
2558 ifp = ifptmp;
2559 count++;
2560 if (!vrf_is_backend_netns())
2561 break;
2562 }
2563 }
2564
a2719d0e 2565 if (ifp == NULL) {
c15dc24f
RW
2566 if (uj)
2567 vty_out(vty, "{}\n");
2568 else
2569 vty_out(vty, "%% Can't find interface %s\n", ifname);
d62a17ae 2570 return CMD_WARNING;
2571 }
31eab818
IR
2572 if (count > 1) {
2573 if (uj) {
2574 vty_out(vty, "{}\n");
2575 } else {
2576 vty_out(vty,
2577 "%% There are multiple interfaces with name %s\n",
2578 ifname);
2579 vty_out(vty, "%% You must specify the VRF name\n");
2580 }
2581 return CMD_WARNING;
d62a17ae 2582 }
c15dc24f
RW
2583
2584 if (uj)
2585 json = json_object_new_object();
2586
2587 if (json)
2588 if_dump_vty_json(vty, ifp, json);
2589 else
2590 if_dump_vty(vty, ifp);
2591
c48349e3 2592 if (json)
962af8a8 2593 vty_json(vty, json);
8b87bdf4 2594
d62a17ae 2595 return CMD_SUCCESS;
8b87bdf4
FL
2596}
2597
a2719d0e 2598static void if_show_description(struct vty *vty, struct vrf *vrf)
ed9bb6d5 2599{
d62a17ae 2600 struct interface *ifp;
ed9bb6d5 2601
d62a17ae 2602 vty_out(vty, "Interface Status Protocol Description\n");
451fda4f 2603 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 2604 int len;
ba5165ec
DS
2605 struct zebra_if *zif;
2606 bool intf_desc;
2607
2608 intf_desc = false;
ed9bb6d5 2609
d62a17ae 2610 len = vty_out(vty, "%s", ifp->name);
2611 vty_out(vty, "%*s", (16 - len), " ");
2612
2613 if (if_is_up(ifp)) {
2614 vty_out(vty, "up ");
2615 if (CHECK_FLAG(ifp->status,
2616 ZEBRA_INTERFACE_LINKDETECTION)) {
2617 if (if_is_running(ifp))
2618 vty_out(vty, "up ");
2619 else
2620 vty_out(vty, "down ");
2621 } else {
2622 vty_out(vty, "unknown ");
2623 }
2624 } else {
2625 vty_out(vty, "down down ");
2626 }
ed9bb6d5 2627
ba5165ec
DS
2628 if (ifp->desc) {
2629 intf_desc = true;
d62a17ae 2630 vty_out(vty, "%s", ifp->desc);
ba5165ec
DS
2631 }
2632 zif = ifp->info;
2633 if (zif && zif->desc) {
2634 vty_out(vty, "%s%s",
2635 intf_desc
2636 ? "\n "
2637 : "",
2638 zif->desc);
2639 }
2640
d62a17ae 2641 vty_out(vty, "\n");
2642 }
8b87bdf4
FL
2643}
2644
2645DEFUN (show_interface_desc,
2646 show_interface_desc_cmd,
a2719d0e 2647 "show interface description vrf NAME",
8b87bdf4
FL
2648 SHOW_STR
2649 "Interface status and configuration\n"
b62ecea5
QY
2650 "Interface description\n"
2651 VRF_CMD_HELP_STR)
8b87bdf4 2652{
a2719d0e 2653 struct vrf *vrf;
8b87bdf4 2654
a2719d0e
IR
2655 vrf = vrf_lookup_by_name(argv[4]->arg);
2656 if (!vrf) {
2657 vty_out(vty, "%% VRF %s not found\n", argv[4]->arg);
2658 return CMD_WARNING;
2659 }
8b87bdf4 2660
a2719d0e 2661 if_show_description(vty, vrf);
8b87bdf4 2662
d62a17ae 2663 return CMD_SUCCESS;
8b87bdf4
FL
2664}
2665
8b87bdf4
FL
2666
2667DEFUN (show_interface_desc_vrf_all,
2668 show_interface_desc_vrf_all_cmd,
a2719d0e 2669 "show interface description [vrf all]",
8b87bdf4
FL
2670 SHOW_STR
2671 "Interface status and configuration\n"
2672 "Interface description\n"
2673 VRF_ALL_CMD_HELP_STR)
2674{
d62a17ae 2675 struct vrf *vrf;
8b87bdf4 2676
a2addae8 2677 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
996c9314 2678 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
c479e756
DS
2679 vty_out(vty, "\n\tVRF %s(%u)\n\n", VRF_LOGNAME(vrf),
2680 vrf->vrf_id);
a2719d0e 2681 if_show_description(vty, vrf);
a2addae8 2682 }
8b87bdf4 2683
d62a17ae 2684 return CMD_SUCCESS;
ed9bb6d5 2685}
2686
09268680
CS
2687int if_multicast_set(struct interface *ifp)
2688{
2689 struct zebra_if *if_data;
2690
2691 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2692 if (if_set_flags(ifp, IFF_MULTICAST) < 0) {
2693 zlog_debug("Can't set multicast flag on interface %s",
2694 ifp->name);
2695 return -1;
2696 }
2697 if_refresh(ifp);
2698 }
2699 if_data = ifp->info;
2700 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
2701
2702 return 0;
2703}
2704
718e3744 2705DEFUN (multicast,
2706 multicast_cmd,
2707 "multicast",
2708 "Set multicast flag to interface\n")
2709{
d62a17ae 2710 VTY_DECLVAR_CONTEXT(interface, ifp);
2711 int ret;
2712 struct zebra_if *if_data;
718e3744 2713
d62a17ae 2714 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2715 ret = if_set_flags(ifp, IFF_MULTICAST);
2716 if (ret < 0) {
2717 vty_out(vty, "Can't set multicast flag\n");
2718 return CMD_WARNING_CONFIG_FAILED;
2719 }
2720 if_refresh(ifp);
48b33aaf 2721 }
d62a17ae 2722 if_data = ifp->info;
2723 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 2724
d62a17ae 2725 return CMD_SUCCESS;
718e3744 2726}
2727
09268680
CS
2728int if_multicast_unset(struct interface *ifp)
2729{
2730 struct zebra_if *if_data;
2731
2732 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2733 if (if_unset_flags(ifp, IFF_MULTICAST) < 0) {
2734 zlog_debug("Can't unset multicast flag on interface %s",
2735 ifp->name);
2736 return -1;
2737 }
2738 if_refresh(ifp);
2739 }
2740 if_data = ifp->info;
2741 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
2742
2743 return 0;
2744}
2745
718e3744 2746DEFUN (no_multicast,
2747 no_multicast_cmd,
2748 "no multicast",
2749 NO_STR
2750 "Unset multicast flag to interface\n")
2751{
d62a17ae 2752 VTY_DECLVAR_CONTEXT(interface, ifp);
2753 int ret;
2754 struct zebra_if *if_data;
718e3744 2755
d62a17ae 2756 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2757 ret = if_unset_flags(ifp, IFF_MULTICAST);
2758 if (ret < 0) {
2759 vty_out(vty, "Can't unset multicast flag\n");
2760 return CMD_WARNING_CONFIG_FAILED;
2761 }
2762 if_refresh(ifp);
48b33aaf 2763 }
d62a17ae 2764 if_data = ifp->info;
2765 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
718e3744 2766
d62a17ae 2767 return CMD_SUCCESS;
718e3744 2768}
2769
09268680 2770int if_linkdetect(struct interface *ifp, bool detect)
2e3b2e47 2771{
d62a17ae 2772 int if_was_operative;
2e3b2e47 2773
d62a17ae 2774 if_was_operative = if_is_no_ptm_operative(ifp);
09268680
CS
2775 if (detect) {
2776 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 2777
09268680
CS
2778 /* When linkdetection is enabled, if might come down */
2779 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
2780 if_down(ifp);
2781 } else {
2782 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 2783
09268680
CS
2784 /* Interface may come up after disabling link detection */
2785 if (if_is_operative(ifp) && !if_was_operative)
8b48cdb9 2786 if_up(ifp, true);
09268680 2787 }
d62a17ae 2788 /* FIXME: Will defer status change forwarding if interface
2789 does not come down! */
09268680
CS
2790 return 0;
2791}
2792
2793DEFUN(linkdetect, linkdetect_cmd, "link-detect",
2794 "Enable link detection on interface\n")
2795{
2796 VTY_DECLVAR_CONTEXT(interface, ifp);
2797
2798 if_linkdetect(ifp, true);
d62a17ae 2799
2800 return CMD_SUCCESS;
2e3b2e47 2801}
2802
2803
2804DEFUN (no_linkdetect,
2805 no_linkdetect_cmd,
2806 "no link-detect",
2807 NO_STR
2808 "Disable link detection on interface\n")
2809{
d62a17ae 2810 VTY_DECLVAR_CONTEXT(interface, ifp);
d62a17ae 2811
09268680
CS
2812 if_linkdetect(ifp, false);
2813
2814 return CMD_SUCCESS;
2815}
2e3b2e47 2816
09268680
CS
2817int if_shutdown(struct interface *ifp)
2818{
2819 struct zebra_if *if_data;
2e3b2e47 2820
09268680
CS
2821 if (ifp->ifindex != IFINDEX_INTERNAL) {
2822 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
2823 rtadv_stop_ra(ifp);
2824 if (if_unset_flags(ifp, IFF_UP) < 0) {
2825 zlog_debug("Can't shutdown interface %s", ifp->name);
2826 return -1;
2827 }
2828 if_refresh(ifp);
2829 }
2830 if_data = ifp->info;
2831 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
2e3b2e47 2832
09268680 2833 return 0;
2e3b2e47 2834}
2835
718e3744 2836DEFUN (shutdown_if,
2837 shutdown_if_cmd,
2838 "shutdown",
2839 "Shutdown the selected interface\n")
2840{
d62a17ae 2841 VTY_DECLVAR_CONTEXT(interface, ifp);
2842 int ret;
2843 struct zebra_if *if_data;
718e3744 2844
d62a17ae 2845 if (ifp->ifindex != IFINDEX_INTERNAL) {
d7fc0e67
DS
2846 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
2847 rtadv_stop_ra(ifp);
d62a17ae 2848 ret = if_unset_flags(ifp, IFF_UP);
2849 if (ret < 0) {
2850 vty_out(vty, "Can't shutdown interface\n");
2851 return CMD_WARNING_CONFIG_FAILED;
2852 }
2853 if_refresh(ifp);
2854 }
2855 if_data = ifp->info;
2856 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
718e3744 2857
d62a17ae 2858 return CMD_SUCCESS;
718e3744 2859}
2860
09268680
CS
2861int if_no_shutdown(struct interface *ifp)
2862{
2863 struct zebra_if *if_data;
2864
2865 if (ifp->ifindex != IFINDEX_INTERNAL) {
2866 if (if_set_flags(ifp, IFF_UP | IFF_RUNNING) < 0) {
2867 zlog_debug("Can't up interface %s", ifp->name);
2868 return -1;
2869 }
2870 if_refresh(ifp);
2871
2872 /* Some addresses (in particular, IPv6 addresses on Linux) get
2873 * removed when the interface goes down. They need to be
2874 * readded.
2875 */
2876 if_addr_wakeup(ifp);
2877 }
2878
2879 if_data = ifp->info;
2880 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
2881
2882 return 0;
2883}
2884
718e3744 2885DEFUN (no_shutdown_if,
2886 no_shutdown_if_cmd,
2887 "no shutdown",
2888 NO_STR
2889 "Shutdown the selected interface\n")
2890{
d62a17ae 2891 VTY_DECLVAR_CONTEXT(interface, ifp);
2892 int ret;
2893 struct zebra_if *if_data;
718e3744 2894
d62a17ae 2895 if (ifp->ifindex != IFINDEX_INTERNAL) {
2896 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2897 if (ret < 0) {
2898 vty_out(vty, "Can't up interface\n");
2899 return CMD_WARNING_CONFIG_FAILED;
2900 }
2901 if_refresh(ifp);
bfac8dcd 2902
d62a17ae 2903 /* Some addresses (in particular, IPv6 addresses on Linux) get
2904 * removed when the interface goes down. They need to be
2905 * readded.
2906 */
2907 if_addr_wakeup(ifp);
2908 }
bfac8dcd 2909
d62a17ae 2910 if_data = ifp->info;
2911 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
718e3744 2912
d62a17ae 2913 return CMD_SUCCESS;
718e3744 2914}
2915
2916DEFUN (bandwidth_if,
2917 bandwidth_if_cmd,
6147e2c6 2918 "bandwidth (1-100000)",
718e3744 2919 "Set bandwidth informational parameter\n"
70bd3c43 2920 "Bandwidth in megabits\n")
718e3744 2921{
d62a17ae 2922 int idx_number = 1;
2923 VTY_DECLVAR_CONTEXT(interface, ifp);
2924 unsigned int bandwidth;
2925
2926 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
2927
2928 /* bandwidth range is <1-100000> */
2929 if (bandwidth < 1 || bandwidth > 100000) {
2930 vty_out(vty, "Bandwidth is invalid\n");
2931 return CMD_WARNING_CONFIG_FAILED;
2932 }
2933
2934 ifp->bandwidth = bandwidth;
718e3744 2935
d62a17ae 2936 /* force protocols to recalculate routes due to cost change */
2937 if (if_is_operative(ifp))
2938 zebra_interface_up_update(ifp);
718e3744 2939
d62a17ae 2940 return CMD_SUCCESS;
718e3744 2941}
2942
2943DEFUN (no_bandwidth_if,
2944 no_bandwidth_if_cmd,
b62ecea5 2945 "no bandwidth [(1-100000)]",
718e3744 2946 NO_STR
b62ecea5
QY
2947 "Set bandwidth informational parameter\n"
2948 "Bandwidth in megabits\n")
718e3744 2949{
d62a17ae 2950 VTY_DECLVAR_CONTEXT(interface, ifp);
718e3744 2951
d62a17ae 2952 ifp->bandwidth = 0;
718e3744 2953
d62a17ae 2954 /* force protocols to recalculate routes due to cost change */
2955 if (if_is_operative(ifp))
2956 zebra_interface_up_update(ifp);
2957
2958 return CMD_SUCCESS;
718e3744 2959}
2960
6b0655a2 2961
d62a17ae 2962struct cmd_node link_params_node = {
f4b8291f 2963 .name = "link-params",
62b346ee 2964 .node = LINK_PARAMS_NODE,
24389580 2965 .parent_node = INTERFACE_NODE,
62b346ee 2966 .prompt = "%s(config-link-params)# ",
dd2c81b8 2967 .no_xpath = true,
16f1b9ee
OD
2968};
2969
d62a17ae 2970static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
2971 uint32_t type, uint32_t value)
16f1b9ee 2972{
d62a17ae 2973 /* Update field as needed */
2974 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
2975 *field = value;
2976 SET_PARAM(ifp->link_params, type);
16f1b9ee 2977
d62a17ae 2978 /* force protocols to update LINK STATE due to parameters change
2979 */
2980 if (if_is_operative(ifp))
2981 zebra_interface_parameters_update(ifp);
2982 }
16f1b9ee 2983}
d62a17ae 2984static void link_param_cmd_set_float(struct interface *ifp, float *field,
2985 uint32_t type, float value)
16f1b9ee
OD
2986{
2987
d62a17ae 2988 /* Update field as needed */
2989 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
2990 *field = value;
2991 SET_PARAM(ifp->link_params, type);
16f1b9ee 2992
d62a17ae 2993 /* force protocols to update LINK STATE due to parameters change
2994 */
2995 if (if_is_operative(ifp))
2996 zebra_interface_parameters_update(ifp);
2997 }
16f1b9ee
OD
2998}
2999
d62a17ae 3000static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
16f1b9ee 3001{
d62a17ae 3002 if (ifp->link_params == NULL)
3003 return;
16f1b9ee 3004
d62a17ae 3005 /* Unset field */
3006 UNSET_PARAM(ifp->link_params, type);
16f1b9ee 3007
d62a17ae 3008 /* force protocols to update LINK STATE due to parameters change */
3009 if (if_is_operative(ifp))
3010 zebra_interface_parameters_update(ifp);
16f1b9ee
OD
3011}
3012
505e5056 3013DEFUN_NOSH (link_params,
16f1b9ee
OD
3014 link_params_cmd,
3015 "link-params",
3016 LINK_PARAMS_STR)
3017{
d62a17ae 3018 /* vty->qobj_index stays the same @ interface pointer */
3019 vty->node = LINK_PARAMS_NODE;
16f1b9ee 3020
d62a17ae 3021 return CMD_SUCCESS;
16f1b9ee
OD
3022}
3023
505e5056 3024DEFUN_NOSH (exit_link_params,
03f99d9a
DS
3025 exit_link_params_cmd,
3026 "exit-link-params",
3027 "Exit from Link Params configuration mode\n")
3028{
d62a17ae 3029 if (vty->node == LINK_PARAMS_NODE)
3030 vty->node = INTERFACE_NODE;
3031 return CMD_SUCCESS;
03f99d9a
DS
3032}
3033
16f1b9ee
OD
3034/* Specific Traffic Engineering parameters commands */
3035DEFUN (link_params_enable,
3036 link_params_enable_cmd,
3037 "enable",
3038 "Activate link parameters on this interface\n")
3039{
d62a17ae 3040 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3041
d62a17ae 3042 /* This command could be issue at startup, when activate MPLS TE */
3043 /* on a new interface or after a ON / OFF / ON toggle */
3044 /* In all case, TE parameters are reset to their default factory */
14a4d9d0 3045 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
d62a17ae 3046 zlog_debug(
3047 "Link-params: enable TE link parameters on interface %s",
3048 ifp->name);
16f1b9ee 3049
d62a17ae 3050 if (!if_link_params_get(ifp)) {
14a4d9d0 3051 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
d62a17ae 3052 zlog_debug(
3053 "Link-params: failed to init TE link parameters %s",
3054 ifp->name);
16f1b9ee 3055
d62a17ae 3056 return CMD_WARNING_CONFIG_FAILED;
3057 }
16f1b9ee 3058
d62a17ae 3059 /* force protocols to update LINK STATE due to parameters change */
3060 if (if_is_operative(ifp))
3061 zebra_interface_parameters_update(ifp);
16f1b9ee 3062
d62a17ae 3063 return CMD_SUCCESS;
16f1b9ee
OD
3064}
3065
3066DEFUN (no_link_params_enable,
3067 no_link_params_enable_cmd,
3068 "no enable",
3069 NO_STR
3070 "Disable link parameters on this interface\n")
3071{
d62a17ae 3072 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3073
14a4d9d0 3074 if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
3075 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
3076 ifp->name);
16f1b9ee 3077
d62a17ae 3078 if_link_params_free(ifp);
16f1b9ee 3079
d62a17ae 3080 /* force protocols to update LINK STATE due to parameters change */
3081 if (if_is_operative(ifp))
3082 zebra_interface_parameters_update(ifp);
16f1b9ee 3083
d62a17ae 3084 return CMD_SUCCESS;
16f1b9ee
OD
3085}
3086
3087/* STANDARD TE metrics */
3088DEFUN (link_params_metric,
3089 link_params_metric_cmd,
6147e2c6 3090 "metric (0-4294967295)",
16f1b9ee
OD
3091 "Link metric for MPLS-TE purpose\n"
3092 "Metric value in decimal\n")
3093{
d62a17ae 3094 int idx_number = 1;
3095 VTY_DECLVAR_CONTEXT(interface, ifp);
3096 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 3097 uint32_t metric;
16f1b9ee 3098
d62a17ae 3099 metric = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 3100
d62a17ae 3101 /* Update TE metric if needed */
3102 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee 3103
d62a17ae 3104 return CMD_SUCCESS;
16f1b9ee
OD
3105}
3106
3107DEFUN (no_link_params_metric,
3108 no_link_params_metric_cmd,
3109 "no metric",
3110 NO_STR
3ddccf18 3111 "Disable Link Metric on this interface\n")
16f1b9ee 3112{
d62a17ae 3113 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3114
d62a17ae 3115 /* Unset TE Metric */
3116 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee 3117
d62a17ae 3118 return CMD_SUCCESS;
16f1b9ee
OD
3119}
3120
3121DEFUN (link_params_maxbw,
3122 link_params_maxbw_cmd,
3123 "max-bw BANDWIDTH",
3124 "Maximum bandwidth that can be used\n"
3125 "Bytes/second (IEEE floating point format)\n")
3126{
d62a17ae 3127 int idx_bandwidth = 1;
3128 VTY_DECLVAR_CONTEXT(interface, ifp);
3129 struct if_link_params *iflp = if_link_params_get(ifp);
3130
3131 float bw;
3132
3133 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3134 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
3135 safe_strerror(errno));
3136 return CMD_WARNING_CONFIG_FAILED;
3137 }
3138
3139 /* Check that Maximum bandwidth is not lower than other bandwidth
3140 * parameters */
3141 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
3142 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
3143 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
3144 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
3145 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
3146 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
3147 vty_out(vty,
3148 "Maximum Bandwidth could not be lower than others bandwidth\n");
3149 return CMD_WARNING_CONFIG_FAILED;
3150 }
3151
3152 /* Update Maximum Bandwidth if needed */
3153 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
3154
3155 return CMD_SUCCESS;
16f1b9ee
OD
3156}
3157
3158DEFUN (link_params_max_rsv_bw,
3159 link_params_max_rsv_bw_cmd,
3160 "max-rsv-bw BANDWIDTH",
3161 "Maximum bandwidth that may be reserved\n"
3162 "Bytes/second (IEEE floating point format)\n")
3163{
d62a17ae 3164 int idx_bandwidth = 1;
3165 VTY_DECLVAR_CONTEXT(interface, ifp);
3166 struct if_link_params *iflp = if_link_params_get(ifp);
3167 float bw;
16f1b9ee 3168
d62a17ae 3169 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3170 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
3171 safe_strerror(errno));
3172 return CMD_WARNING_CONFIG_FAILED;
3173 }
16f1b9ee 3174
d62a17ae 3175 /* Check that bandwidth is not greater than maximum bandwidth parameter
3176 */
3177 if (bw > iflp->max_bw) {
3178 vty_out(vty,
3179 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3180 iflp->max_bw);
3181 return CMD_WARNING_CONFIG_FAILED;
3182 }
16f1b9ee 3183
d62a17ae 3184 /* Update Maximum Reservable Bandwidth if needed */
3185 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
16f1b9ee 3186
d62a17ae 3187 return CMD_SUCCESS;
16f1b9ee
OD
3188}
3189
3190DEFUN (link_params_unrsv_bw,
3191 link_params_unrsv_bw_cmd,
6147e2c6 3192 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
3193 "Unreserved bandwidth at each priority level\n"
3194 "Priority\n"
3195 "Bytes/second (IEEE floating point format)\n")
3196{
d62a17ae 3197 int idx_number = 1;
3198 int idx_bandwidth = 2;
3199 VTY_DECLVAR_CONTEXT(interface, ifp);
3200 struct if_link_params *iflp = if_link_params_get(ifp);
3201 int priority;
3202 float bw;
3203
3204 /* We don't have to consider about range check here. */
3205 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
3206 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
3207 safe_strerror(errno));
3208 return CMD_WARNING_CONFIG_FAILED;
3209 }
3210
3211 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3212 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
3213 safe_strerror(errno));
3214 return CMD_WARNING_CONFIG_FAILED;
3215 }
3216
3217 /* Check that bandwidth is not greater than maximum bandwidth parameter
3218 */
3219 if (bw > iflp->max_bw) {
3220 vty_out(vty,
3221 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3222 iflp->max_bw);
3223 return CMD_WARNING_CONFIG_FAILED;
3224 }
3225
3226 /* Update Unreserved Bandwidth if needed */
3227 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
3228 bw);
3229
3230 return CMD_SUCCESS;
16f1b9ee
OD
3231}
3232
3233DEFUN (link_params_admin_grp,
3234 link_params_admin_grp_cmd,
3235 "admin-grp BITPATTERN",
3236 "Administrative group membership\n"
3237 "32-bit Hexadecimal value (e.g. 0xa1)\n")
3238{
d62a17ae 3239 int idx_bitpattern = 1;
3240 VTY_DECLVAR_CONTEXT(interface, ifp);
3241 struct if_link_params *iflp = if_link_params_get(ifp);
3242 unsigned long value;
16f1b9ee 3243
d62a17ae 3244 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
3245 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
3246 safe_strerror(errno));
3247 return CMD_WARNING_CONFIG_FAILED;
3248 }
16f1b9ee 3249
d62a17ae 3250 /* Update Administrative Group if needed */
3251 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
16f1b9ee 3252
d62a17ae 3253 return CMD_SUCCESS;
16f1b9ee
OD
3254}
3255
3256DEFUN (no_link_params_admin_grp,
3257 no_link_params_admin_grp_cmd,
3258 "no admin-grp",
3259 NO_STR
3ddccf18 3260 "Disable Administrative group membership on this interface\n")
16f1b9ee 3261{
d62a17ae 3262 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3263
d62a17ae 3264 /* Unset Admin Group */
3265 link_param_cmd_unset(ifp, LP_ADM_GRP);
16f1b9ee 3266
d62a17ae 3267 return CMD_SUCCESS;
16f1b9ee
OD
3268}
3269
3270/* RFC5392 & RFC5316: INTER-AS */
3271DEFUN (link_params_inter_as,
3272 link_params_inter_as_cmd,
6147e2c6 3273 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
3274 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
3275 "Remote IP address in dot decimal A.B.C.D\n"
3276 "Remote AS number\n"
3277 "AS number in the range <1-4294967295>\n")
3278{
d62a17ae 3279 int idx_ipv4 = 1;
3280 int idx_number = 3;
16f1b9ee 3281
d62a17ae 3282 VTY_DECLVAR_CONTEXT(interface, ifp);
3283 struct if_link_params *iflp = if_link_params_get(ifp);
3284 struct in_addr addr;
d7c0a89a 3285 uint32_t as;
16f1b9ee 3286
d62a17ae 3287 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
3288 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
3289 return CMD_WARNING_CONFIG_FAILED;
3290 }
16f1b9ee 3291
d62a17ae 3292 as = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 3293
d62a17ae 3294 /* Update Remote IP and Remote AS fields if needed */
3295 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
3296 || iflp->rmt_ip.s_addr != addr.s_addr) {
16f1b9ee 3297
d62a17ae 3298 iflp->rmt_as = as;
3299 iflp->rmt_ip.s_addr = addr.s_addr;
3300 SET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 3301
d62a17ae 3302 /* force protocols to update LINK STATE due to parameters change
3303 */
3304 if (if_is_operative(ifp))
3305 zebra_interface_parameters_update(ifp);
3306 }
3307 return CMD_SUCCESS;
16f1b9ee
OD
3308}
3309
3310DEFUN (no_link_params_inter_as,
3311 no_link_params_inter_as_cmd,
3312 "no neighbor",
3313 NO_STR
3314 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
3315{
d62a17ae 3316 VTY_DECLVAR_CONTEXT(interface, ifp);
3317 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 3318
d62a17ae 3319 /* Reset Remote IP and AS neighbor */
3320 iflp->rmt_as = 0;
3321 iflp->rmt_ip.s_addr = 0;
3322 UNSET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 3323
d62a17ae 3324 /* force protocols to update LINK STATE due to parameters change */
3325 if (if_is_operative(ifp))
3326 zebra_interface_parameters_update(ifp);
16f1b9ee 3327
d62a17ae 3328 return CMD_SUCCESS;
16f1b9ee
OD
3329}
3330
d62a17ae 3331/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
3332 * draft-ietf-isis-metric-extensions-07.txt */
16f1b9ee
OD
3333DEFUN (link_params_delay,
3334 link_params_delay_cmd,
b62ecea5 3335 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 3336 "Unidirectional Average Link Delay\n"
b62ecea5
QY
3337 "Average delay in micro-second as decimal (0...16777215)\n"
3338 "Minimum delay\n"
3339 "Minimum delay in micro-second as decimal (0...16777215)\n"
3340 "Maximum delay\n"
3341 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 3342{
d62a17ae 3343 /* Get and Check new delay values */
d7c0a89a 3344 uint32_t delay = 0, low = 0, high = 0;
d62a17ae 3345 delay = strtoul(argv[1]->arg, NULL, 10);
3346 if (argc == 6) {
3347 low = strtoul(argv[3]->arg, NULL, 10);
3348 high = strtoul(argv[5]->arg, NULL, 10);
3349 }
3350
3351 VTY_DECLVAR_CONTEXT(interface, ifp);
3352 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 3353 uint8_t update = 0;
d62a17ae 3354
3355 if (argc == 2) {
3356 /* Check new delay value against old Min and Max delays if set
3357 */
3358 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
3359 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
3360 vty_out(vty,
3361 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
3362 iflp->min_delay, iflp->max_delay);
3363 return CMD_WARNING_CONFIG_FAILED;
3364 }
3365 /* Update delay if value is not set or change */
3366 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
3367 iflp->av_delay = delay;
3368 SET_PARAM(iflp, LP_DELAY);
3369 update = 1;
3370 }
3371 /* Unset Min and Max delays if already set */
3372 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
3373 iflp->min_delay = 0;
3374 iflp->max_delay = 0;
3375 UNSET_PARAM(iflp, LP_MM_DELAY);
3376 update = 1;
3377 }
3378 } else {
3379 /* Check new delays value coherency */
3380 if (delay <= low || delay >= high) {
3381 vty_out(vty,
3382 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
3383 low, high);
3384 return CMD_WARNING_CONFIG_FAILED;
3385 }
3386 /* Update Delays if needed */
3387 if (IS_PARAM_UNSET(iflp, LP_DELAY)
3388 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
3389 || iflp->av_delay != delay || iflp->min_delay != low
3390 || iflp->max_delay != high) {
3391 iflp->av_delay = delay;
3392 SET_PARAM(iflp, LP_DELAY);
3393 iflp->min_delay = low;
3394 iflp->max_delay = high;
3395 SET_PARAM(iflp, LP_MM_DELAY);
3396 update = 1;
3397 }
3398 }
3399
3400 /* force protocols to update LINK STATE due to parameters change */
3401 if (update == 1 && if_is_operative(ifp))
3402 zebra_interface_parameters_update(ifp);
3403
3404 return CMD_SUCCESS;
16f1b9ee
OD
3405}
3406
16f1b9ee
OD
3407DEFUN (no_link_params_delay,
3408 no_link_params_delay_cmd,
3409 "no delay",
3410 NO_STR
3ddccf18 3411 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 3412{
d62a17ae 3413 VTY_DECLVAR_CONTEXT(interface, ifp);
3414 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 3415
d62a17ae 3416 /* Unset Delays */
3417 iflp->av_delay = 0;
3418 UNSET_PARAM(iflp, LP_DELAY);
3419 iflp->min_delay = 0;
3420 iflp->max_delay = 0;
3421 UNSET_PARAM(iflp, LP_MM_DELAY);
16f1b9ee 3422
d62a17ae 3423 /* force protocols to update LINK STATE due to parameters change */
3424 if (if_is_operative(ifp))
3425 zebra_interface_parameters_update(ifp);
16f1b9ee 3426
d62a17ae 3427 return CMD_SUCCESS;
16f1b9ee
OD
3428}
3429
3430DEFUN (link_params_delay_var,
3431 link_params_delay_var_cmd,
6147e2c6 3432 "delay-variation (0-16777215)",
16f1b9ee
OD
3433 "Unidirectional Link Delay Variation\n"
3434 "delay variation in micro-second as decimal (0...16777215)\n")
3435{
d62a17ae 3436 int idx_number = 1;
3437 VTY_DECLVAR_CONTEXT(interface, ifp);
3438 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 3439 uint32_t value;
16f1b9ee 3440
d62a17ae 3441 value = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 3442
d62a17ae 3443 /* Update Delay Variation if needed */
3444 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
16f1b9ee 3445
d62a17ae 3446 return CMD_SUCCESS;
16f1b9ee
OD
3447}
3448
3449DEFUN (no_link_params_delay_var,
3450 no_link_params_delay_var_cmd,
3451 "no delay-variation",
3452 NO_STR
3ddccf18 3453 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 3454{
d62a17ae 3455 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3456
d62a17ae 3457 /* Unset Delay Variation */
3458 link_param_cmd_unset(ifp, LP_DELAY_VAR);
16f1b9ee 3459
d62a17ae 3460 return CMD_SUCCESS;
16f1b9ee
OD
3461}
3462
3463DEFUN (link_params_pkt_loss,
3464 link_params_pkt_loss_cmd,
3465 "packet-loss PERCENTAGE",
3466 "Unidirectional Link Packet Loss\n"
3467 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
3468{
d62a17ae 3469 int idx_percentage = 1;
3470 VTY_DECLVAR_CONTEXT(interface, ifp);
3471 struct if_link_params *iflp = if_link_params_get(ifp);
3472 float fval;
16f1b9ee 3473
d62a17ae 3474 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
3475 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
3476 safe_strerror(errno));
3477 return CMD_WARNING_CONFIG_FAILED;
3478 }
16f1b9ee 3479
d62a17ae 3480 if (fval > MAX_PKT_LOSS)
3481 fval = MAX_PKT_LOSS;
16f1b9ee 3482
d62a17ae 3483 /* Update Packet Loss if needed */
3484 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
16f1b9ee 3485
d62a17ae 3486 return CMD_SUCCESS;
16f1b9ee
OD
3487}
3488
3489DEFUN (no_link_params_pkt_loss,
3490 no_link_params_pkt_loss_cmd,
3491 "no packet-loss",
3492 NO_STR
3ddccf18 3493 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 3494{
d62a17ae 3495 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3496
d62a17ae 3497 /* Unset Packet Loss */
3498 link_param_cmd_unset(ifp, LP_PKT_LOSS);
16f1b9ee 3499
d62a17ae 3500 return CMD_SUCCESS;
16f1b9ee
OD
3501}
3502
3503DEFUN (link_params_res_bw,
3504 link_params_res_bw_cmd,
3505 "res-bw BANDWIDTH",
3506 "Unidirectional Residual Bandwidth\n"
3507 "Bytes/second (IEEE floating point format)\n")
3508{
d62a17ae 3509 int idx_bandwidth = 1;
3510 VTY_DECLVAR_CONTEXT(interface, ifp);
3511 struct if_link_params *iflp = if_link_params_get(ifp);
3512 float bw;
16f1b9ee 3513
d62a17ae 3514 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3515 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
3516 safe_strerror(errno));
3517 return CMD_WARNING_CONFIG_FAILED;
3518 }
16f1b9ee 3519
d62a17ae 3520 /* Check that bandwidth is not greater than maximum bandwidth parameter
3521 */
3522 if (bw > iflp->max_bw) {
3523 vty_out(vty,
3524 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3525 iflp->max_bw);
3526 return CMD_WARNING_CONFIG_FAILED;
3527 }
16f1b9ee 3528
d62a17ae 3529 /* Update Residual Bandwidth if needed */
3530 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
16f1b9ee 3531
d62a17ae 3532 return CMD_SUCCESS;
16f1b9ee
OD
3533}
3534
3535DEFUN (no_link_params_res_bw,
3536 no_link_params_res_bw_cmd,
3537 "no res-bw",
3538 NO_STR
3ddccf18 3539 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 3540{
d62a17ae 3541 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3542
d62a17ae 3543 /* Unset Residual Bandwidth */
3544 link_param_cmd_unset(ifp, LP_RES_BW);
16f1b9ee 3545
d62a17ae 3546 return CMD_SUCCESS;
16f1b9ee
OD
3547}
3548
3549DEFUN (link_params_ava_bw,
3550 link_params_ava_bw_cmd,
3551 "ava-bw BANDWIDTH",
3552 "Unidirectional Available Bandwidth\n"
3553 "Bytes/second (IEEE floating point format)\n")
3554{
d62a17ae 3555 int idx_bandwidth = 1;
3556 VTY_DECLVAR_CONTEXT(interface, ifp);
3557 struct if_link_params *iflp = if_link_params_get(ifp);
3558 float bw;
16f1b9ee 3559
d62a17ae 3560 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3561 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
3562 safe_strerror(errno));
3563 return CMD_WARNING_CONFIG_FAILED;
3564 }
16f1b9ee 3565
d62a17ae 3566 /* Check that bandwidth is not greater than maximum bandwidth parameter
3567 */
3568 if (bw > iflp->max_bw) {
3569 vty_out(vty,
3570 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3571 iflp->max_bw);
3572 return CMD_WARNING_CONFIG_FAILED;
3573 }
16f1b9ee 3574
d62a17ae 3575 /* Update Residual Bandwidth if needed */
3576 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
16f1b9ee 3577
d62a17ae 3578 return CMD_SUCCESS;
16f1b9ee
OD
3579}
3580
3581DEFUN (no_link_params_ava_bw,
3582 no_link_params_ava_bw_cmd,
3583 "no ava-bw",
3584 NO_STR
3ddccf18 3585 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 3586{
d62a17ae 3587 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3588
d62a17ae 3589 /* Unset Available Bandwidth */
3590 link_param_cmd_unset(ifp, LP_AVA_BW);
16f1b9ee 3591
d62a17ae 3592 return CMD_SUCCESS;
16f1b9ee
OD
3593}
3594
3595DEFUN (link_params_use_bw,
3596 link_params_use_bw_cmd,
3597 "use-bw BANDWIDTH",
3598 "Unidirectional Utilised Bandwidth\n"
3599 "Bytes/second (IEEE floating point format)\n")
3600{
d62a17ae 3601 int idx_bandwidth = 1;
3602 VTY_DECLVAR_CONTEXT(interface, ifp);
3603 struct if_link_params *iflp = if_link_params_get(ifp);
3604 float bw;
16f1b9ee 3605
d62a17ae 3606 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
3607 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
3608 safe_strerror(errno));
3609 return CMD_WARNING_CONFIG_FAILED;
3610 }
16f1b9ee 3611
d62a17ae 3612 /* Check that bandwidth is not greater than maximum bandwidth parameter
3613 */
3614 if (bw > iflp->max_bw) {
3615 vty_out(vty,
3616 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
3617 iflp->max_bw);
3618 return CMD_WARNING_CONFIG_FAILED;
3619 }
16f1b9ee 3620
d62a17ae 3621 /* Update Utilized Bandwidth if needed */
3622 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
16f1b9ee 3623
d62a17ae 3624 return CMD_SUCCESS;
16f1b9ee
OD
3625}
3626
3627DEFUN (no_link_params_use_bw,
3628 no_link_params_use_bw_cmd,
3629 "no use-bw",
3630 NO_STR
3ddccf18 3631 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 3632{
d62a17ae 3633 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 3634
d62a17ae 3635 /* Unset Utilised Bandwidth */
3636 link_param_cmd_unset(ifp, LP_USE_BW);
16f1b9ee 3637
d62a17ae 3638 return CMD_SUCCESS;
16f1b9ee
OD
3639}
3640
09268680
CS
3641int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
3642 const char *label, struct prefix *pp)
3643{
3644 struct zebra_if *if_data;
3645 struct prefix_ipv4 lp;
3646 struct prefix_ipv4 *p;
3647 struct connected *ifc;
3648 enum zebra_dplane_result dplane_res;
3649
3650 if_data = ifp->info;
3651
3652 lp.family = prefix->family;
3653 lp.prefix = prefix->u.prefix4;
3654 lp.prefixlen = prefix->prefixlen;
3655 apply_mask_ipv4(&lp);
3656
3657 ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL);
3658 if (!ifc) {
3659 ifc = connected_new();
3660 ifc->ifp = ifp;
3661
3662 /* Address. */
3663 p = prefix_ipv4_new();
3664 *p = lp;
3665 ifc->address = (struct prefix *)p;
3666
3667 if (pp) {
3668 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
3669 p = prefix_ipv4_new();
3670 *p = *(struct prefix_ipv4 *)pp;
3671 ifc->destination = (struct prefix *)p;
3672 }
3673
3674 /* Label. */
3675 if (label)
3676 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
3677
3678 /* Add to linked list. */
3679 listnode_add(ifp->connected, ifc);
3680 }
3681
3682 /* This address is configured from zebra. */
3683 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
3684 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3685
3686 /* In case of this route need to install kernel. */
3687 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
3688 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
3689 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
3690 /* Some system need to up the interface to set IP address. */
3691 if (!if_is_up(ifp)) {
3692 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
3693 if_refresh(ifp);
3694 }
3695
3696 dplane_res = dplane_intf_addr_set(ifp, ifc);
3697 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
3698 zlog_debug(
1d5453d6 3699 "dplane can't set interface IP address: %s.",
09268680
CS
3700 dplane_res2str(dplane_res));
3701 return NB_ERR;
3702 }
3703
3704 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3705 /* The address will be advertised to zebra clients when the
3706 * notification
3707 * from the kernel has been received.
3708 * It will also be added to the subnet chain list, then. */
3709 }
3710
3711 return 0;
3712}
3713
d62a17ae 3714static int ip_address_install(struct vty *vty, struct interface *ifp,
3715 const char *addr_str, const char *peer_str,
3716 const char *label)
718e3744 3717{
d62a17ae 3718 struct zebra_if *if_data;
a07df329 3719 struct prefix_ipv4 lp, pp;
d62a17ae 3720 struct connected *ifc;
3721 struct prefix_ipv4 *p;
3722 int ret;
64168803 3723 enum zebra_dplane_result dplane_res;
718e3744 3724
d62a17ae 3725 if_data = ifp->info;
bfac8dcd 3726
a07df329 3727 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 3728 if (ret <= 0) {
3729 vty_out(vty, "%% Malformed address \n");
3730 return CMD_WARNING_CONFIG_FAILED;
3731 }
718e3744 3732
a07df329 3733 if (ipv4_martian(&lp.prefix)) {
d62a17ae 3734 vty_out(vty, "%% Invalid address\n");
3735 return CMD_WARNING_CONFIG_FAILED;
3736 }
d914d5ff 3737
a07df329 3738 if (peer_str) {
12256b84 3739 if (lp.prefixlen != IPV4_MAX_BITLEN) {
a07df329
DL
3740 vty_out(vty,
3741 "%% Local prefix length for P-t-P address must be /32\n");
3742 return CMD_WARNING_CONFIG_FAILED;
3743 }
3744
3745 ret = str2prefix_ipv4(peer_str, &pp);
3746 if (ret <= 0) {
3747 vty_out(vty, "%% Malformed peer address\n");
3748 return CMD_WARNING_CONFIG_FAILED;
3749 }
3750 }
3751
3752 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 3753 if (!ifc) {
3754 ifc = connected_new();
3755 ifc->ifp = ifp;
3756
3757 /* Address. */
3758 p = prefix_ipv4_new();
a07df329 3759 *p = lp;
d62a17ae 3760 ifc->address = (struct prefix *)p;
3761
a07df329
DL
3762 if (peer_str) {
3763 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
3764 p = prefix_ipv4_new();
3765 *p = pp;
3766 ifc->destination = (struct prefix *)p;
d62a17ae 3767 }
718e3744 3768
d62a17ae 3769 /* Label. */
3770 if (label)
3771 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
718e3744 3772
d62a17ae 3773 /* Add to linked list. */
3774 listnode_add(ifp->connected, ifc);
718e3744 3775 }
3776
d62a17ae 3777 /* This address is configured from zebra. */
3778 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
3779 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3780
3781 /* In case of this route need to install kernel. */
3782 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
3783 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
3784 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
3785 /* Some system need to up the interface to set IP address. */
3786 if (!if_is_up(ifp)) {
3787 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
3788 if_refresh(ifp);
3789 }
3790
64168803
MS
3791 dplane_res = dplane_intf_addr_set(ifp, ifc);
3792 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
d62a17ae 3793 vty_out(vty, "%% Can't set interface IP address: %s.\n",
64168803 3794 dplane_res2str(dplane_res));
d62a17ae 3795 return CMD_WARNING_CONFIG_FAILED;
3796 }
3797
3798 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3799 /* The address will be advertised to zebra clients when the
3800 * notification
3801 * from the kernel has been received.
3802 * It will also be added to the subnet chain list, then. */
3803 }
3804
3805 return CMD_SUCCESS;
3806}
3807
09268680
CS
3808int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix)
3809{
3810 struct connected *ifc = NULL;
3811 enum zebra_dplane_result dplane_res;
3812
3813 if (prefix->family == AF_INET) {
3814 /* Check current interface address. */
3815 ifc = connected_check_ptp(ifp, prefix, NULL);
3816 if (!ifc) {
1d5453d6 3817 zlog_debug("interface %s Can't find address",
09268680
CS
3818 ifp->name);
3819 return -1;
3820 }
3821
3822 } else if (prefix->family == AF_INET6) {
3823 /* Check current interface address. */
3824 ifc = connected_check(ifp, prefix);
3825 }
3826
3827 if (!ifc) {
1d5453d6 3828 zlog_debug("interface %s Can't find address", ifp->name);
09268680
CS
3829 return -1;
3830 }
3831 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3832
3833 /* This is not real address or interface is not active. */
3834 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
3835 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
3836 listnode_delete(ifp->connected, ifc);
3837 connected_free(&ifc);
3838 return CMD_WARNING_CONFIG_FAILED;
3839 }
3840
3841 /* This is real route. */
3842 dplane_res = dplane_intf_addr_unset(ifp, ifc);
3843 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
1d5453d6 3844 zlog_debug("Can't unset interface IP address: %s.",
09268680
CS
3845 dplane_res2str(dplane_res));
3846 return -1;
3847 }
3848 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3849
3850 return 0;
3851}
3852
d62a17ae 3853static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
3854 const char *addr_str, const char *peer_str,
3855 const char *label)
3856{
a07df329 3857 struct prefix_ipv4 lp, pp;
d62a17ae 3858 struct connected *ifc;
3859 int ret;
64168803 3860 enum zebra_dplane_result dplane_res;
d62a17ae 3861
3862 /* Convert to prefix structure. */
a07df329 3863 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 3864 if (ret <= 0) {
3865 vty_out(vty, "%% Malformed address \n");
3866 return CMD_WARNING_CONFIG_FAILED;
3867 }
3868
a07df329 3869 if (peer_str) {
12256b84 3870 if (lp.prefixlen != IPV4_MAX_BITLEN) {
a07df329
DL
3871 vty_out(vty,
3872 "%% Local prefix length for P-t-P address must be /32\n");
3873 return CMD_WARNING_CONFIG_FAILED;
3874 }
3875
3876 ret = str2prefix_ipv4(peer_str, &pp);
3877 if (ret <= 0) {
3878 vty_out(vty, "%% Malformed peer address\n");
3879 return CMD_WARNING_CONFIG_FAILED;
3880 }
3881 }
3882
d62a17ae 3883 /* Check current interface address. */
a07df329 3884 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 3885 if (!ifc) {
3886 vty_out(vty, "%% Can't find address\n");
3887 return CMD_WARNING_CONFIG_FAILED;
3888 }
3889
3890 /* This is not configured address. */
3891 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
3892 return CMD_WARNING_CONFIG_FAILED;
3893
3894 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
3895
3896 /* This is not real address or interface is not active. */
3897 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
3898 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
3899 listnode_delete(ifp->connected, ifc);
721c0857 3900 connected_free(&ifc);
d62a17ae 3901 return CMD_WARNING_CONFIG_FAILED;
3902 }
3903
3904 /* This is real route. */
64168803
MS
3905 dplane_res = dplane_intf_addr_unset(ifp, ifc);
3906 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
d62a17ae 3907 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
64168803 3908 dplane_res2str(dplane_res));
d62a17ae 3909 return CMD_WARNING_CONFIG_FAILED;
3910 }
3911 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3912 /* we will receive a kernel notification about this route being removed.
3913 * this will trigger its removal from the connected list. */
3914 return CMD_SUCCESS;
718e3744 3915}
3916
3917DEFUN (ip_address,
3918 ip_address_cmd,
3919 "ip address A.B.C.D/M",
3920 "Interface Internet Protocol config commands\n"
3921 "Set the IP address of an interface\n"
3922 "IP address (e.g. 10.0.0.1/8)\n")
3923{
d62a17ae 3924 int idx_ipv4_prefixlen = 2;
3925 VTY_DECLVAR_CONTEXT(interface, ifp);
3926 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
3927 NULL);
718e3744 3928}
3929
3930DEFUN (no_ip_address,
3931 no_ip_address_cmd,
3932 "no ip address A.B.C.D/M",
3933 NO_STR
3934 "Interface Internet Protocol config commands\n"
3935 "Set the IP address of an interface\n"
efd7904e 3936 "IP Address (e.g. 10.0.0.1/8)\n")
718e3744 3937{
d62a17ae 3938 int idx_ipv4_prefixlen = 3;
3939 VTY_DECLVAR_CONTEXT(interface, ifp);
3940 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
3941 NULL, NULL);
718e3744 3942}
3943
60466a63
QY
3944DEFUN(ip_address_peer,
3945 ip_address_peer_cmd,
3946 "ip address A.B.C.D peer A.B.C.D/M",
3947 "Interface Internet Protocol config commands\n"
3948 "Set the IP address of an interface\n"
3949 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
3950 "Specify P-t-P address\n"
3951 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
3952{
3953 VTY_DECLVAR_CONTEXT(interface, ifp);
3954 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
3955}
3956
60466a63
QY
3957DEFUN(no_ip_address_peer,
3958 no_ip_address_peer_cmd,
3959 "no ip address A.B.C.D peer A.B.C.D/M",
3960 NO_STR
3961 "Interface Internet Protocol config commands\n"
3962 "Set the IP address of an interface\n"
3963 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
3964 "Specify P-t-P address\n"
3965 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
3966{
3967 VTY_DECLVAR_CONTEXT(interface, ifp);
3968 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
3969}
986aa00f 3970
718e3744 3971#ifdef HAVE_NETLINK
718e3744 3972DEFUN (ip_address_label,
3973 ip_address_label_cmd,
3974 "ip address A.B.C.D/M label LINE",
3975 "Interface Internet Protocol config commands\n"
3976 "Set the IP address of an interface\n"
3977 "IP address (e.g. 10.0.0.1/8)\n"
3978 "Label of this address\n"
3979 "Label\n")
3980{
d62a17ae 3981 int idx_ipv4_prefixlen = 2;
3982 int idx_line = 4;
3983 VTY_DECLVAR_CONTEXT(interface, ifp);
3984 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
3985 argv[idx_line]->arg);
718e3744 3986}
3987
3988DEFUN (no_ip_address_label,
3989 no_ip_address_label_cmd,
3990 "no ip address A.B.C.D/M label LINE",
3991 NO_STR
3992 "Interface Internet Protocol config commands\n"
3993 "Set the IP address of an interface\n"
3994 "IP address (e.g. 10.0.0.1/8)\n"
3995 "Label of this address\n"
3996 "Label\n")
3997{
d62a17ae 3998 int idx_ipv4_prefixlen = 3;
3999 int idx_line = 5;
4000 VTY_DECLVAR_CONTEXT(interface, ifp);
4001 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
4002 NULL, argv[idx_line]->arg);
718e3744 4003}
4004#endif /* HAVE_NETLINK */
4005
09268680
CS
4006int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix,
4007 const char *label)
4008{
4009 struct zebra_if *if_data;
4010 struct prefix_ipv6 cp;
4011 struct connected *ifc;
4012 struct prefix_ipv6 *p;
4013 enum zebra_dplane_result dplane_res;
4014
4015 if_data = ifp->info;
4016
4017 cp.family = prefix->family;
4018 cp.prefixlen = prefix->prefixlen;
4019 cp.prefix = prefix->u.prefix6;
4020 apply_mask_ipv6(&cp);
4021
4022 ifc = connected_check(ifp, (struct prefix *)&cp);
4023 if (!ifc) {
4024 ifc = connected_new();
4025 ifc->ifp = ifp;
4026
4027 /* Address. */
4028 p = prefix_ipv6_new();
4029 *p = cp;
4030 ifc->address = (struct prefix *)p;
4031
4032 /* Label. */
4033 if (label)
4034 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
4035
4036 /* Add to linked list. */
4037 listnode_add(ifp->connected, ifc);
4038 }
4039
4040 /* This address is configured from zebra. */
4041 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4042 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4043
4044 /* In case of this route need to install kernel. */
4045 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4046 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
4047 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
4048 /* Some system need to up the interface to set IP address. */
4049 if (!if_is_up(ifp)) {
4050 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
4051 if_refresh(ifp);
4052 }
4053
4054 dplane_res = dplane_intf_addr_set(ifp, ifc);
4055 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
4056 zlog_debug(
1d5453d6 4057 "dplane can't set interface IP address: %s.",
09268680
CS
4058 dplane_res2str(dplane_res));
4059 return NB_ERR;
4060 }
4061
4062 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4063 /* The address will be advertised to zebra clients when the
4064 * notification
4065 * from the kernel has been received. */
4066 }
4067
4068 return 0;
4069}
4070
d62a17ae 4071static int ipv6_address_install(struct vty *vty, struct interface *ifp,
4072 const char *addr_str, const char *peer_str,
b1bd1015 4073 const char *label)
d62a17ae 4074{
4075 struct zebra_if *if_data;
4076 struct prefix_ipv6 cp;
4077 struct connected *ifc;
4078 struct prefix_ipv6 *p;
4079 int ret;
0f1f6ce4 4080 enum zebra_dplane_result dplane_res;
d62a17ae 4081
4082 if_data = ifp->info;
4083
4084 ret = str2prefix_ipv6(addr_str, &cp);
4085 if (ret <= 0) {
4086 vty_out(vty, "%% Malformed address \n");
4087 return CMD_WARNING_CONFIG_FAILED;
718e3744 4088 }
4089
d62a17ae 4090 if (ipv6_martian(&cp.prefix)) {
4091 vty_out(vty, "%% Invalid address\n");
4092 return CMD_WARNING_CONFIG_FAILED;
4093 }
718e3744 4094
d62a17ae 4095 ifc = connected_check(ifp, (struct prefix *)&cp);
4096 if (!ifc) {
4097 ifc = connected_new();
4098 ifc->ifp = ifp;
4099
4100 /* Address. */
4101 p = prefix_ipv6_new();
4102 *p = cp;
4103 ifc->address = (struct prefix *)p;
4104
d62a17ae 4105 /* Label. */
4106 if (label)
4107 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
4108
4109 /* Add to linked list. */
4110 listnode_add(ifp->connected, ifc);
718e3744 4111 }
4112
d62a17ae 4113 /* This address is configured from zebra. */
4114 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4115 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4116
4117 /* In case of this route need to install kernel. */
4118 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4119 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
4120 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
4121 /* Some system need to up the interface to set IP address. */
4122 if (!if_is_up(ifp)) {
4123 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
4124 if_refresh(ifp);
4125 }
4126
0f1f6ce4
MS
4127 dplane_res = dplane_intf_addr_set(ifp, ifc);
4128 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
d62a17ae 4129 vty_out(vty, "%% Can't set interface IP address: %s.\n",
0f1f6ce4 4130 dplane_res2str(dplane_res));
d62a17ae 4131 return CMD_WARNING_CONFIG_FAILED;
4132 }
4133
4134 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4135 /* The address will be advertised to zebra clients when the
4136 * notification
4137 * from the kernel has been received. */
4138 }
718e3744 4139
d62a17ae 4140 return CMD_SUCCESS;
718e3744 4141}
4142
b6120505 4143/* Return true if an ipv6 address is configured on ifp */
d62a17ae 4144int ipv6_address_configured(struct interface *ifp)
4145{
4146 struct connected *connected;
4147 struct listnode *node;
4148
4149 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
4150 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
4151 && (connected->address->family == AF_INET6))
4152 return 1;
4153
4154 return 0;
4155}
4156
4157static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
4158 const char *addr_str, const char *peer_str,
b1bd1015 4159 const char *label)
d62a17ae 4160{
4161 struct prefix_ipv6 cp;
4162 struct connected *ifc;
4163 int ret;
0f1f6ce4 4164 enum zebra_dplane_result dplane_res;
d62a17ae 4165
4166 /* Convert to prefix structure. */
4167 ret = str2prefix_ipv6(addr_str, &cp);
4168 if (ret <= 0) {
4169 vty_out(vty, "%% Malformed address \n");
4170 return CMD_WARNING_CONFIG_FAILED;
4171 }
4172
4173 /* Check current interface address. */
4174 ifc = connected_check(ifp, (struct prefix *)&cp);
4175 if (!ifc) {
4176 vty_out(vty, "%% Can't find address\n");
4177 return CMD_WARNING_CONFIG_FAILED;
4178 }
4179
4180 /* This is not configured address. */
4181 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
4182 return CMD_WARNING_CONFIG_FAILED;
4183
4184 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
4185
4186 /* This is not real address or interface is not active. */
4187 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
4188 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
4189 listnode_delete(ifp->connected, ifc);
721c0857 4190 connected_free(&ifc);
d62a17ae 4191 return CMD_WARNING_CONFIG_FAILED;
4192 }
4193
4194 /* This is real route. */
0f1f6ce4
MS
4195 dplane_res = dplane_intf_addr_unset(ifp, ifc);
4196 if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
d62a17ae 4197 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
0f1f6ce4 4198 dplane_res2str(dplane_res));
d62a17ae 4199 return CMD_WARNING_CONFIG_FAILED;
4200 }
4201
4202 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
4203 /* This information will be propagated to the zclients when the
4204 * kernel notification is received. */
4205 return CMD_SUCCESS;
718e3744 4206}
4207
4208DEFUN (ipv6_address,
4209 ipv6_address_cmd,
4210 "ipv6 address X:X::X:X/M",
e23949c0 4211 "Interface IPv6 config commands\n"
718e3744 4212 "Set the IP address of an interface\n"
4213 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4214{
d62a17ae 4215 int idx_ipv6_prefixlen = 2;
4216 VTY_DECLVAR_CONTEXT(interface, ifp);
4217 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
b1bd1015 4218 NULL, NULL);
718e3744 4219}
4220
4221DEFUN (no_ipv6_address,
4222 no_ipv6_address_cmd,
4223 "no ipv6 address X:X::X:X/M",
4224 NO_STR
e23949c0 4225 "Interface IPv6 config commands\n"
718e3744 4226 "Set the IP address of an interface\n"
4227 "IPv6 address (e.g. 3ffe:506::1/48)\n")
4228{
d62a17ae 4229 int idx_ipv6_prefixlen = 3;
4230 VTY_DECLVAR_CONTEXT(interface, ifp);
4231 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
b1bd1015 4232 NULL, NULL);
d62a17ae 4233}
4234
4235static int link_params_config_write(struct vty *vty, struct interface *ifp)
4236{
4237 int i;
4238
4239 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
4240 return -1;
986aa00f 4241
d62a17ae 4242 struct if_link_params *iflp = ifp->link_params;
4243
4244 vty_out(vty, " link-params\n");
4245 vty_out(vty, " enable\n");
4246 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
4247 vty_out(vty, " metric %u\n", iflp->te_metric);
4248 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
4249 vty_out(vty, " max-bw %g\n", iflp->max_bw);
4250 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
4251 && iflp->max_rsv_bw != iflp->default_bw)
4252 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
4253 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
4254 for (i = 0; i < 8; i++)
4255 if (iflp->unrsv_bw[i] != iflp->default_bw)
4256 vty_out(vty, " unrsv-bw %d %g\n", i,
4257 iflp->unrsv_bw[i]);
4258 }
4259 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
4260 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
4261 if (IS_PARAM_SET(iflp, LP_DELAY)) {
4262 vty_out(vty, " delay %u", iflp->av_delay);
4263 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
4264 vty_out(vty, " min %u", iflp->min_delay);
4265 vty_out(vty, " max %u", iflp->max_delay);
4266 }
4267 vty_out(vty, "\n");
bfac8dcd 4268 }
d62a17ae 4269 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
4270 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
4271 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
4272 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
4273 if (IS_PARAM_SET(iflp, LP_AVA_BW))
4274 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
4275 if (IS_PARAM_SET(iflp, LP_RES_BW))
4276 vty_out(vty, " res-bw %g\n", iflp->res_bw);
4277 if (IS_PARAM_SET(iflp, LP_USE_BW))
4278 vty_out(vty, " use-bw %g\n", iflp->use_bw);
4279 if (IS_PARAM_SET(iflp, LP_RMT_AS))
9bcef951 4280 vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip,
d62a17ae 4281 iflp->rmt_as);
07679ad9 4282 vty_out(vty, " exit-link-params\n");
d62a17ae 4283 return 0;
4284}
4285
4286static int if_config_write(struct vty *vty)
4287{
f60a1188 4288 struct vrf *vrf;
d62a17ae 4289 struct interface *ifp;
4290
4291 zebra_ptm_write(vty);
4292
f60a1188
IR
4293 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
4294 FOR_ALL_INTERFACES (vrf, ifp) {
a2addae8
RW
4295 struct zebra_if *if_data;
4296 struct listnode *addrnode;
4297 struct connected *ifc;
4298 struct prefix *p;
d62a17ae 4299
a2addae8 4300 if_data = ifp->info;
d62a17ae 4301
788a036f 4302 if_vty_config_start(vty, ifp);
d62a17ae 4303
a2addae8
RW
4304 if (if_data) {
4305 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
4306 vty_out(vty, " shutdown\n");
d62a17ae 4307
a2addae8
RW
4308 zebra_ptm_if_write(vty, if_data);
4309 }
bfac8dcd 4310
a2addae8
RW
4311 if (ifp->desc)
4312 vty_out(vty, " description %s\n", ifp->desc);
4313
4314 /* Assign bandwidth here to avoid unnecessary interface
4315 flap
4316 while processing config script */
4317 if (ifp->bandwidth != 0)
4318 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
4319
4320 if (!CHECK_FLAG(ifp->status,
4321 ZEBRA_INTERFACE_LINKDETECTION))
4322 vty_out(vty, " no link-detect\n");
4323
4324 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
4325 ifc)) {
4326 if (CHECK_FLAG(ifc->conf,
4327 ZEBRA_IFC_CONFIGURED)) {
4328 char buf[INET6_ADDRSTRLEN];
4329 p = ifc->address;
4330 vty_out(vty, " ip%s address %s",
4331 p->family == AF_INET ? ""
4332 : "v6",
a07df329 4333 inet_ntop(p->family,
60466a63
QY
4334 &p->u.prefix, buf,
4335 sizeof(buf)));
a2addae8
RW
4336 if (CONNECTED_PEER(ifc)) {
4337 p = ifc->destination;
4338 vty_out(vty, " peer %s",
4339 inet_ntop(p->family,
4340 &p->u.prefix,
4341 buf,
4342 sizeof(buf)));
4343 }
4344 vty_out(vty, "/%d", p->prefixlen);
718e3744 4345
a2addae8
RW
4346 if (ifc->label)
4347 vty_out(vty, " label %s",
4348 ifc->label);
718e3744 4349
a2addae8
RW
4350 vty_out(vty, "\n");
4351 }
d62a17ae 4352 }
718e3744 4353
a2addae8
RW
4354 if (if_data) {
4355 if (if_data->multicast
4356 != IF_ZEBRA_MULTICAST_UNSPEC)
4357 vty_out(vty, " %smulticast\n",
4358 if_data->multicast
4359 == IF_ZEBRA_MULTICAST_ON
4360 ? ""
4361 : "no ");
4362 }
718e3744 4363
a2addae8 4364 hook_call(zebra_if_config_wr, vty, ifp);
ce5160c0 4365 zebra_evpn_mh_if_write(vty, ifp);
a2addae8 4366 link_params_config_write(vty, ifp);
16f1b9ee 4367
788a036f 4368 if_vty_config_end(vty);
a2addae8 4369 }
d62a17ae 4370 return 0;
718e3744 4371}
4372
4373/* Allocate and initialize interface vector. */
d62a17ae 4374void zebra_if_init(void)
4375{
4376 /* Initialize interface and new hook. */
ce19a04a
DL
4377 hook_register_prio(if_add, 0, if_zebra_new_hook);
4378 hook_register_prio(if_del, 0, if_zebra_delete_hook);
d62a17ae 4379
4380 /* Install configuration write function. */
9da01b0b 4381 if_cmd_init(if_config_write);
612c2c15 4382 install_node(&link_params_node);
138c5a74
DS
4383 /*
4384 * This is *intentionally* setting this to NULL, signaling
4385 * that interface creation for zebra acts differently
4386 */
4387 if_zapi_callbacks(NULL, NULL, NULL, NULL);
d62a17ae 4388
4389 install_element(VIEW_NODE, &show_interface_cmd);
4390 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
4391 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
4392 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
4393
4394 install_element(ENABLE_NODE, &show_interface_desc_cmd);
4395 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
4396 install_element(INTERFACE_NODE, &multicast_cmd);
4397 install_element(INTERFACE_NODE, &no_multicast_cmd);
4398 install_element(INTERFACE_NODE, &linkdetect_cmd);
4399 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
4400 install_element(INTERFACE_NODE, &shutdown_if_cmd);
4401 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
4402 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
4403 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
4404 install_element(INTERFACE_NODE, &ip_address_cmd);
4405 install_element(INTERFACE_NODE, &no_ip_address_cmd);
a07df329
DL
4406 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
4407 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
d62a17ae 4408 install_element(INTERFACE_NODE, &ipv6_address_cmd);
4409 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 4410#ifdef HAVE_NETLINK
d62a17ae 4411 install_element(INTERFACE_NODE, &ip_address_label_cmd);
4412 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
718e3744 4413#endif /* HAVE_NETLINK */
d62a17ae 4414 install_element(INTERFACE_NODE, &link_params_cmd);
4415 install_default(LINK_PARAMS_NODE);
4416 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
4417 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
4418 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
4419 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
4420 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
4421 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
4422 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
4423 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
4424 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
4425 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
4426 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
4427 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
4428 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
4429 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
4430 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
4431 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
4432 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
4433 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
4434 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
4435 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
4436 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
4437 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
4438 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
4439 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
ce5160c0
AK
4440
4441 /* setup EVPN MH elements */
4442 zebra_evpn_interface_init();
718e3744 4443}