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