]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
zebra: header changes for l2 vni bum-mcast-grp handling
[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);
1374 vty_out(vty, "\n");
1375 }
1376
1377 if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
1378 struct zebra_l2info_brslave *br_slave;
1379
1380 br_slave = &zebra_if->brslave_info;
1381 if (br_slave->bridge_ifindex != IFINDEX_INTERNAL)
1382 vty_out(vty, " Master (bridge) ifindex %u\n",
1383 br_slave->bridge_ifindex);
1384 }
1385
b9368db9
DD
1386 if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
1387 struct zebra_l2info_bondslave *bond_slave;
1388
1389 bond_slave = &zebra_if->bondslave_info;
1390 if (bond_slave->bond_ifindex != IFINDEX_INTERNAL)
1391 vty_out(vty, " Master (bond) ifindex %u\n",
1392 bond_slave->bond_ifindex);
1393 }
1394
8cb73ba4
DS
1395 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
1396 vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
1397 if (zebra_if->link)
1398 vty_out(vty, "(%s)\n", zebra_if->link->name);
1399 else
1400 vty_out(vty, "(Unknown)\n");
1401 }
d62a17ae 1402
1403 if (HAS_LINK_PARAMS(ifp)) {
1404 int i;
1405 struct if_link_params *iflp = ifp->link_params;
1406 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1407 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1408 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1409 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1410 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1411 iflp->max_bw);
1412 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1413 vty_out(vty,
1414 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1415 iflp->max_rsv_bw);
1416 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1417 vty_out(vty,
1418 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1419 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1420 vty_out(vty,
1421 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1422 i, iflp->unrsv_bw[i], i + 1,
1423 iflp->unrsv_bw[i + 1]);
1424 }
1425
1426 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1427 vty_out(vty, " Administrative Group:%u\n",
1428 iflp->admin_grp);
1429 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1430 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1431 iflp->av_delay);
1432 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1433 vty_out(vty, " Min: %u (micro-sec.)",
1434 iflp->min_delay);
1435 vty_out(vty, " Max: %u (micro-sec.)",
1436 iflp->max_delay);
1437 }
1438 vty_out(vty, "\n");
1439 }
1440 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1441 vty_out(vty,
1442 " Link Delay Variation %u (micro-sec.)\n",
1443 iflp->delay_var);
1444 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1445 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1446 iflp->pkt_loss);
1447 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1448 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1449 iflp->ava_bw);
1450 if (IS_PARAM_SET(iflp, LP_RES_BW))
1451 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1452 iflp->res_bw);
1453 if (IS_PARAM_SET(iflp, LP_USE_BW))
1454 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1455 iflp->use_bw);
1456 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1457 vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n",
1458 inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
1459 }
1460
2eb27eec
DL
1461 hook_call(zebra_if_extra_info, vty, ifp);
1462
d62a17ae 1463 if (listhead(ifp->nbr_connected))
1464 vty_out(vty, " Neighbor address(s):\n");
1465 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
1466 nbr_connected_dump_vty(vty, nbr_connected);
718e3744 1467
1468#ifdef HAVE_PROC_NET_DEV
d62a17ae 1469 /* Statistics print out using proc file system. */
1470 vty_out(vty,
1471 " %lu input packets (%lu multicast), %lu bytes, "
1472 "%lu dropped\n",
1473 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1474 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1475
1476 vty_out(vty,
1477 " %lu input errors, %lu length, %lu overrun,"
1478 " %lu CRC, %lu frame\n",
1479 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1480 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1481 ifp->stats.rx_frame_errors);
1482
1483 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1484 ifp->stats.rx_missed_errors);
1485
1486 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1487 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1488 ifp->stats.tx_dropped);
1489
1490 vty_out(vty,
1491 " %lu output errors, %lu aborted, %lu carrier,"
1492 " %lu fifo, %lu heartbeat\n",
1493 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1494 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1495 ifp->stats.tx_heartbeat_errors);
1496
1497 vty_out(vty, " %lu window, %lu collisions\n",
1498 ifp->stats.tx_window_errors, ifp->stats.collisions);
718e3744 1499#endif /* HAVE_PROC_NET_DEV */
1500
1501#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1502#if defined(__bsdi__) || defined(__NetBSD__)
1503 /* Statistics print out using sysctl (). */
1504 vty_out(vty,
1505 " input packets %llu, bytes %llu, dropped %llu,"
1506 " multicast packets %llu\n",
1507 (unsigned long long)ifp->stats.ifi_ipackets,
1508 (unsigned long long)ifp->stats.ifi_ibytes,
1509 (unsigned long long)ifp->stats.ifi_iqdrops,
1510 (unsigned long long)ifp->stats.ifi_imcasts);
1511
1512 vty_out(vty, " input errors %llu\n",
1513 (unsigned long long)ifp->stats.ifi_ierrors);
1514
1515 vty_out(vty,
1516 " output packets %llu, bytes %llu,"
1517 " multicast packets %llu\n",
1518 (unsigned long long)ifp->stats.ifi_opackets,
1519 (unsigned long long)ifp->stats.ifi_obytes,
1520 (unsigned long long)ifp->stats.ifi_omcasts);
1521
1522 vty_out(vty, " output errors %llu\n",
1523 (unsigned long long)ifp->stats.ifi_oerrors);
1524
1525 vty_out(vty, " collisions %llu\n",
1526 (unsigned long long)ifp->stats.ifi_collisions);
718e3744 1527#else
d62a17ae 1528 /* Statistics print out using sysctl (). */
1529 vty_out(vty,
1530 " input packets %lu, bytes %lu, dropped %lu,"
1531 " multicast packets %lu\n",
1532 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1533 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts);
718e3744 1534
d62a17ae 1535 vty_out(vty, " input errors %lu\n", ifp->stats.ifi_ierrors);
718e3744 1536
d62a17ae 1537 vty_out(vty,
1538 " output packets %lu, bytes %lu, multicast packets %lu\n",
1539 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1540 ifp->stats.ifi_omcasts);
718e3744 1541
d62a17ae 1542 vty_out(vty, " output errors %lu\n", ifp->stats.ifi_oerrors);
718e3744 1543
d62a17ae 1544 vty_out(vty, " collisions %lu\n", ifp->stats.ifi_collisions);
718e3744 1545#endif /* __bsdi__ || __NetBSD__ */
1546#endif /* HAVE_NET_RT_IFLIST */
1547}
1548
d62a17ae 1549static void interface_update_stats(void)
78860b9f
DS
1550{
1551#ifdef HAVE_PROC_NET_DEV
d62a17ae 1552 /* If system has interface statistics via proc file system, update
1553 statistics. */
1554 ifstat_update_proc();
78860b9f
DS
1555#endif /* HAVE_PROC_NET_DEV */
1556#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1557 ifstat_update_sysctl();
78860b9f
DS
1558#endif /* HAVE_NET_RT_IFLIST */
1559}
1560
d62a17ae 1561struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
718e3744 1562
49548752
NS
1563#ifndef VTYSH_EXTRACT_PL
1564#include "zebra/interface_clippy.c"
1565#endif
8b87bdf4 1566/* Show all interfaces to vty. */
49548752
NS
1567DEFPY(show_interface, show_interface_cmd,
1568 "show interface [vrf NAME$name] [brief$brief]",
1569 SHOW_STR
1570 "Interface status and configuration\n"
1571 VRF_CMD_HELP_STR
1572 "Interface status and configuration summary\n")
8b87bdf4 1573{
f4e14fdb 1574 struct vrf *vrf;
d62a17ae 1575 struct interface *ifp;
1576 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1577
d62a17ae 1578 interface_update_stats();
8b87bdf4 1579
49548752
NS
1580 if (name)
1581 VRF_GET_ID(vrf_id, name, false);
8b87bdf4 1582
d62a17ae 1583 /* All interface print. */
f4e14fdb 1584 vrf = vrf_lookup_by_id(vrf_id);
49548752
NS
1585 if (brief) {
1586 ifs_dump_brief_vty(vty, vrf);
1587 } else {
1588 FOR_ALL_INTERFACES (vrf, ifp) {
1589 if_dump_vty(vty, ifp);
1590 }
1591 }
8b87bdf4 1592
d62a17ae 1593 return CMD_SUCCESS;
8b87bdf4
FL
1594}
1595
8b87bdf4
FL
1596
1597/* Show all interfaces to vty. */
8b3f0677
DW
1598DEFUN (show_interface_vrf_all,
1599 show_interface_vrf_all_cmd,
9ccf14f7 1600 "show interface vrf all",
8b87bdf4
FL
1601 SHOW_STR
1602 "Interface status and configuration\n"
1603 VRF_ALL_CMD_HELP_STR)
718e3744 1604{
d62a17ae 1605 struct vrf *vrf;
d62a17ae 1606 struct interface *ifp;
8b87bdf4 1607
d62a17ae 1608 interface_update_stats();
718e3744 1609
d62a17ae 1610 /* All interface print. */
a2addae8 1611 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
451fda4f 1612 FOR_ALL_INTERFACES (vrf, ifp)
a2addae8 1613 if_dump_vty(vty, ifp);
8b87bdf4 1614
d62a17ae 1615 return CMD_SUCCESS;
8b87bdf4
FL
1616}
1617
1618/* Show specified interface to vty. */
1721646e
DS
1619
1620DEFUN (show_interface_name_vrf,
1621 show_interface_name_vrf_cmd,
9ccf14f7 1622 "show interface IFNAME vrf NAME",
8b87bdf4
FL
1623 SHOW_STR
1624 "Interface status and configuration\n"
1721646e
DS
1625 "Interface name\n"
1626 VRF_CMD_HELP_STR)
8b87bdf4 1627{
d62a17ae 1628 int idx_ifname = 2;
1629 int idx_name = 4;
1630 struct interface *ifp;
0439cb9d 1631 vrf_id_t vrf_id;
8b87bdf4 1632
d62a17ae 1633 interface_update_stats();
8b87bdf4 1634
ec1db588 1635 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
8b87bdf4 1636
d62a17ae 1637 /* Specified interface print. */
1638 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1639 if (ifp == NULL) {
1640 vty_out(vty, "%% Can't find interface %s\n",
1641 argv[idx_ifname]->arg);
1642 return CMD_WARNING;
1643 }
1644 if_dump_vty(vty, ifp);
718e3744 1645
d62a17ae 1646 return CMD_SUCCESS;
718e3744 1647}
1648
8b87bdf4 1649/* Show specified interface to vty. */
8b3f0677
DW
1650DEFUN (show_interface_name_vrf_all,
1651 show_interface_name_vrf_all_cmd,
b62ecea5 1652 "show interface IFNAME [vrf all]",
8b87bdf4
FL
1653 SHOW_STR
1654 "Interface status and configuration\n"
1721646e 1655 "Interface name\n"
8b87bdf4
FL
1656 VRF_ALL_CMD_HELP_STR)
1657{
d62a17ae 1658 int idx_ifname = 2;
1659 struct vrf *vrf;
1660 struct interface *ifp;
1661 int found = 0;
8b87bdf4 1662
d62a17ae 1663 interface_update_stats();
8b87bdf4 1664
d62a17ae 1665 /* All interface print. */
a2addae8 1666 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1667 /* Specified interface print. */
1668 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id);
1669 if (ifp) {
1670 if_dump_vty(vty, ifp);
1671 found++;
1672 }
1673 }
8b87bdf4 1674
d62a17ae 1675 if (!found) {
1676 vty_out(vty, "%% Can't find interface %s\n",
1677 argv[idx_ifname]->arg);
1678 return CMD_WARNING;
1679 }
8b87bdf4 1680
d62a17ae 1681 return CMD_SUCCESS;
8b87bdf4
FL
1682}
1683
1721646e 1684
d62a17ae 1685static void if_show_description(struct vty *vty, vrf_id_t vrf_id)
ed9bb6d5 1686{
f4e14fdb 1687 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
d62a17ae 1688 struct interface *ifp;
ed9bb6d5 1689
d62a17ae 1690 vty_out(vty, "Interface Status Protocol Description\n");
451fda4f 1691 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1692 int len;
ed9bb6d5 1693
d62a17ae 1694 len = vty_out(vty, "%s", ifp->name);
1695 vty_out(vty, "%*s", (16 - len), " ");
1696
1697 if (if_is_up(ifp)) {
1698 vty_out(vty, "up ");
1699 if (CHECK_FLAG(ifp->status,
1700 ZEBRA_INTERFACE_LINKDETECTION)) {
1701 if (if_is_running(ifp))
1702 vty_out(vty, "up ");
1703 else
1704 vty_out(vty, "down ");
1705 } else {
1706 vty_out(vty, "unknown ");
1707 }
1708 } else {
1709 vty_out(vty, "down down ");
1710 }
ed9bb6d5 1711
d62a17ae 1712 if (ifp->desc)
1713 vty_out(vty, "%s", ifp->desc);
1714 vty_out(vty, "\n");
1715 }
8b87bdf4
FL
1716}
1717
1718DEFUN (show_interface_desc,
1719 show_interface_desc_cmd,
b62ecea5 1720 "show interface description [vrf NAME]",
8b87bdf4
FL
1721 SHOW_STR
1722 "Interface status and configuration\n"
b62ecea5
QY
1723 "Interface description\n"
1724 VRF_CMD_HELP_STR)
8b87bdf4 1725{
d62a17ae 1726 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1727
d62a17ae 1728 if (argc > 3)
ec1db588 1729 VRF_GET_ID(vrf_id, argv[4]->arg, false);
8b87bdf4 1730
d62a17ae 1731 if_show_description(vty, vrf_id);
8b87bdf4 1732
d62a17ae 1733 return CMD_SUCCESS;
8b87bdf4
FL
1734}
1735
8b87bdf4
FL
1736
1737DEFUN (show_interface_desc_vrf_all,
1738 show_interface_desc_vrf_all_cmd,
9ccf14f7 1739 "show interface description vrf all",
8b87bdf4
FL
1740 SHOW_STR
1741 "Interface status and configuration\n"
1742 "Interface description\n"
1743 VRF_ALL_CMD_HELP_STR)
1744{
d62a17ae 1745 struct vrf *vrf;
8b87bdf4 1746
a2addae8 1747 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
996c9314 1748 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
a2addae8
RW
1749 vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
1750 if_show_description(vty, vrf->vrf_id);
1751 }
8b87bdf4 1752
d62a17ae 1753 return CMD_SUCCESS;
ed9bb6d5 1754}
1755
718e3744 1756DEFUN (multicast,
1757 multicast_cmd,
1758 "multicast",
1759 "Set multicast flag to interface\n")
1760{
d62a17ae 1761 VTY_DECLVAR_CONTEXT(interface, ifp);
1762 int ret;
1763 struct zebra_if *if_data;
718e3744 1764
d62a17ae 1765 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1766 ret = if_set_flags(ifp, IFF_MULTICAST);
1767 if (ret < 0) {
1768 vty_out(vty, "Can't set multicast flag\n");
1769 return CMD_WARNING_CONFIG_FAILED;
1770 }
1771 if_refresh(ifp);
48b33aaf 1772 }
d62a17ae 1773 if_data = ifp->info;
1774 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1775
d62a17ae 1776 return CMD_SUCCESS;
718e3744 1777}
1778
1779DEFUN (no_multicast,
1780 no_multicast_cmd,
1781 "no multicast",
1782 NO_STR
1783 "Unset multicast flag to interface\n")
1784{
d62a17ae 1785 VTY_DECLVAR_CONTEXT(interface, ifp);
1786 int ret;
1787 struct zebra_if *if_data;
718e3744 1788
d62a17ae 1789 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1790 ret = if_unset_flags(ifp, IFF_MULTICAST);
1791 if (ret < 0) {
1792 vty_out(vty, "Can't unset multicast flag\n");
1793 return CMD_WARNING_CONFIG_FAILED;
1794 }
1795 if_refresh(ifp);
48b33aaf 1796 }
d62a17ae 1797 if_data = ifp->info;
1798 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
718e3744 1799
d62a17ae 1800 return CMD_SUCCESS;
718e3744 1801}
1802
2e3b2e47 1803DEFUN (linkdetect,
1804 linkdetect_cmd,
1805 "link-detect",
1806 "Enable link detection on interface\n")
1807{
d62a17ae 1808 VTY_DECLVAR_CONTEXT(interface, ifp);
1809 int if_was_operative;
2e3b2e47 1810
d62a17ae 1811 if_was_operative = if_is_no_ptm_operative(ifp);
1812 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1813
d62a17ae 1814 /* When linkdetection is enabled, if might come down */
1815 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
1816 if_down(ifp);
2e3b2e47 1817
d62a17ae 1818 /* FIXME: Will defer status change forwarding if interface
1819 does not come down! */
1820
1821 return CMD_SUCCESS;
2e3b2e47 1822}
1823
1824
1825DEFUN (no_linkdetect,
1826 no_linkdetect_cmd,
1827 "no link-detect",
1828 NO_STR
1829 "Disable link detection on interface\n")
1830{
d62a17ae 1831 VTY_DECLVAR_CONTEXT(interface, ifp);
1832 int if_was_operative;
1833
1834 if_was_operative = if_is_no_ptm_operative(ifp);
1835 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1836
d62a17ae 1837 /* Interface may come up after disabling link detection */
1838 if (if_is_operative(ifp) && !if_was_operative)
1839 if_up(ifp);
2e3b2e47 1840
d62a17ae 1841 /* FIXME: see linkdetect_cmd */
2e3b2e47 1842
d62a17ae 1843 return CMD_SUCCESS;
2e3b2e47 1844}
1845
718e3744 1846DEFUN (shutdown_if,
1847 shutdown_if_cmd,
1848 "shutdown",
1849 "Shutdown the selected interface\n")
1850{
d62a17ae 1851 VTY_DECLVAR_CONTEXT(interface, ifp);
1852 int ret;
1853 struct zebra_if *if_data;
718e3744 1854
d62a17ae 1855 if (ifp->ifindex != IFINDEX_INTERNAL) {
1856 ret = if_unset_flags(ifp, IFF_UP);
1857 if (ret < 0) {
1858 vty_out(vty, "Can't shutdown interface\n");
1859 return CMD_WARNING_CONFIG_FAILED;
1860 }
1861 if_refresh(ifp);
1862 }
1863 if_data = ifp->info;
1864 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
718e3744 1865
d62a17ae 1866 return CMD_SUCCESS;
718e3744 1867}
1868
1869DEFUN (no_shutdown_if,
1870 no_shutdown_if_cmd,
1871 "no shutdown",
1872 NO_STR
1873 "Shutdown the selected interface\n")
1874{
d62a17ae 1875 VTY_DECLVAR_CONTEXT(interface, ifp);
1876 int ret;
1877 struct zebra_if *if_data;
718e3744 1878
d62a17ae 1879 if (ifp->ifindex != IFINDEX_INTERNAL) {
1880 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
1881 if (ret < 0) {
1882 vty_out(vty, "Can't up interface\n");
1883 return CMD_WARNING_CONFIG_FAILED;
1884 }
1885 if_refresh(ifp);
bfac8dcd 1886
d62a17ae 1887 /* Some addresses (in particular, IPv6 addresses on Linux) get
1888 * removed when the interface goes down. They need to be
1889 * readded.
1890 */
1891 if_addr_wakeup(ifp);
1892 }
bfac8dcd 1893
d62a17ae 1894 if_data = ifp->info;
1895 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
718e3744 1896
d62a17ae 1897 return CMD_SUCCESS;
718e3744 1898}
1899
1900DEFUN (bandwidth_if,
1901 bandwidth_if_cmd,
6147e2c6 1902 "bandwidth (1-100000)",
718e3744 1903 "Set bandwidth informational parameter\n"
70bd3c43 1904 "Bandwidth in megabits\n")
718e3744 1905{
d62a17ae 1906 int idx_number = 1;
1907 VTY_DECLVAR_CONTEXT(interface, ifp);
1908 unsigned int bandwidth;
1909
1910 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1911
1912 /* bandwidth range is <1-100000> */
1913 if (bandwidth < 1 || bandwidth > 100000) {
1914 vty_out(vty, "Bandwidth is invalid\n");
1915 return CMD_WARNING_CONFIG_FAILED;
1916 }
1917
1918 ifp->bandwidth = bandwidth;
718e3744 1919
d62a17ae 1920 /* force protocols to recalculate routes due to cost change */
1921 if (if_is_operative(ifp))
1922 zebra_interface_up_update(ifp);
718e3744 1923
d62a17ae 1924 return CMD_SUCCESS;
718e3744 1925}
1926
1927DEFUN (no_bandwidth_if,
1928 no_bandwidth_if_cmd,
b62ecea5 1929 "no bandwidth [(1-100000)]",
718e3744 1930 NO_STR
b62ecea5
QY
1931 "Set bandwidth informational parameter\n"
1932 "Bandwidth in megabits\n")
718e3744 1933{
d62a17ae 1934 VTY_DECLVAR_CONTEXT(interface, ifp);
718e3744 1935
d62a17ae 1936 ifp->bandwidth = 0;
718e3744 1937
d62a17ae 1938 /* force protocols to recalculate routes due to cost change */
1939 if (if_is_operative(ifp))
1940 zebra_interface_up_update(ifp);
1941
1942 return CMD_SUCCESS;
718e3744 1943}
1944
6b0655a2 1945
d62a17ae 1946struct cmd_node link_params_node = {
9d303b37 1947 LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,
16f1b9ee
OD
1948};
1949
d62a17ae 1950static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1951 uint32_t type, uint32_t value)
16f1b9ee 1952{
d62a17ae 1953 /* Update field as needed */
1954 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1955 *field = value;
1956 SET_PARAM(ifp->link_params, type);
16f1b9ee 1957
d62a17ae 1958 /* force protocols to update LINK STATE due to parameters change
1959 */
1960 if (if_is_operative(ifp))
1961 zebra_interface_parameters_update(ifp);
1962 }
16f1b9ee 1963}
d62a17ae 1964static void link_param_cmd_set_float(struct interface *ifp, float *field,
1965 uint32_t type, float value)
16f1b9ee
OD
1966{
1967
d62a17ae 1968 /* Update field as needed */
1969 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1970 *field = value;
1971 SET_PARAM(ifp->link_params, type);
16f1b9ee 1972
d62a17ae 1973 /* force protocols to update LINK STATE due to parameters change
1974 */
1975 if (if_is_operative(ifp))
1976 zebra_interface_parameters_update(ifp);
1977 }
16f1b9ee
OD
1978}
1979
d62a17ae 1980static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
16f1b9ee 1981{
d62a17ae 1982 if (ifp->link_params == NULL)
1983 return;
16f1b9ee 1984
d62a17ae 1985 /* Unset field */
1986 UNSET_PARAM(ifp->link_params, type);
16f1b9ee 1987
d62a17ae 1988 /* force protocols to update LINK STATE due to parameters change */
1989 if (if_is_operative(ifp))
1990 zebra_interface_parameters_update(ifp);
16f1b9ee
OD
1991}
1992
505e5056 1993DEFUN_NOSH (link_params,
16f1b9ee
OD
1994 link_params_cmd,
1995 "link-params",
1996 LINK_PARAMS_STR)
1997{
d62a17ae 1998 /* vty->qobj_index stays the same @ interface pointer */
1999 vty->node = LINK_PARAMS_NODE;
16f1b9ee 2000
d62a17ae 2001 return CMD_SUCCESS;
16f1b9ee
OD
2002}
2003
505e5056 2004DEFUN_NOSH (exit_link_params,
03f99d9a
DS
2005 exit_link_params_cmd,
2006 "exit-link-params",
2007 "Exit from Link Params configuration mode\n")
2008{
d62a17ae 2009 if (vty->node == LINK_PARAMS_NODE)
2010 vty->node = INTERFACE_NODE;
2011 return CMD_SUCCESS;
03f99d9a
DS
2012}
2013
16f1b9ee
OD
2014/* Specific Traffic Engineering parameters commands */
2015DEFUN (link_params_enable,
2016 link_params_enable_cmd,
2017 "enable",
2018 "Activate link parameters on this interface\n")
2019{
d62a17ae 2020 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2021
d62a17ae 2022 /* This command could be issue at startup, when activate MPLS TE */
2023 /* on a new interface or after a ON / OFF / ON toggle */
2024 /* In all case, TE parameters are reset to their default factory */
2025 if (IS_ZEBRA_DEBUG_EVENT)
2026 zlog_debug(
2027 "Link-params: enable TE link parameters on interface %s",
2028 ifp->name);
16f1b9ee 2029
d62a17ae 2030 if (!if_link_params_get(ifp)) {
2031 if (IS_ZEBRA_DEBUG_EVENT)
2032 zlog_debug(
2033 "Link-params: failed to init TE link parameters %s",
2034 ifp->name);
16f1b9ee 2035
d62a17ae 2036 return CMD_WARNING_CONFIG_FAILED;
2037 }
16f1b9ee 2038
d62a17ae 2039 /* force protocols to update LINK STATE due to parameters change */
2040 if (if_is_operative(ifp))
2041 zebra_interface_parameters_update(ifp);
16f1b9ee 2042
d62a17ae 2043 return CMD_SUCCESS;
16f1b9ee
OD
2044}
2045
2046DEFUN (no_link_params_enable,
2047 no_link_params_enable_cmd,
2048 "no enable",
2049 NO_STR
2050 "Disable link parameters on this interface\n")
2051{
d62a17ae 2052 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2053
d62a17ae 2054 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
2055 ifp->name);
16f1b9ee 2056
d62a17ae 2057 if_link_params_free(ifp);
16f1b9ee 2058
d62a17ae 2059 /* force protocols to update LINK STATE due to parameters change */
2060 if (if_is_operative(ifp))
2061 zebra_interface_parameters_update(ifp);
16f1b9ee 2062
d62a17ae 2063 return CMD_SUCCESS;
16f1b9ee
OD
2064}
2065
2066/* STANDARD TE metrics */
2067DEFUN (link_params_metric,
2068 link_params_metric_cmd,
6147e2c6 2069 "metric (0-4294967295)",
16f1b9ee
OD
2070 "Link metric for MPLS-TE purpose\n"
2071 "Metric value in decimal\n")
2072{
d62a17ae 2073 int idx_number = 1;
2074 VTY_DECLVAR_CONTEXT(interface, ifp);
2075 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2076 uint32_t metric;
16f1b9ee 2077
d62a17ae 2078 metric = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2079
d62a17ae 2080 /* Update TE metric if needed */
2081 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee 2082
d62a17ae 2083 return CMD_SUCCESS;
16f1b9ee
OD
2084}
2085
2086DEFUN (no_link_params_metric,
2087 no_link_params_metric_cmd,
2088 "no metric",
2089 NO_STR
3ddccf18 2090 "Disable Link Metric on this interface\n")
16f1b9ee 2091{
d62a17ae 2092 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2093
d62a17ae 2094 /* Unset TE Metric */
2095 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee 2096
d62a17ae 2097 return CMD_SUCCESS;
16f1b9ee
OD
2098}
2099
2100DEFUN (link_params_maxbw,
2101 link_params_maxbw_cmd,
2102 "max-bw BANDWIDTH",
2103 "Maximum bandwidth that can be used\n"
2104 "Bytes/second (IEEE floating point format)\n")
2105{
d62a17ae 2106 int idx_bandwidth = 1;
2107 VTY_DECLVAR_CONTEXT(interface, ifp);
2108 struct if_link_params *iflp = if_link_params_get(ifp);
2109
2110 float bw;
2111
2112 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2113 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
2114 safe_strerror(errno));
2115 return CMD_WARNING_CONFIG_FAILED;
2116 }
2117
2118 /* Check that Maximum bandwidth is not lower than other bandwidth
2119 * parameters */
2120 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
2121 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
2122 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
2123 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
2124 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
2125 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
2126 vty_out(vty,
2127 "Maximum Bandwidth could not be lower than others bandwidth\n");
2128 return CMD_WARNING_CONFIG_FAILED;
2129 }
2130
2131 /* Update Maximum Bandwidth if needed */
2132 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
2133
2134 return CMD_SUCCESS;
16f1b9ee
OD
2135}
2136
2137DEFUN (link_params_max_rsv_bw,
2138 link_params_max_rsv_bw_cmd,
2139 "max-rsv-bw BANDWIDTH",
2140 "Maximum bandwidth that may be reserved\n"
2141 "Bytes/second (IEEE floating point format)\n")
2142{
d62a17ae 2143 int idx_bandwidth = 1;
2144 VTY_DECLVAR_CONTEXT(interface, ifp);
2145 struct if_link_params *iflp = if_link_params_get(ifp);
2146 float bw;
16f1b9ee 2147
d62a17ae 2148 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2149 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
2150 safe_strerror(errno));
2151 return CMD_WARNING_CONFIG_FAILED;
2152 }
16f1b9ee 2153
d62a17ae 2154 /* Check that bandwidth is not greater than maximum bandwidth parameter
2155 */
2156 if (bw > iflp->max_bw) {
2157 vty_out(vty,
2158 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2159 iflp->max_bw);
2160 return CMD_WARNING_CONFIG_FAILED;
2161 }
16f1b9ee 2162
d62a17ae 2163 /* Update Maximum Reservable Bandwidth if needed */
2164 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
16f1b9ee 2165
d62a17ae 2166 return CMD_SUCCESS;
16f1b9ee
OD
2167}
2168
2169DEFUN (link_params_unrsv_bw,
2170 link_params_unrsv_bw_cmd,
6147e2c6 2171 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
2172 "Unreserved bandwidth at each priority level\n"
2173 "Priority\n"
2174 "Bytes/second (IEEE floating point format)\n")
2175{
d62a17ae 2176 int idx_number = 1;
2177 int idx_bandwidth = 2;
2178 VTY_DECLVAR_CONTEXT(interface, ifp);
2179 struct if_link_params *iflp = if_link_params_get(ifp);
2180 int priority;
2181 float bw;
2182
2183 /* We don't have to consider about range check here. */
2184 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2185 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2186 safe_strerror(errno));
2187 return CMD_WARNING_CONFIG_FAILED;
2188 }
2189
2190 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2191 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2192 safe_strerror(errno));
2193 return CMD_WARNING_CONFIG_FAILED;
2194 }
2195
2196 /* Check that bandwidth is not greater than maximum bandwidth parameter
2197 */
2198 if (bw > iflp->max_bw) {
2199 vty_out(vty,
2200 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2201 iflp->max_bw);
2202 return CMD_WARNING_CONFIG_FAILED;
2203 }
2204
2205 /* Update Unreserved Bandwidth if needed */
2206 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2207 bw);
2208
2209 return CMD_SUCCESS;
16f1b9ee
OD
2210}
2211
2212DEFUN (link_params_admin_grp,
2213 link_params_admin_grp_cmd,
2214 "admin-grp BITPATTERN",
2215 "Administrative group membership\n"
2216 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2217{
d62a17ae 2218 int idx_bitpattern = 1;
2219 VTY_DECLVAR_CONTEXT(interface, ifp);
2220 struct if_link_params *iflp = if_link_params_get(ifp);
2221 unsigned long value;
16f1b9ee 2222
d62a17ae 2223 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2224 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2225 safe_strerror(errno));
2226 return CMD_WARNING_CONFIG_FAILED;
2227 }
16f1b9ee 2228
d62a17ae 2229 /* Update Administrative Group if needed */
2230 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
16f1b9ee 2231
d62a17ae 2232 return CMD_SUCCESS;
16f1b9ee
OD
2233}
2234
2235DEFUN (no_link_params_admin_grp,
2236 no_link_params_admin_grp_cmd,
2237 "no admin-grp",
2238 NO_STR
3ddccf18 2239 "Disable Administrative group membership on this interface\n")
16f1b9ee 2240{
d62a17ae 2241 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2242
d62a17ae 2243 /* Unset Admin Group */
2244 link_param_cmd_unset(ifp, LP_ADM_GRP);
16f1b9ee 2245
d62a17ae 2246 return CMD_SUCCESS;
16f1b9ee
OD
2247}
2248
2249/* RFC5392 & RFC5316: INTER-AS */
2250DEFUN (link_params_inter_as,
2251 link_params_inter_as_cmd,
6147e2c6 2252 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
2253 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2254 "Remote IP address in dot decimal A.B.C.D\n"
2255 "Remote AS number\n"
2256 "AS number in the range <1-4294967295>\n")
2257{
d62a17ae 2258 int idx_ipv4 = 1;
2259 int idx_number = 3;
16f1b9ee 2260
d62a17ae 2261 VTY_DECLVAR_CONTEXT(interface, ifp);
2262 struct if_link_params *iflp = if_link_params_get(ifp);
2263 struct in_addr addr;
d7c0a89a 2264 uint32_t as;
16f1b9ee 2265
d62a17ae 2266 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2267 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2268 return CMD_WARNING_CONFIG_FAILED;
2269 }
16f1b9ee 2270
d62a17ae 2271 as = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2272
d62a17ae 2273 /* Update Remote IP and Remote AS fields if needed */
2274 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2275 || iflp->rmt_ip.s_addr != addr.s_addr) {
16f1b9ee 2276
d62a17ae 2277 iflp->rmt_as = as;
2278 iflp->rmt_ip.s_addr = addr.s_addr;
2279 SET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2280
d62a17ae 2281 /* force protocols to update LINK STATE due to parameters change
2282 */
2283 if (if_is_operative(ifp))
2284 zebra_interface_parameters_update(ifp);
2285 }
2286 return CMD_SUCCESS;
16f1b9ee
OD
2287}
2288
2289DEFUN (no_link_params_inter_as,
2290 no_link_params_inter_as_cmd,
2291 "no neighbor",
2292 NO_STR
2293 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2294{
d62a17ae 2295 VTY_DECLVAR_CONTEXT(interface, ifp);
2296 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2297
d62a17ae 2298 /* Reset Remote IP and AS neighbor */
2299 iflp->rmt_as = 0;
2300 iflp->rmt_ip.s_addr = 0;
2301 UNSET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2302
d62a17ae 2303 /* force protocols to update LINK STATE due to parameters change */
2304 if (if_is_operative(ifp))
2305 zebra_interface_parameters_update(ifp);
16f1b9ee 2306
d62a17ae 2307 return CMD_SUCCESS;
16f1b9ee
OD
2308}
2309
d62a17ae 2310/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2311 * draft-ietf-isis-metric-extensions-07.txt */
16f1b9ee
OD
2312DEFUN (link_params_delay,
2313 link_params_delay_cmd,
b62ecea5 2314 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 2315 "Unidirectional Average Link Delay\n"
b62ecea5
QY
2316 "Average delay in micro-second as decimal (0...16777215)\n"
2317 "Minimum delay\n"
2318 "Minimum delay in micro-second as decimal (0...16777215)\n"
2319 "Maximum delay\n"
2320 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 2321{
d62a17ae 2322 /* Get and Check new delay values */
d7c0a89a 2323 uint32_t delay = 0, low = 0, high = 0;
d62a17ae 2324 delay = strtoul(argv[1]->arg, NULL, 10);
2325 if (argc == 6) {
2326 low = strtoul(argv[3]->arg, NULL, 10);
2327 high = strtoul(argv[5]->arg, NULL, 10);
2328 }
2329
2330 VTY_DECLVAR_CONTEXT(interface, ifp);
2331 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2332 uint8_t update = 0;
d62a17ae 2333
2334 if (argc == 2) {
2335 /* Check new delay value against old Min and Max delays if set
2336 */
2337 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2338 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2339 vty_out(vty,
2340 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2341 iflp->min_delay, iflp->max_delay);
2342 return CMD_WARNING_CONFIG_FAILED;
2343 }
2344 /* Update delay if value is not set or change */
2345 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2346 iflp->av_delay = delay;
2347 SET_PARAM(iflp, LP_DELAY);
2348 update = 1;
2349 }
2350 /* Unset Min and Max delays if already set */
2351 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2352 iflp->min_delay = 0;
2353 iflp->max_delay = 0;
2354 UNSET_PARAM(iflp, LP_MM_DELAY);
2355 update = 1;
2356 }
2357 } else {
2358 /* Check new delays value coherency */
2359 if (delay <= low || delay >= high) {
2360 vty_out(vty,
2361 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2362 low, high);
2363 return CMD_WARNING_CONFIG_FAILED;
2364 }
2365 /* Update Delays if needed */
2366 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2367 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2368 || iflp->av_delay != delay || iflp->min_delay != low
2369 || iflp->max_delay != high) {
2370 iflp->av_delay = delay;
2371 SET_PARAM(iflp, LP_DELAY);
2372 iflp->min_delay = low;
2373 iflp->max_delay = high;
2374 SET_PARAM(iflp, LP_MM_DELAY);
2375 update = 1;
2376 }
2377 }
2378
2379 /* force protocols to update LINK STATE due to parameters change */
2380 if (update == 1 && if_is_operative(ifp))
2381 zebra_interface_parameters_update(ifp);
2382
2383 return CMD_SUCCESS;
16f1b9ee
OD
2384}
2385
16f1b9ee
OD
2386DEFUN (no_link_params_delay,
2387 no_link_params_delay_cmd,
2388 "no delay",
2389 NO_STR
3ddccf18 2390 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 2391{
d62a17ae 2392 VTY_DECLVAR_CONTEXT(interface, ifp);
2393 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2394
d62a17ae 2395 /* Unset Delays */
2396 iflp->av_delay = 0;
2397 UNSET_PARAM(iflp, LP_DELAY);
2398 iflp->min_delay = 0;
2399 iflp->max_delay = 0;
2400 UNSET_PARAM(iflp, LP_MM_DELAY);
16f1b9ee 2401
d62a17ae 2402 /* force protocols to update LINK STATE due to parameters change */
2403 if (if_is_operative(ifp))
2404 zebra_interface_parameters_update(ifp);
16f1b9ee 2405
d62a17ae 2406 return CMD_SUCCESS;
16f1b9ee
OD
2407}
2408
2409DEFUN (link_params_delay_var,
2410 link_params_delay_var_cmd,
6147e2c6 2411 "delay-variation (0-16777215)",
16f1b9ee
OD
2412 "Unidirectional Link Delay Variation\n"
2413 "delay variation in micro-second as decimal (0...16777215)\n")
2414{
d62a17ae 2415 int idx_number = 1;
2416 VTY_DECLVAR_CONTEXT(interface, ifp);
2417 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2418 uint32_t value;
16f1b9ee 2419
d62a17ae 2420 value = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2421
d62a17ae 2422 /* Update Delay Variation if needed */
2423 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
16f1b9ee 2424
d62a17ae 2425 return CMD_SUCCESS;
16f1b9ee
OD
2426}
2427
2428DEFUN (no_link_params_delay_var,
2429 no_link_params_delay_var_cmd,
2430 "no delay-variation",
2431 NO_STR
3ddccf18 2432 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 2433{
d62a17ae 2434 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2435
d62a17ae 2436 /* Unset Delay Variation */
2437 link_param_cmd_unset(ifp, LP_DELAY_VAR);
16f1b9ee 2438
d62a17ae 2439 return CMD_SUCCESS;
16f1b9ee
OD
2440}
2441
2442DEFUN (link_params_pkt_loss,
2443 link_params_pkt_loss_cmd,
2444 "packet-loss PERCENTAGE",
2445 "Unidirectional Link Packet Loss\n"
2446 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2447{
d62a17ae 2448 int idx_percentage = 1;
2449 VTY_DECLVAR_CONTEXT(interface, ifp);
2450 struct if_link_params *iflp = if_link_params_get(ifp);
2451 float fval;
16f1b9ee 2452
d62a17ae 2453 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2454 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2455 safe_strerror(errno));
2456 return CMD_WARNING_CONFIG_FAILED;
2457 }
16f1b9ee 2458
d62a17ae 2459 if (fval > MAX_PKT_LOSS)
2460 fval = MAX_PKT_LOSS;
16f1b9ee 2461
d62a17ae 2462 /* Update Packet Loss if needed */
2463 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
16f1b9ee 2464
d62a17ae 2465 return CMD_SUCCESS;
16f1b9ee
OD
2466}
2467
2468DEFUN (no_link_params_pkt_loss,
2469 no_link_params_pkt_loss_cmd,
2470 "no packet-loss",
2471 NO_STR
3ddccf18 2472 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 2473{
d62a17ae 2474 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2475
d62a17ae 2476 /* Unset Packet Loss */
2477 link_param_cmd_unset(ifp, LP_PKT_LOSS);
16f1b9ee 2478
d62a17ae 2479 return CMD_SUCCESS;
16f1b9ee
OD
2480}
2481
2482DEFUN (link_params_res_bw,
2483 link_params_res_bw_cmd,
2484 "res-bw BANDWIDTH",
2485 "Unidirectional Residual Bandwidth\n"
2486 "Bytes/second (IEEE floating point format)\n")
2487{
d62a17ae 2488 int idx_bandwidth = 1;
2489 VTY_DECLVAR_CONTEXT(interface, ifp);
2490 struct if_link_params *iflp = if_link_params_get(ifp);
2491 float bw;
16f1b9ee 2492
d62a17ae 2493 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2494 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2495 safe_strerror(errno));
2496 return CMD_WARNING_CONFIG_FAILED;
2497 }
16f1b9ee 2498
d62a17ae 2499 /* Check that bandwidth is not greater than maximum bandwidth parameter
2500 */
2501 if (bw > iflp->max_bw) {
2502 vty_out(vty,
2503 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2504 iflp->max_bw);
2505 return CMD_WARNING_CONFIG_FAILED;
2506 }
16f1b9ee 2507
d62a17ae 2508 /* Update Residual Bandwidth if needed */
2509 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
16f1b9ee 2510
d62a17ae 2511 return CMD_SUCCESS;
16f1b9ee
OD
2512}
2513
2514DEFUN (no_link_params_res_bw,
2515 no_link_params_res_bw_cmd,
2516 "no res-bw",
2517 NO_STR
3ddccf18 2518 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 2519{
d62a17ae 2520 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2521
d62a17ae 2522 /* Unset Residual Bandwidth */
2523 link_param_cmd_unset(ifp, LP_RES_BW);
16f1b9ee 2524
d62a17ae 2525 return CMD_SUCCESS;
16f1b9ee
OD
2526}
2527
2528DEFUN (link_params_ava_bw,
2529 link_params_ava_bw_cmd,
2530 "ava-bw BANDWIDTH",
2531 "Unidirectional Available Bandwidth\n"
2532 "Bytes/second (IEEE floating point format)\n")
2533{
d62a17ae 2534 int idx_bandwidth = 1;
2535 VTY_DECLVAR_CONTEXT(interface, ifp);
2536 struct if_link_params *iflp = if_link_params_get(ifp);
2537 float bw;
16f1b9ee 2538
d62a17ae 2539 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2540 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2541 safe_strerror(errno));
2542 return CMD_WARNING_CONFIG_FAILED;
2543 }
16f1b9ee 2544
d62a17ae 2545 /* Check that bandwidth is not greater than maximum bandwidth parameter
2546 */
2547 if (bw > iflp->max_bw) {
2548 vty_out(vty,
2549 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2550 iflp->max_bw);
2551 return CMD_WARNING_CONFIG_FAILED;
2552 }
16f1b9ee 2553
d62a17ae 2554 /* Update Residual Bandwidth if needed */
2555 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
16f1b9ee 2556
d62a17ae 2557 return CMD_SUCCESS;
16f1b9ee
OD
2558}
2559
2560DEFUN (no_link_params_ava_bw,
2561 no_link_params_ava_bw_cmd,
2562 "no ava-bw",
2563 NO_STR
3ddccf18 2564 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 2565{
d62a17ae 2566 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2567
d62a17ae 2568 /* Unset Available Bandwidth */
2569 link_param_cmd_unset(ifp, LP_AVA_BW);
16f1b9ee 2570
d62a17ae 2571 return CMD_SUCCESS;
16f1b9ee
OD
2572}
2573
2574DEFUN (link_params_use_bw,
2575 link_params_use_bw_cmd,
2576 "use-bw BANDWIDTH",
2577 "Unidirectional Utilised Bandwidth\n"
2578 "Bytes/second (IEEE floating point format)\n")
2579{
d62a17ae 2580 int idx_bandwidth = 1;
2581 VTY_DECLVAR_CONTEXT(interface, ifp);
2582 struct if_link_params *iflp = if_link_params_get(ifp);
2583 float bw;
16f1b9ee 2584
d62a17ae 2585 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2586 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2587 safe_strerror(errno));
2588 return CMD_WARNING_CONFIG_FAILED;
2589 }
16f1b9ee 2590
d62a17ae 2591 /* Check that bandwidth is not greater than maximum bandwidth parameter
2592 */
2593 if (bw > iflp->max_bw) {
2594 vty_out(vty,
2595 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2596 iflp->max_bw);
2597 return CMD_WARNING_CONFIG_FAILED;
2598 }
16f1b9ee 2599
d62a17ae 2600 /* Update Utilized Bandwidth if needed */
2601 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
16f1b9ee 2602
d62a17ae 2603 return CMD_SUCCESS;
16f1b9ee
OD
2604}
2605
2606DEFUN (no_link_params_use_bw,
2607 no_link_params_use_bw_cmd,
2608 "no use-bw",
2609 NO_STR
3ddccf18 2610 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 2611{
d62a17ae 2612 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2613
d62a17ae 2614 /* Unset Utilised Bandwidth */
2615 link_param_cmd_unset(ifp, LP_USE_BW);
16f1b9ee 2616
d62a17ae 2617 return CMD_SUCCESS;
16f1b9ee
OD
2618}
2619
d62a17ae 2620static int ip_address_install(struct vty *vty, struct interface *ifp,
2621 const char *addr_str, const char *peer_str,
2622 const char *label)
718e3744 2623{
d62a17ae 2624 struct zebra_if *if_data;
a07df329 2625 struct prefix_ipv4 lp, pp;
d62a17ae 2626 struct connected *ifc;
2627 struct prefix_ipv4 *p;
2628 int ret;
718e3744 2629
d62a17ae 2630 if_data = ifp->info;
bfac8dcd 2631
a07df329 2632 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2633 if (ret <= 0) {
2634 vty_out(vty, "%% Malformed address \n");
2635 return CMD_WARNING_CONFIG_FAILED;
2636 }
718e3744 2637
a07df329 2638 if (ipv4_martian(&lp.prefix)) {
d62a17ae 2639 vty_out(vty, "%% Invalid address\n");
2640 return CMD_WARNING_CONFIG_FAILED;
2641 }
d914d5ff 2642
a07df329
DL
2643 if (peer_str) {
2644 if (lp.prefixlen != 32) {
2645 vty_out(vty,
2646 "%% Local prefix length for P-t-P address must be /32\n");
2647 return CMD_WARNING_CONFIG_FAILED;
2648 }
2649
2650 ret = str2prefix_ipv4(peer_str, &pp);
2651 if (ret <= 0) {
2652 vty_out(vty, "%% Malformed peer address\n");
2653 return CMD_WARNING_CONFIG_FAILED;
2654 }
2655 }
2656
2657 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2658 if (!ifc) {
2659 ifc = connected_new();
2660 ifc->ifp = ifp;
2661
2662 /* Address. */
2663 p = prefix_ipv4_new();
a07df329 2664 *p = lp;
d62a17ae 2665 ifc->address = (struct prefix *)p;
2666
a07df329
DL
2667 if (peer_str) {
2668 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2669 p = prefix_ipv4_new();
2670 *p = pp;
2671 ifc->destination = (struct prefix *)p;
2672 } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
d62a17ae 2673 p = prefix_ipv4_new();
a07df329 2674 *p = lp;
d62a17ae 2675 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
2676 p->prefixlen);
2677 ifc->destination = (struct prefix *)p;
2678 }
718e3744 2679
d62a17ae 2680 /* Label. */
2681 if (label)
2682 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
718e3744 2683
d62a17ae 2684 /* Add to linked list. */
2685 listnode_add(ifp->connected, ifc);
718e3744 2686 }
2687
d62a17ae 2688 /* This address is configured from zebra. */
2689 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2690 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2691
2692 /* In case of this route need to install kernel. */
2693 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2694 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2695 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2696 /* Some system need to up the interface to set IP address. */
2697 if (!if_is_up(ifp)) {
2698 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2699 if_refresh(ifp);
2700 }
2701
2702 ret = if_set_prefix(ifp, ifc);
2703 if (ret < 0) {
2704 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2705 safe_strerror(errno));
2706 return CMD_WARNING_CONFIG_FAILED;
2707 }
2708
2709 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2710 /* The address will be advertised to zebra clients when the
2711 * notification
2712 * from the kernel has been received.
2713 * It will also be added to the subnet chain list, then. */
2714 }
2715
2716 return CMD_SUCCESS;
2717}
2718
2719static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2720 const char *addr_str, const char *peer_str,
2721 const char *label)
2722{
a07df329 2723 struct prefix_ipv4 lp, pp;
d62a17ae 2724 struct connected *ifc;
2725 int ret;
2726
2727 /* Convert to prefix structure. */
a07df329 2728 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2729 if (ret <= 0) {
2730 vty_out(vty, "%% Malformed address \n");
2731 return CMD_WARNING_CONFIG_FAILED;
2732 }
2733
a07df329
DL
2734 if (peer_str) {
2735 if (lp.prefixlen != 32) {
2736 vty_out(vty,
2737 "%% Local prefix length for P-t-P address must be /32\n");
2738 return CMD_WARNING_CONFIG_FAILED;
2739 }
2740
2741 ret = str2prefix_ipv4(peer_str, &pp);
2742 if (ret <= 0) {
2743 vty_out(vty, "%% Malformed peer address\n");
2744 return CMD_WARNING_CONFIG_FAILED;
2745 }
2746 }
2747
d62a17ae 2748 /* Check current interface address. */
a07df329 2749 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2750 if (!ifc) {
2751 vty_out(vty, "%% Can't find address\n");
2752 return CMD_WARNING_CONFIG_FAILED;
2753 }
2754
2755 /* This is not configured address. */
2756 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2757 return CMD_WARNING_CONFIG_FAILED;
2758
2759 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2760
2761 /* This is not real address or interface is not active. */
2762 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2763 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2764 listnode_delete(ifp->connected, ifc);
2765 connected_free(ifc);
2766 return CMD_WARNING_CONFIG_FAILED;
2767 }
2768
2769 /* This is real route. */
2770 ret = if_unset_prefix(ifp, ifc);
2771 if (ret < 0) {
2772 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2773 safe_strerror(errno));
2774 return CMD_WARNING_CONFIG_FAILED;
2775 }
2776 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2777 /* we will receive a kernel notification about this route being removed.
2778 * this will trigger its removal from the connected list. */
2779 return CMD_SUCCESS;
718e3744 2780}
2781
2782DEFUN (ip_address,
2783 ip_address_cmd,
2784 "ip address A.B.C.D/M",
2785 "Interface Internet Protocol config commands\n"
2786 "Set the IP address of an interface\n"
2787 "IP address (e.g. 10.0.0.1/8)\n")
2788{
d62a17ae 2789 int idx_ipv4_prefixlen = 2;
2790 VTY_DECLVAR_CONTEXT(interface, ifp);
2791 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2792 NULL);
718e3744 2793}
2794
2795DEFUN (no_ip_address,
2796 no_ip_address_cmd,
2797 "no ip address A.B.C.D/M",
2798 NO_STR
2799 "Interface Internet Protocol config commands\n"
2800 "Set the IP address of an interface\n"
efd7904e 2801 "IP Address (e.g. 10.0.0.1/8)\n")
718e3744 2802{
d62a17ae 2803 int idx_ipv4_prefixlen = 3;
2804 VTY_DECLVAR_CONTEXT(interface, ifp);
2805 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2806 NULL, NULL);
718e3744 2807}
2808
60466a63
QY
2809DEFUN(ip_address_peer,
2810 ip_address_peer_cmd,
2811 "ip address A.B.C.D peer A.B.C.D/M",
2812 "Interface Internet Protocol config commands\n"
2813 "Set the IP address of an interface\n"
2814 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2815 "Specify P-t-P address\n"
2816 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2817{
2818 VTY_DECLVAR_CONTEXT(interface, ifp);
2819 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
2820}
2821
60466a63
QY
2822DEFUN(no_ip_address_peer,
2823 no_ip_address_peer_cmd,
2824 "no ip address A.B.C.D peer A.B.C.D/M",
2825 NO_STR
2826 "Interface Internet Protocol config commands\n"
2827 "Set the IP address of an interface\n"
2828 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2829 "Specify P-t-P address\n"
2830 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2831{
2832 VTY_DECLVAR_CONTEXT(interface, ifp);
2833 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
2834}
986aa00f 2835
718e3744 2836#ifdef HAVE_NETLINK
718e3744 2837DEFUN (ip_address_label,
2838 ip_address_label_cmd,
2839 "ip address A.B.C.D/M label LINE",
2840 "Interface Internet Protocol config commands\n"
2841 "Set the IP address of an interface\n"
2842 "IP address (e.g. 10.0.0.1/8)\n"
2843 "Label of this address\n"
2844 "Label\n")
2845{
d62a17ae 2846 int idx_ipv4_prefixlen = 2;
2847 int idx_line = 4;
2848 VTY_DECLVAR_CONTEXT(interface, ifp);
2849 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2850 argv[idx_line]->arg);
718e3744 2851}
2852
2853DEFUN (no_ip_address_label,
2854 no_ip_address_label_cmd,
2855 "no ip address A.B.C.D/M label LINE",
2856 NO_STR
2857 "Interface Internet Protocol config commands\n"
2858 "Set the IP address of an interface\n"
2859 "IP address (e.g. 10.0.0.1/8)\n"
2860 "Label of this address\n"
2861 "Label\n")
2862{
d62a17ae 2863 int idx_ipv4_prefixlen = 3;
2864 int idx_line = 5;
2865 VTY_DECLVAR_CONTEXT(interface, ifp);
2866 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2867 NULL, argv[idx_line]->arg);
718e3744 2868}
2869#endif /* HAVE_NETLINK */
2870
d62a17ae 2871static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2872 const char *addr_str, const char *peer_str,
b1bd1015 2873 const char *label)
d62a17ae 2874{
2875 struct zebra_if *if_data;
2876 struct prefix_ipv6 cp;
2877 struct connected *ifc;
2878 struct prefix_ipv6 *p;
2879 int ret;
2880
2881 if_data = ifp->info;
2882
2883 ret = str2prefix_ipv6(addr_str, &cp);
2884 if (ret <= 0) {
2885 vty_out(vty, "%% Malformed address \n");
2886 return CMD_WARNING_CONFIG_FAILED;
718e3744 2887 }
2888
d62a17ae 2889 if (ipv6_martian(&cp.prefix)) {
2890 vty_out(vty, "%% Invalid address\n");
2891 return CMD_WARNING_CONFIG_FAILED;
2892 }
718e3744 2893
d62a17ae 2894 ifc = connected_check(ifp, (struct prefix *)&cp);
2895 if (!ifc) {
2896 ifc = connected_new();
2897 ifc->ifp = ifp;
2898
2899 /* Address. */
2900 p = prefix_ipv6_new();
2901 *p = cp;
2902 ifc->address = (struct prefix *)p;
2903
d62a17ae 2904 /* Label. */
2905 if (label)
2906 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2907
2908 /* Add to linked list. */
2909 listnode_add(ifp->connected, ifc);
718e3744 2910 }
2911
d62a17ae 2912 /* This address is configured from zebra. */
2913 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2914 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2915
2916 /* In case of this route need to install kernel. */
2917 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2918 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2919 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2920 /* Some system need to up the interface to set IP address. */
2921 if (!if_is_up(ifp)) {
2922 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2923 if_refresh(ifp);
2924 }
2925
2926 ret = if_prefix_add_ipv6(ifp, ifc);
2927
2928 if (ret < 0) {
2929 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2930 safe_strerror(errno));
2931 return CMD_WARNING_CONFIG_FAILED;
2932 }
2933
2934 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2935 /* The address will be advertised to zebra clients when the
2936 * notification
2937 * from the kernel has been received. */
2938 }
718e3744 2939
d62a17ae 2940 return CMD_SUCCESS;
718e3744 2941}
2942
b6120505 2943/* Return true if an ipv6 address is configured on ifp */
d62a17ae 2944int ipv6_address_configured(struct interface *ifp)
2945{
2946 struct connected *connected;
2947 struct listnode *node;
2948
2949 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2950 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2951 && (connected->address->family == AF_INET6))
2952 return 1;
2953
2954 return 0;
2955}
2956
2957static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2958 const char *addr_str, const char *peer_str,
b1bd1015 2959 const char *label)
d62a17ae 2960{
2961 struct prefix_ipv6 cp;
2962 struct connected *ifc;
2963 int ret;
2964
2965 /* Convert to prefix structure. */
2966 ret = str2prefix_ipv6(addr_str, &cp);
2967 if (ret <= 0) {
2968 vty_out(vty, "%% Malformed address \n");
2969 return CMD_WARNING_CONFIG_FAILED;
2970 }
2971
2972 /* Check current interface address. */
2973 ifc = connected_check(ifp, (struct prefix *)&cp);
2974 if (!ifc) {
2975 vty_out(vty, "%% Can't find address\n");
2976 return CMD_WARNING_CONFIG_FAILED;
2977 }
2978
2979 /* This is not configured address. */
2980 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2981 return CMD_WARNING_CONFIG_FAILED;
2982
2983 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2984
2985 /* This is not real address or interface is not active. */
2986 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2987 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2988 listnode_delete(ifp->connected, ifc);
2989 connected_free(ifc);
2990 return CMD_WARNING_CONFIG_FAILED;
2991 }
2992
2993 /* This is real route. */
2994 ret = if_prefix_delete_ipv6(ifp, ifc);
2995 if (ret < 0) {
2996 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2997 safe_strerror(errno));
2998 return CMD_WARNING_CONFIG_FAILED;
2999 }
3000
3001 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
3002 /* This information will be propagated to the zclients when the
3003 * kernel notification is received. */
3004 return CMD_SUCCESS;
718e3744 3005}
3006
3007DEFUN (ipv6_address,
3008 ipv6_address_cmd,
3009 "ipv6 address X:X::X:X/M",
e23949c0 3010 "Interface IPv6 config commands\n"
718e3744 3011 "Set the IP address of an interface\n"
3012 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3013{
d62a17ae 3014 int idx_ipv6_prefixlen = 2;
3015 VTY_DECLVAR_CONTEXT(interface, ifp);
3016 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
b1bd1015 3017 NULL, NULL);
718e3744 3018}
3019
3020DEFUN (no_ipv6_address,
3021 no_ipv6_address_cmd,
3022 "no ipv6 address X:X::X:X/M",
3023 NO_STR
e23949c0 3024 "Interface IPv6 config commands\n"
718e3744 3025 "Set the IP address of an interface\n"
3026 "IPv6 address (e.g. 3ffe:506::1/48)\n")
3027{
d62a17ae 3028 int idx_ipv6_prefixlen = 3;
3029 VTY_DECLVAR_CONTEXT(interface, ifp);
3030 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
b1bd1015 3031 NULL, NULL);
d62a17ae 3032}
3033
3034static int link_params_config_write(struct vty *vty, struct interface *ifp)
3035{
3036 int i;
3037
3038 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
3039 return -1;
986aa00f 3040
d62a17ae 3041 struct if_link_params *iflp = ifp->link_params;
3042
3043 vty_out(vty, " link-params\n");
3044 vty_out(vty, " enable\n");
3045 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
3046 vty_out(vty, " metric %u\n", iflp->te_metric);
3047 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
3048 vty_out(vty, " max-bw %g\n", iflp->max_bw);
3049 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
3050 && iflp->max_rsv_bw != iflp->default_bw)
3051 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
3052 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
3053 for (i = 0; i < 8; i++)
3054 if (iflp->unrsv_bw[i] != iflp->default_bw)
3055 vty_out(vty, " unrsv-bw %d %g\n", i,
3056 iflp->unrsv_bw[i]);
3057 }
3058 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
3059 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
3060 if (IS_PARAM_SET(iflp, LP_DELAY)) {
3061 vty_out(vty, " delay %u", iflp->av_delay);
3062 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
3063 vty_out(vty, " min %u", iflp->min_delay);
3064 vty_out(vty, " max %u", iflp->max_delay);
3065 }
3066 vty_out(vty, "\n");
bfac8dcd 3067 }
d62a17ae 3068 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
3069 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
3070 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
3071 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
3072 if (IS_PARAM_SET(iflp, LP_AVA_BW))
3073 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
3074 if (IS_PARAM_SET(iflp, LP_RES_BW))
3075 vty_out(vty, " res-bw %g\n", iflp->res_bw);
3076 if (IS_PARAM_SET(iflp, LP_USE_BW))
3077 vty_out(vty, " use-bw %g\n", iflp->use_bw);
3078 if (IS_PARAM_SET(iflp, LP_RMT_AS))
3079 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
3080 iflp->rmt_as);
3081 vty_out(vty, " exit-link-params\n");
3082 return 0;
3083}
3084
3085static int if_config_write(struct vty *vty)
3086{
7fe96307 3087 struct vrf *vrf0;
d62a17ae 3088 struct interface *ifp;
3089
3090 zebra_ptm_write(vty);
3091
7fe96307
A
3092 RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
3093 FOR_ALL_INTERFACES (vrf0, ifp) {
a2addae8
RW
3094 struct zebra_if *if_data;
3095 struct listnode *addrnode;
3096 struct connected *ifc;
3097 struct prefix *p;
3098 struct vrf *vrf;
d62a17ae 3099
a2addae8
RW
3100 if_data = ifp->info;
3101 vrf = vrf_lookup_by_id(ifp->vrf_id);
d62a17ae 3102
a2addae8
RW
3103 if (ifp->vrf_id == VRF_DEFAULT)
3104 vty_frame(vty, "interface %s\n", ifp->name);
3105 else
3106 vty_frame(vty, "interface %s vrf %s\n",
3107 ifp->name, vrf->name);
d62a17ae 3108
a2addae8
RW
3109 if (if_data) {
3110 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
3111 vty_out(vty, " shutdown\n");
d62a17ae 3112
a2addae8
RW
3113 zebra_ptm_if_write(vty, if_data);
3114 }
bfac8dcd 3115
a2addae8
RW
3116 if (ifp->desc)
3117 vty_out(vty, " description %s\n", ifp->desc);
3118
3119 /* Assign bandwidth here to avoid unnecessary interface
3120 flap
3121 while processing config script */
3122 if (ifp->bandwidth != 0)
3123 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
3124
3125 if (!CHECK_FLAG(ifp->status,
3126 ZEBRA_INTERFACE_LINKDETECTION))
3127 vty_out(vty, " no link-detect\n");
3128
3129 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
3130 ifc)) {
3131 if (CHECK_FLAG(ifc->conf,
3132 ZEBRA_IFC_CONFIGURED)) {
3133 char buf[INET6_ADDRSTRLEN];
3134 p = ifc->address;
3135 vty_out(vty, " ip%s address %s",
3136 p->family == AF_INET ? ""
3137 : "v6",
a07df329 3138 inet_ntop(p->family,
60466a63
QY
3139 &p->u.prefix, buf,
3140 sizeof(buf)));
a2addae8
RW
3141 if (CONNECTED_PEER(ifc)) {
3142 p = ifc->destination;
3143 vty_out(vty, " peer %s",
3144 inet_ntop(p->family,
3145 &p->u.prefix,
3146 buf,
3147 sizeof(buf)));
3148 }
3149 vty_out(vty, "/%d", p->prefixlen);
718e3744 3150
a2addae8
RW
3151 if (ifc->label)
3152 vty_out(vty, " label %s",
3153 ifc->label);
718e3744 3154
a2addae8
RW
3155 vty_out(vty, "\n");
3156 }
d62a17ae 3157 }
718e3744 3158
a2addae8
RW
3159 if (if_data) {
3160 if (if_data->multicast
3161 != IF_ZEBRA_MULTICAST_UNSPEC)
3162 vty_out(vty, " %smulticast\n",
3163 if_data->multicast
3164 == IF_ZEBRA_MULTICAST_ON
3165 ? ""
3166 : "no ");
3167 }
718e3744 3168
a2addae8 3169 hook_call(zebra_if_config_wr, vty, ifp);
ca776988 3170
a2addae8 3171 link_params_config_write(vty, ifp);
16f1b9ee 3172
a2addae8
RW
3173 vty_endframe(vty, "!\n");
3174 }
d62a17ae 3175 return 0;
718e3744 3176}
3177
3178/* Allocate and initialize interface vector. */
d62a17ae 3179void zebra_if_init(void)
3180{
3181 /* Initialize interface and new hook. */
ce19a04a
DL
3182 hook_register_prio(if_add, 0, if_zebra_new_hook);
3183 hook_register_prio(if_del, 0, if_zebra_delete_hook);
d62a17ae 3184
3185 /* Install configuration write function. */
3186 install_node(&interface_node, if_config_write);
3187 install_node(&link_params_node, NULL);
3188 if_cmd_init();
3189
3190 install_element(VIEW_NODE, &show_interface_cmd);
3191 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
3192 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
3193 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
3194
3195 install_element(ENABLE_NODE, &show_interface_desc_cmd);
3196 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
3197 install_element(INTERFACE_NODE, &multicast_cmd);
3198 install_element(INTERFACE_NODE, &no_multicast_cmd);
3199 install_element(INTERFACE_NODE, &linkdetect_cmd);
3200 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
3201 install_element(INTERFACE_NODE, &shutdown_if_cmd);
3202 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
3203 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
3204 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
3205 install_element(INTERFACE_NODE, &ip_address_cmd);
3206 install_element(INTERFACE_NODE, &no_ip_address_cmd);
a07df329
DL
3207 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
3208 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
d62a17ae 3209 install_element(INTERFACE_NODE, &ipv6_address_cmd);
3210 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 3211#ifdef HAVE_NETLINK
d62a17ae 3212 install_element(INTERFACE_NODE, &ip_address_label_cmd);
3213 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
718e3744 3214#endif /* HAVE_NETLINK */
d62a17ae 3215 install_element(INTERFACE_NODE, &link_params_cmd);
3216 install_default(LINK_PARAMS_NODE);
3217 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
3218 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
3219 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
3220 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
3221 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
3222 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
3223 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
3224 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
3225 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
3226 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
3227 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
3228 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
3229 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
3230 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
3231 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
3232 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
3233 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
3234 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
3235 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
3236 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
3237 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
3238 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
3239 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
3240 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
718e3744 3241}