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