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