]> git.proxmox.com Git - mirror_frr.git/blame - zebra/interface.c
Merge pull request #3087 from opensourcerouting/bfd-memleak
[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
809static bool mac_is_same(char *mac1, char *mac2)
810{
811 if (mac1[0] == mac2[0] &&
812 mac1[1] == mac2[1] &&
813 mac1[2] == mac2[2] &&
814 mac1[3] == mac2[3] &&
815 mac1[4] == mac2[4] &&
816 mac1[5] == mac2[5])
817 return true;
818 else
819 return false;
820}
821
822void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
823 char mac[6],
824 struct in6_addr *address,
825 int add)
5c610faf 826{
d62a17ae 827 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
20089ae2 828 struct zebra_if *zif = ifp->info;
d62a17ae 829 char buf[16] = "169.254.0.1";
830 struct in_addr ipv4_ll;
5895d33f 831 ns_id_t ns_id;
5c610faf 832
d62a17ae 833 inet_pton(AF_INET, buf, &ipv4_ll);
5c610faf 834
009f8ad5 835 ns_id = zvrf->zns->ns_id;
d1479ec8 836
a8a4fa89 837 /*
f26bc773 838 * Remove existed arp record for the interface as netlink
839 * protocol does not have update message types
840 *
841 * supported message types are RTM_NEWNEIGH and RTM_DELNEIGH
842 */
ee98d1f1
DS
843 if (!mac_is_same(zif->neigh_mac, mac)) {
844 kernel_neigh_update(0, ifp->ifindex, ipv4_ll.s_addr,
845 mac, 6, ns_id);
d1479ec8 846
ee98d1f1
DS
847 /* Add arp record */
848 kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr,
849 mac, 6, ns_id);
850 }
d1479ec8 851
ee98d1f1 852 memcpy(&zif->neigh_mac[0], &mac[0], 6);
20089ae2
DS
853
854 /*
855 * We need to note whether or not we originated a v6
856 * neighbor entry for this interface. So that when
857 * someone unwisely accidently deletes this entry
858 * we can shove it back in.
859 */
860 zif->v6_2_v4_ll_neigh_entry = !!add;
861 memcpy(&zif->v6_2_v4_ll_addr6, address, sizeof(*address));
862
d62a17ae 863 zvrf->neigh_updates++;
5c610faf
DS
864}
865
ee98d1f1
DS
866void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
867 struct in6_addr *address, int add)
868{
869
870 char mac[6];
871
872 ipv6_ll_address_to_mac(address, (uint8_t *)mac);
873 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
874}
875
d62a17ae 876static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
5c610faf 877{
d62a17ae 878 if (listhead(ifp->nbr_connected)) {
879 struct nbr_connected *nbr_connected;
880 struct listnode *node;
5c610faf 881
d62a17ae 882 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
883 nbr_connected))
884 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
885 ifp, &nbr_connected->address->u.prefix6, 1);
886 }
5c610faf
DS
887}
888
d62a17ae 889void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)
5c610faf 890{
d62a17ae 891 if (listhead(ifp->nbr_connected)) {
892 struct nbr_connected *nbr_connected;
893 struct listnode *node;
5c610faf 894
d62a17ae 895 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node,
896 nbr_connected))
897 if_nbr_ipv6ll_to_ipv4ll_neigh_update(
898 ifp, &nbr_connected->address->u.prefix6, 0);
899 }
5c610faf
DS
900}
901
d62a17ae 902static void if_down_del_nbr_connected(struct interface *ifp)
a197c47c 903{
d62a17ae 904 struct nbr_connected *nbr_connected;
905 struct listnode *node, *nnode;
a197c47c 906
d62a17ae 907 for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode,
908 nbr_connected)) {
909 listnode_delete(ifp->nbr_connected, nbr_connected);
910 nbr_connected_free(nbr_connected);
911 }
a197c47c
DS
912}
913
718e3744 914/* Interface is up. */
d62a17ae 915void if_up(struct interface *ifp)
916{
917 struct zebra_if *zif;
918 struct interface *link_if;
154a3944 919 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
d62a17ae 920
921 zif = ifp->info;
922 zif->up_count++;
923 quagga_timestamp(2, zif->up_last, sizeof(zif->up_last));
924
925 /* Notify the protocol daemons. */
926 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
e914ccbe 927 flog_warn(EC_ZEBRA_PTM_NOT_READY,
9df414fe 928 "%s: interface %s hasn't passed ptm check\n",
d62a17ae 929 __func__, ifp->name);
930 return;
931 }
932 zebra_interface_up_update(ifp);
933
934 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp);
935
936#if defined(HAVE_RTADV)
937 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
938 if (zif->rtadv.AdvSendAdvertisements
939 && (zif->rtadv.MaxRtrAdvInterval >= 1000)) {
940 zif->rtadv.inFastRexmit = 1;
941 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
942 }
9c3bf1ce 943#endif
6c9678b4 944
d62a17ae 945 /* Install connected routes to the kernel. */
946 if_install_connected(ifp);
947
948 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
949 zlog_debug("%u: IF %s up, scheduling RIB processing",
950 ifp->vrf_id, ifp->name);
951 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
952
d62a17ae 953 /* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
954 * are checked to see if (remote) neighbor entries need to be installed
955 * on them for ARP suppression.
956 */
957 if (IS_ZEBRA_IF_VXLAN(ifp))
958 zebra_vxlan_if_up(ifp);
959 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
960 link_if = ifp;
961 zebra_vxlan_svi_up(ifp, link_if);
962 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
154a3944 963 link_if = if_lookup_by_index_per_ns(zvrf->zns,
71349e03 964 zif->link_ifindex);
d62a17ae 965 if (link_if)
966 zebra_vxlan_svi_up(ifp, link_if);
967 }
718e3744 968}
969
970/* Interface goes down. We have to manage different behavior of based
971 OS. */
d62a17ae 972void if_down(struct interface *ifp)
973{
974 struct zebra_if *zif;
975 struct interface *link_if;
154a3944 976 struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
d62a17ae 977
978 zif = ifp->info;
979 zif->down_count++;
980 quagga_timestamp(2, zif->down_last, sizeof(zif->down_last));
981
982 /* Handle interface down for specific types for EVPN. Non-VxLAN
983 * interfaces
984 * are checked to see if (remote) neighbor entries need to be purged
985 * for ARP suppression.
986 */
987 if (IS_ZEBRA_IF_VXLAN(ifp))
988 zebra_vxlan_if_down(ifp);
989 else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
990 link_if = ifp;
991 zebra_vxlan_svi_down(ifp, link_if);
992 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
154a3944 993 link_if = if_lookup_by_index_per_ns(zvrf->zns,
71349e03 994 zif->link_ifindex);
d62a17ae 995 if (link_if)
996 zebra_vxlan_svi_down(ifp, link_if);
997 }
2232a77c 998
13d60d35 999
d62a17ae 1000 /* Notify to the protocol daemons. */
1001 zebra_interface_down_update(ifp);
718e3744 1002
d62a17ae 1003 /* Uninstall connected routes from the kernel. */
1004 if_uninstall_connected(ifp);
718e3744 1005
d62a17ae 1006 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
1007 zlog_debug("%u: IF %s down, scheduling RIB processing",
1008 ifp->vrf_id, ifp->name);
1009 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
5c610faf 1010
d62a17ae 1011 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
a197c47c 1012
d62a17ae 1013 /* Delete all neighbor addresses learnt through IPv6 RA */
1014 if_down_del_nbr_connected(ifp);
718e3744 1015}
1016
d62a17ae 1017void if_refresh(struct interface *ifp)
718e3744 1018{
d62a17ae 1019 if_get_flags(ifp);
718e3744 1020}
1021
680c278f
PG
1022void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
1023 ns_id_t ns_id)
6675513d 1024{
d62a17ae 1025 struct zebra_if *zif;
6675513d 1026
0e4864ea
PG
1027 if (IS_ZEBRA_IF_VETH(ifp))
1028 return;
d62a17ae 1029 zif = (struct zebra_if *)ifp->info;
1030 zif->link_ifindex = link_ifindex;
680c278f 1031 zif->link = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
d62a17ae 1032 link_ifindex);
6675513d 1033}
1034
98efddf1
DS
1035/*
1036 * during initial link dump kernel does not order lower devices before
1037 * upper devices so we need to fixup link dependencies at the end of dump
1038 */
520ebf72
AK
1039void zebra_if_update_all_links(void)
1040{
1041 struct route_node *rn;
1042 struct interface *ifp;
1043 struct zebra_if *zif;
1044 struct zebra_ns *ns;
1045
1046 if (IS_ZEBRA_DEBUG_KERNEL)
1047 zlog_info("fixup link dependencies");
1048
1049 ns = zebra_ns_lookup(NS_DEFAULT);
1050 for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
1051 ifp = (struct interface *)rn->info;
1052 if (!ifp)
1053 continue;
1054 zif = ifp->info;
1055 if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
1056 zif->link = if_lookup_by_index_per_ns(ns,
1057 zif->link_ifindex);
1058 if (IS_ZEBRA_DEBUG_KERNEL)
1059 zlog_debug("interface %s/%d's lower fixup to %s/%d",
1060 ifp->name, ifp->ifindex,
1061 zif->link?zif->link->name:"unk",
1062 zif->link_ifindex);
1063 }
1064 }
1065}
1066
1067
d5a5c8f0 1068
718e3744 1069/* Output prefix string to vty. */
d62a17ae 1070static int prefix_vty_out(struct vty *vty, struct prefix *p)
718e3744 1071{
d62a17ae 1072 char str[INET6_ADDRSTRLEN];
718e3744 1073
d62a17ae 1074 inet_ntop(p->family, &p->u.prefix, str, sizeof(str));
1075 vty_out(vty, "%s", str);
1076 return strlen(str);
718e3744 1077}
1078
1079/* Dump if address information to vty. */
d62a17ae 1080static void connected_dump_vty(struct vty *vty, struct connected *connected)
718e3744 1081{
d62a17ae 1082 struct prefix *p;
718e3744 1083
d62a17ae 1084 /* Print interface address. */
1085 p = connected->address;
1086 vty_out(vty, " %s ", prefix_family_str(p));
1087 prefix_vty_out(vty, p);
1088 vty_out(vty, "/%d", p->prefixlen);
718e3744 1089
d62a17ae 1090 /* If there is destination address, print it. */
1091 if (connected->destination) {
1092 vty_out(vty,
1093 (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
1094 prefix_vty_out(vty, connected->destination);
abffde07
DL
1095 if (CONNECTED_PEER(connected))
1096 vty_out(vty, "/%d", connected->destination->prefixlen);
d62a17ae 1097 }
718e3744 1098
d62a17ae 1099 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY))
1100 vty_out(vty, " secondary");
718e3744 1101
d62a17ae 1102 if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED))
1103 vty_out(vty, " unnumbered");
525c1839 1104
d62a17ae 1105 if (connected->label)
1106 vty_out(vty, " %s", connected->label);
718e3744 1107
d62a17ae 1108 vty_out(vty, "\n");
718e3744 1109}
1110
a80beece 1111/* Dump interface neighbor address information to vty. */
d62a17ae 1112static void nbr_connected_dump_vty(struct vty *vty,
1113 struct nbr_connected *connected)
a80beece 1114{
d62a17ae 1115 struct prefix *p;
a80beece 1116
d62a17ae 1117 /* Print interface address. */
1118 p = connected->address;
1119 vty_out(vty, " %s ", prefix_family_str(p));
1120 prefix_vty_out(vty, p);
1121 vty_out(vty, "/%d", p->prefixlen);
a80beece 1122
d62a17ae 1123 vty_out(vty, "\n");
a80beece
DS
1124}
1125
d62a17ae 1126static const char *zebra_ziftype_2str(zebra_iftype_t zif_type)
6675513d 1127{
d62a17ae 1128 switch (zif_type) {
1129 case ZEBRA_IF_OTHER:
1130 return "Other";
1131 break;
6675513d 1132
d62a17ae 1133 case ZEBRA_IF_BRIDGE:
1134 return "Bridge";
1135 break;
6675513d 1136
d62a17ae 1137 case ZEBRA_IF_VLAN:
1138 return "Vlan";
1139 break;
6675513d 1140
d62a17ae 1141 case ZEBRA_IF_VXLAN:
1142 return "Vxlan";
1143 break;
6675513d 1144
d62a17ae 1145 case ZEBRA_IF_VRF:
1146 return "VRF";
1147 break;
6675513d 1148
0e4864ea
PG
1149 case ZEBRA_IF_VETH:
1150 return "VETH";
1151 break;
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
8cb73ba4
DS
1282 if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
1283 vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
1284 if (zebra_if->link)
1285 vty_out(vty, "(%s)\n", zebra_if->link->name);
1286 else
1287 vty_out(vty, "(Unknown)\n");
1288 }
d62a17ae 1289
1290 if (HAS_LINK_PARAMS(ifp)) {
1291 int i;
1292 struct if_link_params *iflp = ifp->link_params;
1293 vty_out(vty, " Traffic Engineering Link Parameters:\n");
1294 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1295 vty_out(vty, " TE metric %u\n", iflp->te_metric);
1296 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1297 vty_out(vty, " Maximum Bandwidth %g (Byte/s)\n",
1298 iflp->max_bw);
1299 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1300 vty_out(vty,
1301 " Maximum Reservable Bandwidth %g (Byte/s)\n",
1302 iflp->max_rsv_bw);
1303 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1304 vty_out(vty,
1305 " Unreserved Bandwidth per Class Type in Byte/s:\n");
1306 for (i = 0; i < MAX_CLASS_TYPE; i += 2)
1307 vty_out(vty,
1308 " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
1309 i, iflp->unrsv_bw[i], i + 1,
1310 iflp->unrsv_bw[i + 1]);
1311 }
1312
1313 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1314 vty_out(vty, " Administrative Group:%u\n",
1315 iflp->admin_grp);
1316 if (IS_PARAM_SET(iflp, LP_DELAY)) {
1317 vty_out(vty, " Link Delay Average: %u (micro-sec.)",
1318 iflp->av_delay);
1319 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
1320 vty_out(vty, " Min: %u (micro-sec.)",
1321 iflp->min_delay);
1322 vty_out(vty, " Max: %u (micro-sec.)",
1323 iflp->max_delay);
1324 }
1325 vty_out(vty, "\n");
1326 }
1327 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1328 vty_out(vty,
1329 " Link Delay Variation %u (micro-sec.)\n",
1330 iflp->delay_var);
1331 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1332 vty_out(vty, " Link Packet Loss %g (in %%)\n",
1333 iflp->pkt_loss);
1334 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1335 vty_out(vty, " Available Bandwidth %g (Byte/s)\n",
1336 iflp->ava_bw);
1337 if (IS_PARAM_SET(iflp, LP_RES_BW))
1338 vty_out(vty, " Residual Bandwidth %g (Byte/s)\n",
1339 iflp->res_bw);
1340 if (IS_PARAM_SET(iflp, LP_USE_BW))
1341 vty_out(vty, " Utilized Bandwidth %g (Byte/s)\n",
1342 iflp->use_bw);
1343 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1344 vty_out(vty, " Neighbor ASBR IP: %s AS: %u \n",
1345 inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
1346 }
1347
2eb27eec
DL
1348 hook_call(zebra_if_extra_info, vty, ifp);
1349
d62a17ae 1350 if (listhead(ifp->nbr_connected))
1351 vty_out(vty, " Neighbor address(s):\n");
1352 for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected))
1353 nbr_connected_dump_vty(vty, nbr_connected);
718e3744 1354
1355#ifdef HAVE_PROC_NET_DEV
d62a17ae 1356 /* Statistics print out using proc file system. */
1357 vty_out(vty,
1358 " %lu input packets (%lu multicast), %lu bytes, "
1359 "%lu dropped\n",
1360 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1361 ifp->stats.rx_bytes, ifp->stats.rx_dropped);
1362
1363 vty_out(vty,
1364 " %lu input errors, %lu length, %lu overrun,"
1365 " %lu CRC, %lu frame\n",
1366 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1367 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1368 ifp->stats.rx_frame_errors);
1369
1370 vty_out(vty, " %lu fifo, %lu missed\n", ifp->stats.rx_fifo_errors,
1371 ifp->stats.rx_missed_errors);
1372
1373 vty_out(vty, " %lu output packets, %lu bytes, %lu dropped\n",
1374 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1375 ifp->stats.tx_dropped);
1376
1377 vty_out(vty,
1378 " %lu output errors, %lu aborted, %lu carrier,"
1379 " %lu fifo, %lu heartbeat\n",
1380 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1381 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1382 ifp->stats.tx_heartbeat_errors);
1383
1384 vty_out(vty, " %lu window, %lu collisions\n",
1385 ifp->stats.tx_window_errors, ifp->stats.collisions);
718e3744 1386#endif /* HAVE_PROC_NET_DEV */
1387
1388#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1389#if defined(__bsdi__) || defined(__NetBSD__)
1390 /* Statistics print out using sysctl (). */
1391 vty_out(vty,
1392 " input packets %llu, bytes %llu, dropped %llu,"
1393 " multicast packets %llu\n",
1394 (unsigned long long)ifp->stats.ifi_ipackets,
1395 (unsigned long long)ifp->stats.ifi_ibytes,
1396 (unsigned long long)ifp->stats.ifi_iqdrops,
1397 (unsigned long long)ifp->stats.ifi_imcasts);
1398
1399 vty_out(vty, " input errors %llu\n",
1400 (unsigned long long)ifp->stats.ifi_ierrors);
1401
1402 vty_out(vty,
1403 " output packets %llu, bytes %llu,"
1404 " multicast packets %llu\n",
1405 (unsigned long long)ifp->stats.ifi_opackets,
1406 (unsigned long long)ifp->stats.ifi_obytes,
1407 (unsigned long long)ifp->stats.ifi_omcasts);
1408
1409 vty_out(vty, " output errors %llu\n",
1410 (unsigned long long)ifp->stats.ifi_oerrors);
1411
1412 vty_out(vty, " collisions %llu\n",
1413 (unsigned long long)ifp->stats.ifi_collisions);
718e3744 1414#else
d62a17ae 1415 /* Statistics print out using sysctl (). */
1416 vty_out(vty,
1417 " input packets %lu, bytes %lu, dropped %lu,"
1418 " multicast packets %lu\n",
1419 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1420 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts);
718e3744 1421
d62a17ae 1422 vty_out(vty, " input errors %lu\n", ifp->stats.ifi_ierrors);
718e3744 1423
d62a17ae 1424 vty_out(vty,
1425 " output packets %lu, bytes %lu, multicast packets %lu\n",
1426 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1427 ifp->stats.ifi_omcasts);
718e3744 1428
d62a17ae 1429 vty_out(vty, " output errors %lu\n", ifp->stats.ifi_oerrors);
718e3744 1430
d62a17ae 1431 vty_out(vty, " collisions %lu\n", ifp->stats.ifi_collisions);
718e3744 1432#endif /* __bsdi__ || __NetBSD__ */
1433#endif /* HAVE_NET_RT_IFLIST */
1434}
1435
d62a17ae 1436static void interface_update_stats(void)
78860b9f
DS
1437{
1438#ifdef HAVE_PROC_NET_DEV
d62a17ae 1439 /* If system has interface statistics via proc file system, update
1440 statistics. */
1441 ifstat_update_proc();
78860b9f
DS
1442#endif /* HAVE_PROC_NET_DEV */
1443#ifdef HAVE_NET_RT_IFLIST
d62a17ae 1444 ifstat_update_sysctl();
78860b9f
DS
1445#endif /* HAVE_NET_RT_IFLIST */
1446}
1447
d62a17ae 1448struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};
718e3744 1449
8b87bdf4 1450/* Show all interfaces to vty. */
8b3f0677
DW
1451DEFUN (show_interface,
1452 show_interface_cmd,
b62ecea5 1453 "show interface [vrf NAME]",
8b87bdf4 1454 SHOW_STR
b62ecea5
QY
1455 "Interface status and configuration\n"
1456 VRF_CMD_HELP_STR)
8b87bdf4 1457{
f4e14fdb 1458 struct vrf *vrf;
d62a17ae 1459 struct interface *ifp;
1460 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1461
d62a17ae 1462 interface_update_stats();
8b87bdf4 1463
d62a17ae 1464 if (argc > 2)
ec1db588 1465 VRF_GET_ID(vrf_id, argv[3]->arg, false);
8b87bdf4 1466
d62a17ae 1467 /* All interface print. */
f4e14fdb 1468 vrf = vrf_lookup_by_id(vrf_id);
451fda4f 1469 FOR_ALL_INTERFACES (vrf, ifp)
d62a17ae 1470 if_dump_vty(vty, ifp);
8b87bdf4 1471
d62a17ae 1472 return CMD_SUCCESS;
8b87bdf4
FL
1473}
1474
8b87bdf4
FL
1475
1476/* Show all interfaces to vty. */
8b3f0677
DW
1477DEFUN (show_interface_vrf_all,
1478 show_interface_vrf_all_cmd,
9ccf14f7 1479 "show interface vrf all",
8b87bdf4
FL
1480 SHOW_STR
1481 "Interface status and configuration\n"
1482 VRF_ALL_CMD_HELP_STR)
718e3744 1483{
d62a17ae 1484 struct vrf *vrf;
d62a17ae 1485 struct interface *ifp;
8b87bdf4 1486
d62a17ae 1487 interface_update_stats();
718e3744 1488
d62a17ae 1489 /* All interface print. */
a2addae8 1490 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
451fda4f 1491 FOR_ALL_INTERFACES (vrf, ifp)
a2addae8 1492 if_dump_vty(vty, ifp);
8b87bdf4 1493
d62a17ae 1494 return CMD_SUCCESS;
8b87bdf4
FL
1495}
1496
1497/* Show specified interface to vty. */
1721646e
DS
1498
1499DEFUN (show_interface_name_vrf,
1500 show_interface_name_vrf_cmd,
9ccf14f7 1501 "show interface IFNAME vrf NAME",
8b87bdf4
FL
1502 SHOW_STR
1503 "Interface status and configuration\n"
1721646e
DS
1504 "Interface name\n"
1505 VRF_CMD_HELP_STR)
8b87bdf4 1506{
d62a17ae 1507 int idx_ifname = 2;
1508 int idx_name = 4;
1509 struct interface *ifp;
0439cb9d 1510 vrf_id_t vrf_id;
8b87bdf4 1511
d62a17ae 1512 interface_update_stats();
8b87bdf4 1513
ec1db588 1514 VRF_GET_ID(vrf_id, argv[idx_name]->arg, false);
8b87bdf4 1515
d62a17ae 1516 /* Specified interface print. */
1517 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
1518 if (ifp == NULL) {
1519 vty_out(vty, "%% Can't find interface %s\n",
1520 argv[idx_ifname]->arg);
1521 return CMD_WARNING;
1522 }
1523 if_dump_vty(vty, ifp);
718e3744 1524
d62a17ae 1525 return CMD_SUCCESS;
718e3744 1526}
1527
8b87bdf4 1528/* Show specified interface to vty. */
8b3f0677
DW
1529DEFUN (show_interface_name_vrf_all,
1530 show_interface_name_vrf_all_cmd,
b62ecea5 1531 "show interface IFNAME [vrf all]",
8b87bdf4
FL
1532 SHOW_STR
1533 "Interface status and configuration\n"
1721646e 1534 "Interface name\n"
8b87bdf4
FL
1535 VRF_ALL_CMD_HELP_STR)
1536{
d62a17ae 1537 int idx_ifname = 2;
1538 struct vrf *vrf;
1539 struct interface *ifp;
1540 int found = 0;
8b87bdf4 1541
d62a17ae 1542 interface_update_stats();
8b87bdf4 1543
d62a17ae 1544 /* All interface print. */
a2addae8 1545 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
d62a17ae 1546 /* Specified interface print. */
1547 ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id);
1548 if (ifp) {
1549 if_dump_vty(vty, ifp);
1550 found++;
1551 }
1552 }
8b87bdf4 1553
d62a17ae 1554 if (!found) {
1555 vty_out(vty, "%% Can't find interface %s\n",
1556 argv[idx_ifname]->arg);
1557 return CMD_WARNING;
1558 }
8b87bdf4 1559
d62a17ae 1560 return CMD_SUCCESS;
8b87bdf4
FL
1561}
1562
1721646e 1563
d62a17ae 1564static void if_show_description(struct vty *vty, vrf_id_t vrf_id)
ed9bb6d5 1565{
f4e14fdb 1566 struct vrf *vrf = vrf_lookup_by_id(vrf_id);
d62a17ae 1567 struct interface *ifp;
ed9bb6d5 1568
d62a17ae 1569 vty_out(vty, "Interface Status Protocol Description\n");
451fda4f 1570 FOR_ALL_INTERFACES (vrf, ifp) {
d62a17ae 1571 int len;
ed9bb6d5 1572
d62a17ae 1573 len = vty_out(vty, "%s", ifp->name);
1574 vty_out(vty, "%*s", (16 - len), " ");
1575
1576 if (if_is_up(ifp)) {
1577 vty_out(vty, "up ");
1578 if (CHECK_FLAG(ifp->status,
1579 ZEBRA_INTERFACE_LINKDETECTION)) {
1580 if (if_is_running(ifp))
1581 vty_out(vty, "up ");
1582 else
1583 vty_out(vty, "down ");
1584 } else {
1585 vty_out(vty, "unknown ");
1586 }
1587 } else {
1588 vty_out(vty, "down down ");
1589 }
ed9bb6d5 1590
d62a17ae 1591 if (ifp->desc)
1592 vty_out(vty, "%s", ifp->desc);
1593 vty_out(vty, "\n");
1594 }
8b87bdf4
FL
1595}
1596
1597DEFUN (show_interface_desc,
1598 show_interface_desc_cmd,
b62ecea5 1599 "show interface description [vrf NAME]",
8b87bdf4
FL
1600 SHOW_STR
1601 "Interface status and configuration\n"
b62ecea5
QY
1602 "Interface description\n"
1603 VRF_CMD_HELP_STR)
8b87bdf4 1604{
d62a17ae 1605 vrf_id_t vrf_id = VRF_DEFAULT;
8b87bdf4 1606
d62a17ae 1607 if (argc > 3)
ec1db588 1608 VRF_GET_ID(vrf_id, argv[4]->arg, false);
8b87bdf4 1609
d62a17ae 1610 if_show_description(vty, vrf_id);
8b87bdf4 1611
d62a17ae 1612 return CMD_SUCCESS;
8b87bdf4
FL
1613}
1614
8b87bdf4
FL
1615
1616DEFUN (show_interface_desc_vrf_all,
1617 show_interface_desc_vrf_all_cmd,
9ccf14f7 1618 "show interface description vrf all",
8b87bdf4
FL
1619 SHOW_STR
1620 "Interface status and configuration\n"
1621 "Interface description\n"
1622 VRF_ALL_CMD_HELP_STR)
1623{
d62a17ae 1624 struct vrf *vrf;
8b87bdf4 1625
a2addae8 1626 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
996c9314 1627 if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name)) {
a2addae8
RW
1628 vty_out(vty, "\n\tVRF %u\n\n", vrf->vrf_id);
1629 if_show_description(vty, vrf->vrf_id);
1630 }
8b87bdf4 1631
d62a17ae 1632 return CMD_SUCCESS;
ed9bb6d5 1633}
1634
718e3744 1635DEFUN (multicast,
1636 multicast_cmd,
1637 "multicast",
1638 "Set multicast flag to interface\n")
1639{
d62a17ae 1640 VTY_DECLVAR_CONTEXT(interface, ifp);
1641 int ret;
1642 struct zebra_if *if_data;
718e3744 1643
d62a17ae 1644 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1645 ret = if_set_flags(ifp, IFF_MULTICAST);
1646 if (ret < 0) {
1647 vty_out(vty, "Can't set multicast flag\n");
1648 return CMD_WARNING_CONFIG_FAILED;
1649 }
1650 if_refresh(ifp);
48b33aaf 1651 }
d62a17ae 1652 if_data = ifp->info;
1653 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
48b33aaf 1654
d62a17ae 1655 return CMD_SUCCESS;
718e3744 1656}
1657
1658DEFUN (no_multicast,
1659 no_multicast_cmd,
1660 "no multicast",
1661 NO_STR
1662 "Unset multicast flag to interface\n")
1663{
d62a17ae 1664 VTY_DECLVAR_CONTEXT(interface, ifp);
1665 int ret;
1666 struct zebra_if *if_data;
718e3744 1667
d62a17ae 1668 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
1669 ret = if_unset_flags(ifp, IFF_MULTICAST);
1670 if (ret < 0) {
1671 vty_out(vty, "Can't unset multicast flag\n");
1672 return CMD_WARNING_CONFIG_FAILED;
1673 }
1674 if_refresh(ifp);
48b33aaf 1675 }
d62a17ae 1676 if_data = ifp->info;
1677 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
718e3744 1678
d62a17ae 1679 return CMD_SUCCESS;
718e3744 1680}
1681
2e3b2e47 1682DEFUN (linkdetect,
1683 linkdetect_cmd,
1684 "link-detect",
1685 "Enable link detection on interface\n")
1686{
d62a17ae 1687 VTY_DECLVAR_CONTEXT(interface, ifp);
1688 int if_was_operative;
2e3b2e47 1689
d62a17ae 1690 if_was_operative = if_is_no_ptm_operative(ifp);
1691 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1692
d62a17ae 1693 /* When linkdetection is enabled, if might come down */
1694 if (!if_is_no_ptm_operative(ifp) && if_was_operative)
1695 if_down(ifp);
2e3b2e47 1696
d62a17ae 1697 /* FIXME: Will defer status change forwarding if interface
1698 does not come down! */
1699
1700 return CMD_SUCCESS;
2e3b2e47 1701}
1702
1703
1704DEFUN (no_linkdetect,
1705 no_linkdetect_cmd,
1706 "no link-detect",
1707 NO_STR
1708 "Disable link detection on interface\n")
1709{
d62a17ae 1710 VTY_DECLVAR_CONTEXT(interface, ifp);
1711 int if_was_operative;
1712
1713 if_was_operative = if_is_no_ptm_operative(ifp);
1714 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
2e3b2e47 1715
d62a17ae 1716 /* Interface may come up after disabling link detection */
1717 if (if_is_operative(ifp) && !if_was_operative)
1718 if_up(ifp);
2e3b2e47 1719
d62a17ae 1720 /* FIXME: see linkdetect_cmd */
2e3b2e47 1721
d62a17ae 1722 return CMD_SUCCESS;
2e3b2e47 1723}
1724
718e3744 1725DEFUN (shutdown_if,
1726 shutdown_if_cmd,
1727 "shutdown",
1728 "Shutdown the selected interface\n")
1729{
d62a17ae 1730 VTY_DECLVAR_CONTEXT(interface, ifp);
1731 int ret;
1732 struct zebra_if *if_data;
718e3744 1733
d62a17ae 1734 if (ifp->ifindex != IFINDEX_INTERNAL) {
1735 ret = if_unset_flags(ifp, IFF_UP);
1736 if (ret < 0) {
1737 vty_out(vty, "Can't shutdown interface\n");
1738 return CMD_WARNING_CONFIG_FAILED;
1739 }
1740 if_refresh(ifp);
1741 }
1742 if_data = ifp->info;
1743 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
718e3744 1744
d62a17ae 1745 return CMD_SUCCESS;
718e3744 1746}
1747
1748DEFUN (no_shutdown_if,
1749 no_shutdown_if_cmd,
1750 "no shutdown",
1751 NO_STR
1752 "Shutdown the selected interface\n")
1753{
d62a17ae 1754 VTY_DECLVAR_CONTEXT(interface, ifp);
1755 int ret;
1756 struct zebra_if *if_data;
718e3744 1757
d62a17ae 1758 if (ifp->ifindex != IFINDEX_INTERNAL) {
1759 ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING);
1760 if (ret < 0) {
1761 vty_out(vty, "Can't up interface\n");
1762 return CMD_WARNING_CONFIG_FAILED;
1763 }
1764 if_refresh(ifp);
bfac8dcd 1765
d62a17ae 1766 /* Some addresses (in particular, IPv6 addresses on Linux) get
1767 * removed when the interface goes down. They need to be
1768 * readded.
1769 */
1770 if_addr_wakeup(ifp);
1771 }
bfac8dcd 1772
d62a17ae 1773 if_data = ifp->info;
1774 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
718e3744 1775
d62a17ae 1776 return CMD_SUCCESS;
718e3744 1777}
1778
1779DEFUN (bandwidth_if,
1780 bandwidth_if_cmd,
6147e2c6 1781 "bandwidth (1-100000)",
718e3744 1782 "Set bandwidth informational parameter\n"
70bd3c43 1783 "Bandwidth in megabits\n")
718e3744 1784{
d62a17ae 1785 int idx_number = 1;
1786 VTY_DECLVAR_CONTEXT(interface, ifp);
1787 unsigned int bandwidth;
1788
1789 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1790
1791 /* bandwidth range is <1-100000> */
1792 if (bandwidth < 1 || bandwidth > 100000) {
1793 vty_out(vty, "Bandwidth is invalid\n");
1794 return CMD_WARNING_CONFIG_FAILED;
1795 }
1796
1797 ifp->bandwidth = bandwidth;
718e3744 1798
d62a17ae 1799 /* force protocols to recalculate routes due to cost change */
1800 if (if_is_operative(ifp))
1801 zebra_interface_up_update(ifp);
718e3744 1802
d62a17ae 1803 return CMD_SUCCESS;
718e3744 1804}
1805
1806DEFUN (no_bandwidth_if,
1807 no_bandwidth_if_cmd,
b62ecea5 1808 "no bandwidth [(1-100000)]",
718e3744 1809 NO_STR
b62ecea5
QY
1810 "Set bandwidth informational parameter\n"
1811 "Bandwidth in megabits\n")
718e3744 1812{
d62a17ae 1813 VTY_DECLVAR_CONTEXT(interface, ifp);
718e3744 1814
d62a17ae 1815 ifp->bandwidth = 0;
718e3744 1816
d62a17ae 1817 /* force protocols to recalculate routes due to cost change */
1818 if (if_is_operative(ifp))
1819 zebra_interface_up_update(ifp);
1820
1821 return CMD_SUCCESS;
718e3744 1822}
1823
6b0655a2 1824
d62a17ae 1825struct cmd_node link_params_node = {
9d303b37 1826 LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,
16f1b9ee
OD
1827};
1828
d62a17ae 1829static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
1830 uint32_t type, uint32_t value)
16f1b9ee 1831{
d62a17ae 1832 /* Update field as needed */
1833 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1834 *field = value;
1835 SET_PARAM(ifp->link_params, type);
16f1b9ee 1836
d62a17ae 1837 /* force protocols to update LINK STATE due to parameters change
1838 */
1839 if (if_is_operative(ifp))
1840 zebra_interface_parameters_update(ifp);
1841 }
16f1b9ee 1842}
d62a17ae 1843static void link_param_cmd_set_float(struct interface *ifp, float *field,
1844 uint32_t type, float value)
16f1b9ee
OD
1845{
1846
d62a17ae 1847 /* Update field as needed */
1848 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
1849 *field = value;
1850 SET_PARAM(ifp->link_params, type);
16f1b9ee 1851
d62a17ae 1852 /* force protocols to update LINK STATE due to parameters change
1853 */
1854 if (if_is_operative(ifp))
1855 zebra_interface_parameters_update(ifp);
1856 }
16f1b9ee
OD
1857}
1858
d62a17ae 1859static void link_param_cmd_unset(struct interface *ifp, uint32_t type)
16f1b9ee 1860{
d62a17ae 1861 if (ifp->link_params == NULL)
1862 return;
16f1b9ee 1863
d62a17ae 1864 /* Unset field */
1865 UNSET_PARAM(ifp->link_params, type);
16f1b9ee 1866
d62a17ae 1867 /* force protocols to update LINK STATE due to parameters change */
1868 if (if_is_operative(ifp))
1869 zebra_interface_parameters_update(ifp);
16f1b9ee
OD
1870}
1871
505e5056 1872DEFUN_NOSH (link_params,
16f1b9ee
OD
1873 link_params_cmd,
1874 "link-params",
1875 LINK_PARAMS_STR)
1876{
d62a17ae 1877 /* vty->qobj_index stays the same @ interface pointer */
1878 vty->node = LINK_PARAMS_NODE;
16f1b9ee 1879
d62a17ae 1880 return CMD_SUCCESS;
16f1b9ee
OD
1881}
1882
505e5056 1883DEFUN_NOSH (exit_link_params,
03f99d9a
DS
1884 exit_link_params_cmd,
1885 "exit-link-params",
1886 "Exit from Link Params configuration mode\n")
1887{
d62a17ae 1888 if (vty->node == LINK_PARAMS_NODE)
1889 vty->node = INTERFACE_NODE;
1890 return CMD_SUCCESS;
03f99d9a
DS
1891}
1892
16f1b9ee
OD
1893/* Specific Traffic Engineering parameters commands */
1894DEFUN (link_params_enable,
1895 link_params_enable_cmd,
1896 "enable",
1897 "Activate link parameters on this interface\n")
1898{
d62a17ae 1899 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1900
d62a17ae 1901 /* This command could be issue at startup, when activate MPLS TE */
1902 /* on a new interface or after a ON / OFF / ON toggle */
1903 /* In all case, TE parameters are reset to their default factory */
1904 if (IS_ZEBRA_DEBUG_EVENT)
1905 zlog_debug(
1906 "Link-params: enable TE link parameters on interface %s",
1907 ifp->name);
16f1b9ee 1908
d62a17ae 1909 if (!if_link_params_get(ifp)) {
1910 if (IS_ZEBRA_DEBUG_EVENT)
1911 zlog_debug(
1912 "Link-params: failed to init TE link parameters %s",
1913 ifp->name);
16f1b9ee 1914
d62a17ae 1915 return CMD_WARNING_CONFIG_FAILED;
1916 }
16f1b9ee 1917
d62a17ae 1918 /* force protocols to update LINK STATE due to parameters change */
1919 if (if_is_operative(ifp))
1920 zebra_interface_parameters_update(ifp);
16f1b9ee 1921
d62a17ae 1922 return CMD_SUCCESS;
16f1b9ee
OD
1923}
1924
1925DEFUN (no_link_params_enable,
1926 no_link_params_enable_cmd,
1927 "no enable",
1928 NO_STR
1929 "Disable link parameters on this interface\n")
1930{
d62a17ae 1931 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1932
d62a17ae 1933 zlog_debug("MPLS-TE: disable TE link parameters on interface %s",
1934 ifp->name);
16f1b9ee 1935
d62a17ae 1936 if_link_params_free(ifp);
16f1b9ee 1937
d62a17ae 1938 /* force protocols to update LINK STATE due to parameters change */
1939 if (if_is_operative(ifp))
1940 zebra_interface_parameters_update(ifp);
16f1b9ee 1941
d62a17ae 1942 return CMD_SUCCESS;
16f1b9ee
OD
1943}
1944
1945/* STANDARD TE metrics */
1946DEFUN (link_params_metric,
1947 link_params_metric_cmd,
6147e2c6 1948 "metric (0-4294967295)",
16f1b9ee
OD
1949 "Link metric for MPLS-TE purpose\n"
1950 "Metric value in decimal\n")
1951{
d62a17ae 1952 int idx_number = 1;
1953 VTY_DECLVAR_CONTEXT(interface, ifp);
1954 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 1955 uint32_t metric;
16f1b9ee 1956
d62a17ae 1957 metric = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 1958
d62a17ae 1959 /* Update TE metric if needed */
1960 link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
16f1b9ee 1961
d62a17ae 1962 return CMD_SUCCESS;
16f1b9ee
OD
1963}
1964
1965DEFUN (no_link_params_metric,
1966 no_link_params_metric_cmd,
1967 "no metric",
1968 NO_STR
3ddccf18 1969 "Disable Link Metric on this interface\n")
16f1b9ee 1970{
d62a17ae 1971 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 1972
d62a17ae 1973 /* Unset TE Metric */
1974 link_param_cmd_unset(ifp, LP_TE_METRIC);
16f1b9ee 1975
d62a17ae 1976 return CMD_SUCCESS;
16f1b9ee
OD
1977}
1978
1979DEFUN (link_params_maxbw,
1980 link_params_maxbw_cmd,
1981 "max-bw BANDWIDTH",
1982 "Maximum bandwidth that can be used\n"
1983 "Bytes/second (IEEE floating point format)\n")
1984{
d62a17ae 1985 int idx_bandwidth = 1;
1986 VTY_DECLVAR_CONTEXT(interface, ifp);
1987 struct if_link_params *iflp = if_link_params_get(ifp);
1988
1989 float bw;
1990
1991 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
1992 vty_out(vty, "link_params_maxbw: fscanf: %s\n",
1993 safe_strerror(errno));
1994 return CMD_WARNING_CONFIG_FAILED;
1995 }
1996
1997 /* Check that Maximum bandwidth is not lower than other bandwidth
1998 * parameters */
1999 if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
2000 || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
2001 || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
2002 || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
2003 || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
2004 || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
2005 vty_out(vty,
2006 "Maximum Bandwidth could not be lower than others bandwidth\n");
2007 return CMD_WARNING_CONFIG_FAILED;
2008 }
2009
2010 /* Update Maximum Bandwidth if needed */
2011 link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
2012
2013 return CMD_SUCCESS;
16f1b9ee
OD
2014}
2015
2016DEFUN (link_params_max_rsv_bw,
2017 link_params_max_rsv_bw_cmd,
2018 "max-rsv-bw BANDWIDTH",
2019 "Maximum bandwidth that may be reserved\n"
2020 "Bytes/second (IEEE floating point format)\n")
2021{
d62a17ae 2022 int idx_bandwidth = 1;
2023 VTY_DECLVAR_CONTEXT(interface, ifp);
2024 struct if_link_params *iflp = if_link_params_get(ifp);
2025 float bw;
16f1b9ee 2026
d62a17ae 2027 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2028 vty_out(vty, "link_params_max_rsv_bw: fscanf: %s\n",
2029 safe_strerror(errno));
2030 return CMD_WARNING_CONFIG_FAILED;
2031 }
16f1b9ee 2032
d62a17ae 2033 /* Check that bandwidth is not greater than maximum bandwidth parameter
2034 */
2035 if (bw > iflp->max_bw) {
2036 vty_out(vty,
2037 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2038 iflp->max_bw);
2039 return CMD_WARNING_CONFIG_FAILED;
2040 }
16f1b9ee 2041
d62a17ae 2042 /* Update Maximum Reservable Bandwidth if needed */
2043 link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
16f1b9ee 2044
d62a17ae 2045 return CMD_SUCCESS;
16f1b9ee
OD
2046}
2047
2048DEFUN (link_params_unrsv_bw,
2049 link_params_unrsv_bw_cmd,
6147e2c6 2050 "unrsv-bw (0-7) BANDWIDTH",
16f1b9ee
OD
2051 "Unreserved bandwidth at each priority level\n"
2052 "Priority\n"
2053 "Bytes/second (IEEE floating point format)\n")
2054{
d62a17ae 2055 int idx_number = 1;
2056 int idx_bandwidth = 2;
2057 VTY_DECLVAR_CONTEXT(interface, ifp);
2058 struct if_link_params *iflp = if_link_params_get(ifp);
2059 int priority;
2060 float bw;
2061
2062 /* We don't have to consider about range check here. */
2063 if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) {
2064 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2065 safe_strerror(errno));
2066 return CMD_WARNING_CONFIG_FAILED;
2067 }
2068
2069 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2070 vty_out(vty, "link_params_unrsv_bw: fscanf: %s\n",
2071 safe_strerror(errno));
2072 return CMD_WARNING_CONFIG_FAILED;
2073 }
2074
2075 /* Check that bandwidth is not greater than maximum bandwidth parameter
2076 */
2077 if (bw > iflp->max_bw) {
2078 vty_out(vty,
2079 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2080 iflp->max_bw);
2081 return CMD_WARNING_CONFIG_FAILED;
2082 }
2083
2084 /* Update Unreserved Bandwidth if needed */
2085 link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
2086 bw);
2087
2088 return CMD_SUCCESS;
16f1b9ee
OD
2089}
2090
2091DEFUN (link_params_admin_grp,
2092 link_params_admin_grp_cmd,
2093 "admin-grp BITPATTERN",
2094 "Administrative group membership\n"
2095 "32-bit Hexadecimal value (e.g. 0xa1)\n")
2096{
d62a17ae 2097 int idx_bitpattern = 1;
2098 VTY_DECLVAR_CONTEXT(interface, ifp);
2099 struct if_link_params *iflp = if_link_params_get(ifp);
2100 unsigned long value;
16f1b9ee 2101
d62a17ae 2102 if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) {
2103 vty_out(vty, "link_params_admin_grp: fscanf: %s\n",
2104 safe_strerror(errno));
2105 return CMD_WARNING_CONFIG_FAILED;
2106 }
16f1b9ee 2107
d62a17ae 2108 /* Update Administrative Group if needed */
2109 link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
16f1b9ee 2110
d62a17ae 2111 return CMD_SUCCESS;
16f1b9ee
OD
2112}
2113
2114DEFUN (no_link_params_admin_grp,
2115 no_link_params_admin_grp_cmd,
2116 "no admin-grp",
2117 NO_STR
3ddccf18 2118 "Disable Administrative group membership on this interface\n")
16f1b9ee 2119{
d62a17ae 2120 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2121
d62a17ae 2122 /* Unset Admin Group */
2123 link_param_cmd_unset(ifp, LP_ADM_GRP);
16f1b9ee 2124
d62a17ae 2125 return CMD_SUCCESS;
16f1b9ee
OD
2126}
2127
2128/* RFC5392 & RFC5316: INTER-AS */
2129DEFUN (link_params_inter_as,
2130 link_params_inter_as_cmd,
6147e2c6 2131 "neighbor A.B.C.D as (1-4294967295)",
16f1b9ee
OD
2132 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
2133 "Remote IP address in dot decimal A.B.C.D\n"
2134 "Remote AS number\n"
2135 "AS number in the range <1-4294967295>\n")
2136{
d62a17ae 2137 int idx_ipv4 = 1;
2138 int idx_number = 3;
16f1b9ee 2139
d62a17ae 2140 VTY_DECLVAR_CONTEXT(interface, ifp);
2141 struct if_link_params *iflp = if_link_params_get(ifp);
2142 struct in_addr addr;
d7c0a89a 2143 uint32_t as;
16f1b9ee 2144
d62a17ae 2145 if (!inet_aton(argv[idx_ipv4]->arg, &addr)) {
2146 vty_out(vty, "Please specify Router-Addr by A.B.C.D\n");
2147 return CMD_WARNING_CONFIG_FAILED;
2148 }
16f1b9ee 2149
d62a17ae 2150 as = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2151
d62a17ae 2152 /* Update Remote IP and Remote AS fields if needed */
2153 if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as
2154 || iflp->rmt_ip.s_addr != addr.s_addr) {
16f1b9ee 2155
d62a17ae 2156 iflp->rmt_as = as;
2157 iflp->rmt_ip.s_addr = addr.s_addr;
2158 SET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2159
d62a17ae 2160 /* force protocols to update LINK STATE due to parameters change
2161 */
2162 if (if_is_operative(ifp))
2163 zebra_interface_parameters_update(ifp);
2164 }
2165 return CMD_SUCCESS;
16f1b9ee
OD
2166}
2167
2168DEFUN (no_link_params_inter_as,
2169 no_link_params_inter_as_cmd,
2170 "no neighbor",
2171 NO_STR
2172 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2173{
d62a17ae 2174 VTY_DECLVAR_CONTEXT(interface, ifp);
2175 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2176
d62a17ae 2177 /* Reset Remote IP and AS neighbor */
2178 iflp->rmt_as = 0;
2179 iflp->rmt_ip.s_addr = 0;
2180 UNSET_PARAM(iflp, LP_RMT_AS);
16f1b9ee 2181
d62a17ae 2182 /* force protocols to update LINK STATE due to parameters change */
2183 if (if_is_operative(ifp))
2184 zebra_interface_parameters_update(ifp);
16f1b9ee 2185
d62a17ae 2186 return CMD_SUCCESS;
16f1b9ee
OD
2187}
2188
d62a17ae 2189/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions &
2190 * draft-ietf-isis-metric-extensions-07.txt */
16f1b9ee
OD
2191DEFUN (link_params_delay,
2192 link_params_delay_cmd,
b62ecea5 2193 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
16f1b9ee 2194 "Unidirectional Average Link Delay\n"
b62ecea5
QY
2195 "Average delay in micro-second as decimal (0...16777215)\n"
2196 "Minimum delay\n"
2197 "Minimum delay in micro-second as decimal (0...16777215)\n"
2198 "Maximum delay\n"
2199 "Maximum delay in micro-second as decimal (0...16777215)\n")
16f1b9ee 2200{
d62a17ae 2201 /* Get and Check new delay values */
d7c0a89a 2202 uint32_t delay = 0, low = 0, high = 0;
d62a17ae 2203 delay = strtoul(argv[1]->arg, NULL, 10);
2204 if (argc == 6) {
2205 low = strtoul(argv[3]->arg, NULL, 10);
2206 high = strtoul(argv[5]->arg, NULL, 10);
2207 }
2208
2209 VTY_DECLVAR_CONTEXT(interface, ifp);
2210 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2211 uint8_t update = 0;
d62a17ae 2212
2213 if (argc == 2) {
2214 /* Check new delay value against old Min and Max delays if set
2215 */
2216 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2217 && (delay <= iflp->min_delay || delay >= iflp->max_delay)) {
2218 vty_out(vty,
2219 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2220 iflp->min_delay, iflp->max_delay);
2221 return CMD_WARNING_CONFIG_FAILED;
2222 }
2223 /* Update delay if value is not set or change */
2224 if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
2225 iflp->av_delay = delay;
2226 SET_PARAM(iflp, LP_DELAY);
2227 update = 1;
2228 }
2229 /* Unset Min and Max delays if already set */
2230 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2231 iflp->min_delay = 0;
2232 iflp->max_delay = 0;
2233 UNSET_PARAM(iflp, LP_MM_DELAY);
2234 update = 1;
2235 }
2236 } else {
2237 /* Check new delays value coherency */
2238 if (delay <= low || delay >= high) {
2239 vty_out(vty,
2240 "Average delay should be comprise between Min (%d) and Max (%d) delay\n",
2241 low, high);
2242 return CMD_WARNING_CONFIG_FAILED;
2243 }
2244 /* Update Delays if needed */
2245 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2246 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2247 || iflp->av_delay != delay || iflp->min_delay != low
2248 || iflp->max_delay != high) {
2249 iflp->av_delay = delay;
2250 SET_PARAM(iflp, LP_DELAY);
2251 iflp->min_delay = low;
2252 iflp->max_delay = high;
2253 SET_PARAM(iflp, LP_MM_DELAY);
2254 update = 1;
2255 }
2256 }
2257
2258 /* force protocols to update LINK STATE due to parameters change */
2259 if (update == 1 && if_is_operative(ifp))
2260 zebra_interface_parameters_update(ifp);
2261
2262 return CMD_SUCCESS;
16f1b9ee
OD
2263}
2264
16f1b9ee
OD
2265DEFUN (no_link_params_delay,
2266 no_link_params_delay_cmd,
2267 "no delay",
2268 NO_STR
3ddccf18 2269 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
16f1b9ee 2270{
d62a17ae 2271 VTY_DECLVAR_CONTEXT(interface, ifp);
2272 struct if_link_params *iflp = if_link_params_get(ifp);
16f1b9ee 2273
d62a17ae 2274 /* Unset Delays */
2275 iflp->av_delay = 0;
2276 UNSET_PARAM(iflp, LP_DELAY);
2277 iflp->min_delay = 0;
2278 iflp->max_delay = 0;
2279 UNSET_PARAM(iflp, LP_MM_DELAY);
16f1b9ee 2280
d62a17ae 2281 /* force protocols to update LINK STATE due to parameters change */
2282 if (if_is_operative(ifp))
2283 zebra_interface_parameters_update(ifp);
16f1b9ee 2284
d62a17ae 2285 return CMD_SUCCESS;
16f1b9ee
OD
2286}
2287
2288DEFUN (link_params_delay_var,
2289 link_params_delay_var_cmd,
6147e2c6 2290 "delay-variation (0-16777215)",
16f1b9ee
OD
2291 "Unidirectional Link Delay Variation\n"
2292 "delay variation in micro-second as decimal (0...16777215)\n")
2293{
d62a17ae 2294 int idx_number = 1;
2295 VTY_DECLVAR_CONTEXT(interface, ifp);
2296 struct if_link_params *iflp = if_link_params_get(ifp);
d7c0a89a 2297 uint32_t value;
16f1b9ee 2298
d62a17ae 2299 value = strtoul(argv[idx_number]->arg, NULL, 10);
16f1b9ee 2300
d62a17ae 2301 /* Update Delay Variation if needed */
2302 link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
16f1b9ee 2303
d62a17ae 2304 return CMD_SUCCESS;
16f1b9ee
OD
2305}
2306
2307DEFUN (no_link_params_delay_var,
2308 no_link_params_delay_var_cmd,
2309 "no delay-variation",
2310 NO_STR
3ddccf18 2311 "Disable Unidirectional Delay Variation on this interface\n")
16f1b9ee 2312{
d62a17ae 2313 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2314
d62a17ae 2315 /* Unset Delay Variation */
2316 link_param_cmd_unset(ifp, LP_DELAY_VAR);
16f1b9ee 2317
d62a17ae 2318 return CMD_SUCCESS;
16f1b9ee
OD
2319}
2320
2321DEFUN (link_params_pkt_loss,
2322 link_params_pkt_loss_cmd,
2323 "packet-loss PERCENTAGE",
2324 "Unidirectional Link Packet Loss\n"
2325 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2326{
d62a17ae 2327 int idx_percentage = 1;
2328 VTY_DECLVAR_CONTEXT(interface, ifp);
2329 struct if_link_params *iflp = if_link_params_get(ifp);
2330 float fval;
16f1b9ee 2331
d62a17ae 2332 if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) {
2333 vty_out(vty, "link_params_pkt_loss: fscanf: %s\n",
2334 safe_strerror(errno));
2335 return CMD_WARNING_CONFIG_FAILED;
2336 }
16f1b9ee 2337
d62a17ae 2338 if (fval > MAX_PKT_LOSS)
2339 fval = MAX_PKT_LOSS;
16f1b9ee 2340
d62a17ae 2341 /* Update Packet Loss if needed */
2342 link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
16f1b9ee 2343
d62a17ae 2344 return CMD_SUCCESS;
16f1b9ee
OD
2345}
2346
2347DEFUN (no_link_params_pkt_loss,
2348 no_link_params_pkt_loss_cmd,
2349 "no packet-loss",
2350 NO_STR
3ddccf18 2351 "Disable Unidirectional Link Packet Loss on this interface\n")
16f1b9ee 2352{
d62a17ae 2353 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2354
d62a17ae 2355 /* Unset Packet Loss */
2356 link_param_cmd_unset(ifp, LP_PKT_LOSS);
16f1b9ee 2357
d62a17ae 2358 return CMD_SUCCESS;
16f1b9ee
OD
2359}
2360
2361DEFUN (link_params_res_bw,
2362 link_params_res_bw_cmd,
2363 "res-bw BANDWIDTH",
2364 "Unidirectional Residual Bandwidth\n"
2365 "Bytes/second (IEEE floating point format)\n")
2366{
d62a17ae 2367 int idx_bandwidth = 1;
2368 VTY_DECLVAR_CONTEXT(interface, ifp);
2369 struct if_link_params *iflp = if_link_params_get(ifp);
2370 float bw;
16f1b9ee 2371
d62a17ae 2372 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2373 vty_out(vty, "link_params_res_bw: fscanf: %s\n",
2374 safe_strerror(errno));
2375 return CMD_WARNING_CONFIG_FAILED;
2376 }
16f1b9ee 2377
d62a17ae 2378 /* Check that bandwidth is not greater than maximum bandwidth parameter
2379 */
2380 if (bw > iflp->max_bw) {
2381 vty_out(vty,
2382 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2383 iflp->max_bw);
2384 return CMD_WARNING_CONFIG_FAILED;
2385 }
16f1b9ee 2386
d62a17ae 2387 /* Update Residual Bandwidth if needed */
2388 link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
16f1b9ee 2389
d62a17ae 2390 return CMD_SUCCESS;
16f1b9ee
OD
2391}
2392
2393DEFUN (no_link_params_res_bw,
2394 no_link_params_res_bw_cmd,
2395 "no res-bw",
2396 NO_STR
3ddccf18 2397 "Disable Unidirectional Residual Bandwidth on this interface\n")
16f1b9ee 2398{
d62a17ae 2399 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2400
d62a17ae 2401 /* Unset Residual Bandwidth */
2402 link_param_cmd_unset(ifp, LP_RES_BW);
16f1b9ee 2403
d62a17ae 2404 return CMD_SUCCESS;
16f1b9ee
OD
2405}
2406
2407DEFUN (link_params_ava_bw,
2408 link_params_ava_bw_cmd,
2409 "ava-bw BANDWIDTH",
2410 "Unidirectional Available Bandwidth\n"
2411 "Bytes/second (IEEE floating point format)\n")
2412{
d62a17ae 2413 int idx_bandwidth = 1;
2414 VTY_DECLVAR_CONTEXT(interface, ifp);
2415 struct if_link_params *iflp = if_link_params_get(ifp);
2416 float bw;
16f1b9ee 2417
d62a17ae 2418 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2419 vty_out(vty, "link_params_ava_bw: fscanf: %s\n",
2420 safe_strerror(errno));
2421 return CMD_WARNING_CONFIG_FAILED;
2422 }
16f1b9ee 2423
d62a17ae 2424 /* Check that bandwidth is not greater than maximum bandwidth parameter
2425 */
2426 if (bw > iflp->max_bw) {
2427 vty_out(vty,
2428 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2429 iflp->max_bw);
2430 return CMD_WARNING_CONFIG_FAILED;
2431 }
16f1b9ee 2432
d62a17ae 2433 /* Update Residual Bandwidth if needed */
2434 link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
16f1b9ee 2435
d62a17ae 2436 return CMD_SUCCESS;
16f1b9ee
OD
2437}
2438
2439DEFUN (no_link_params_ava_bw,
2440 no_link_params_ava_bw_cmd,
2441 "no ava-bw",
2442 NO_STR
3ddccf18 2443 "Disable Unidirectional Available Bandwidth on this interface\n")
16f1b9ee 2444{
d62a17ae 2445 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2446
d62a17ae 2447 /* Unset Available Bandwidth */
2448 link_param_cmd_unset(ifp, LP_AVA_BW);
16f1b9ee 2449
d62a17ae 2450 return CMD_SUCCESS;
16f1b9ee
OD
2451}
2452
2453DEFUN (link_params_use_bw,
2454 link_params_use_bw_cmd,
2455 "use-bw BANDWIDTH",
2456 "Unidirectional Utilised Bandwidth\n"
2457 "Bytes/second (IEEE floating point format)\n")
2458{
d62a17ae 2459 int idx_bandwidth = 1;
2460 VTY_DECLVAR_CONTEXT(interface, ifp);
2461 struct if_link_params *iflp = if_link_params_get(ifp);
2462 float bw;
16f1b9ee 2463
d62a17ae 2464 if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) {
2465 vty_out(vty, "link_params_use_bw: fscanf: %s\n",
2466 safe_strerror(errno));
2467 return CMD_WARNING_CONFIG_FAILED;
2468 }
16f1b9ee 2469
d62a17ae 2470 /* Check that bandwidth is not greater than maximum bandwidth parameter
2471 */
2472 if (bw > iflp->max_bw) {
2473 vty_out(vty,
2474 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
2475 iflp->max_bw);
2476 return CMD_WARNING_CONFIG_FAILED;
2477 }
16f1b9ee 2478
d62a17ae 2479 /* Update Utilized Bandwidth if needed */
2480 link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
16f1b9ee 2481
d62a17ae 2482 return CMD_SUCCESS;
16f1b9ee
OD
2483}
2484
2485DEFUN (no_link_params_use_bw,
2486 no_link_params_use_bw_cmd,
2487 "no use-bw",
2488 NO_STR
3ddccf18 2489 "Disable Unidirectional Utilised Bandwidth on this interface\n")
16f1b9ee 2490{
d62a17ae 2491 VTY_DECLVAR_CONTEXT(interface, ifp);
16f1b9ee 2492
d62a17ae 2493 /* Unset Utilised Bandwidth */
2494 link_param_cmd_unset(ifp, LP_USE_BW);
16f1b9ee 2495
d62a17ae 2496 return CMD_SUCCESS;
16f1b9ee
OD
2497}
2498
d62a17ae 2499static int ip_address_install(struct vty *vty, struct interface *ifp,
2500 const char *addr_str, const char *peer_str,
2501 const char *label)
718e3744 2502{
d62a17ae 2503 struct zebra_if *if_data;
a07df329 2504 struct prefix_ipv4 lp, pp;
d62a17ae 2505 struct connected *ifc;
2506 struct prefix_ipv4 *p;
2507 int ret;
718e3744 2508
d62a17ae 2509 if_data = ifp->info;
bfac8dcd 2510
a07df329 2511 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2512 if (ret <= 0) {
2513 vty_out(vty, "%% Malformed address \n");
2514 return CMD_WARNING_CONFIG_FAILED;
2515 }
718e3744 2516
a07df329 2517 if (ipv4_martian(&lp.prefix)) {
d62a17ae 2518 vty_out(vty, "%% Invalid address\n");
2519 return CMD_WARNING_CONFIG_FAILED;
2520 }
d914d5ff 2521
a07df329
DL
2522 if (peer_str) {
2523 if (lp.prefixlen != 32) {
2524 vty_out(vty,
2525 "%% Local prefix length for P-t-P address must be /32\n");
2526 return CMD_WARNING_CONFIG_FAILED;
2527 }
2528
2529 ret = str2prefix_ipv4(peer_str, &pp);
2530 if (ret <= 0) {
2531 vty_out(vty, "%% Malformed peer address\n");
2532 return CMD_WARNING_CONFIG_FAILED;
2533 }
2534 }
2535
2536 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2537 if (!ifc) {
2538 ifc = connected_new();
2539 ifc->ifp = ifp;
2540
2541 /* Address. */
2542 p = prefix_ipv4_new();
a07df329 2543 *p = lp;
d62a17ae 2544 ifc->address = (struct prefix *)p;
2545
a07df329
DL
2546 if (peer_str) {
2547 SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2548 p = prefix_ipv4_new();
2549 *p = pp;
2550 ifc->destination = (struct prefix *)p;
2551 } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) {
d62a17ae 2552 p = prefix_ipv4_new();
a07df329 2553 *p = lp;
d62a17ae 2554 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,
2555 p->prefixlen);
2556 ifc->destination = (struct prefix *)p;
2557 }
718e3744 2558
d62a17ae 2559 /* Label. */
2560 if (label)
2561 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
718e3744 2562
d62a17ae 2563 /* Add to linked list. */
2564 listnode_add(ifp->connected, ifc);
718e3744 2565 }
2566
d62a17ae 2567 /* This address is configured from zebra. */
2568 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2569 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2570
2571 /* In case of this route need to install kernel. */
2572 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2573 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2574 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2575 /* Some system need to up the interface to set IP address. */
2576 if (!if_is_up(ifp)) {
2577 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2578 if_refresh(ifp);
2579 }
2580
2581 ret = if_set_prefix(ifp, ifc);
2582 if (ret < 0) {
2583 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2584 safe_strerror(errno));
2585 return CMD_WARNING_CONFIG_FAILED;
2586 }
2587
2588 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2589 /* The address will be advertised to zebra clients when the
2590 * notification
2591 * from the kernel has been received.
2592 * It will also be added to the subnet chain list, then. */
2593 }
2594
2595 return CMD_SUCCESS;
2596}
2597
2598static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
2599 const char *addr_str, const char *peer_str,
2600 const char *label)
2601{
a07df329 2602 struct prefix_ipv4 lp, pp;
d62a17ae 2603 struct connected *ifc;
2604 int ret;
2605
2606 /* Convert to prefix structure. */
a07df329 2607 ret = str2prefix_ipv4(addr_str, &lp);
d62a17ae 2608 if (ret <= 0) {
2609 vty_out(vty, "%% Malformed address \n");
2610 return CMD_WARNING_CONFIG_FAILED;
2611 }
2612
a07df329
DL
2613 if (peer_str) {
2614 if (lp.prefixlen != 32) {
2615 vty_out(vty,
2616 "%% Local prefix length for P-t-P address must be /32\n");
2617 return CMD_WARNING_CONFIG_FAILED;
2618 }
2619
2620 ret = str2prefix_ipv4(peer_str, &pp);
2621 if (ret <= 0) {
2622 vty_out(vty, "%% Malformed peer address\n");
2623 return CMD_WARNING_CONFIG_FAILED;
2624 }
2625 }
2626
d62a17ae 2627 /* Check current interface address. */
a07df329 2628 ifc = connected_check_ptp(ifp, &lp, peer_str ? &pp : NULL);
d62a17ae 2629 if (!ifc) {
2630 vty_out(vty, "%% Can't find address\n");
2631 return CMD_WARNING_CONFIG_FAILED;
2632 }
2633
2634 /* This is not configured address. */
2635 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2636 return CMD_WARNING_CONFIG_FAILED;
2637
2638 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2639
2640 /* This is not real address or interface is not active. */
2641 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2642 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2643 listnode_delete(ifp->connected, ifc);
2644 connected_free(ifc);
2645 return CMD_WARNING_CONFIG_FAILED;
2646 }
2647
2648 /* This is real route. */
2649 ret = if_unset_prefix(ifp, ifc);
2650 if (ret < 0) {
2651 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2652 safe_strerror(errno));
2653 return CMD_WARNING_CONFIG_FAILED;
2654 }
2655 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2656 /* we will receive a kernel notification about this route being removed.
2657 * this will trigger its removal from the connected list. */
2658 return CMD_SUCCESS;
718e3744 2659}
2660
2661DEFUN (ip_address,
2662 ip_address_cmd,
2663 "ip address A.B.C.D/M",
2664 "Interface Internet Protocol config commands\n"
2665 "Set the IP address of an interface\n"
2666 "IP address (e.g. 10.0.0.1/8)\n")
2667{
d62a17ae 2668 int idx_ipv4_prefixlen = 2;
2669 VTY_DECLVAR_CONTEXT(interface, ifp);
2670 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2671 NULL);
718e3744 2672}
2673
2674DEFUN (no_ip_address,
2675 no_ip_address_cmd,
2676 "no ip address A.B.C.D/M",
2677 NO_STR
2678 "Interface Internet Protocol config commands\n"
2679 "Set the IP address of an interface\n"
efd7904e 2680 "IP Address (e.g. 10.0.0.1/8)\n")
718e3744 2681{
d62a17ae 2682 int idx_ipv4_prefixlen = 3;
2683 VTY_DECLVAR_CONTEXT(interface, ifp);
2684 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2685 NULL, NULL);
718e3744 2686}
2687
60466a63
QY
2688DEFUN(ip_address_peer,
2689 ip_address_peer_cmd,
2690 "ip address A.B.C.D peer A.B.C.D/M",
2691 "Interface Internet Protocol config commands\n"
2692 "Set the IP address of an interface\n"
2693 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2694 "Specify P-t-P address\n"
2695 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2696{
2697 VTY_DECLVAR_CONTEXT(interface, ifp);
2698 return ip_address_install(vty, ifp, argv[2]->arg, argv[4]->arg, NULL);
2699}
2700
60466a63
QY
2701DEFUN(no_ip_address_peer,
2702 no_ip_address_peer_cmd,
2703 "no ip address A.B.C.D peer A.B.C.D/M",
2704 NO_STR
2705 "Interface Internet Protocol config commands\n"
2706 "Set the IP address of an interface\n"
2707 "Local IP (e.g. 10.0.0.1) for P-t-P address\n"
2708 "Specify P-t-P address\n"
2709 "Peer IP address (e.g. 10.0.0.1/8)\n")
a07df329
DL
2710{
2711 VTY_DECLVAR_CONTEXT(interface, ifp);
2712 return ip_address_uninstall(vty, ifp, argv[3]->arg, argv[5]->arg, NULL);
2713}
986aa00f 2714
718e3744 2715#ifdef HAVE_NETLINK
718e3744 2716DEFUN (ip_address_label,
2717 ip_address_label_cmd,
2718 "ip address A.B.C.D/M label LINE",
2719 "Interface Internet Protocol config commands\n"
2720 "Set the IP address of an interface\n"
2721 "IP address (e.g. 10.0.0.1/8)\n"
2722 "Label of this address\n"
2723 "Label\n")
2724{
d62a17ae 2725 int idx_ipv4_prefixlen = 2;
2726 int idx_line = 4;
2727 VTY_DECLVAR_CONTEXT(interface, ifp);
2728 return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL,
2729 argv[idx_line]->arg);
718e3744 2730}
2731
2732DEFUN (no_ip_address_label,
2733 no_ip_address_label_cmd,
2734 "no ip address A.B.C.D/M label LINE",
2735 NO_STR
2736 "Interface Internet Protocol config commands\n"
2737 "Set the IP address of an interface\n"
2738 "IP address (e.g. 10.0.0.1/8)\n"
2739 "Label of this address\n"
2740 "Label\n")
2741{
d62a17ae 2742 int idx_ipv4_prefixlen = 3;
2743 int idx_line = 5;
2744 VTY_DECLVAR_CONTEXT(interface, ifp);
2745 return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg,
2746 NULL, argv[idx_line]->arg);
718e3744 2747}
2748#endif /* HAVE_NETLINK */
2749
d62a17ae 2750static int ipv6_address_install(struct vty *vty, struct interface *ifp,
2751 const char *addr_str, const char *peer_str,
2752 const char *label, int secondary)
2753{
2754 struct zebra_if *if_data;
2755 struct prefix_ipv6 cp;
2756 struct connected *ifc;
2757 struct prefix_ipv6 *p;
2758 int ret;
2759
2760 if_data = ifp->info;
2761
2762 ret = str2prefix_ipv6(addr_str, &cp);
2763 if (ret <= 0) {
2764 vty_out(vty, "%% Malformed address \n");
2765 return CMD_WARNING_CONFIG_FAILED;
718e3744 2766 }
2767
d62a17ae 2768 if (ipv6_martian(&cp.prefix)) {
2769 vty_out(vty, "%% Invalid address\n");
2770 return CMD_WARNING_CONFIG_FAILED;
2771 }
718e3744 2772
d62a17ae 2773 ifc = connected_check(ifp, (struct prefix *)&cp);
2774 if (!ifc) {
2775 ifc = connected_new();
2776 ifc->ifp = ifp;
2777
2778 /* Address. */
2779 p = prefix_ipv6_new();
2780 *p = cp;
2781 ifc->address = (struct prefix *)p;
2782
2783 /* Secondary. */
2784 if (secondary)
2785 SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY);
2786
2787 /* Label. */
2788 if (label)
2789 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
2790
2791 /* Add to linked list. */
2792 listnode_add(ifp->connected, ifc);
718e3744 2793 }
2794
d62a17ae 2795 /* This address is configured from zebra. */
2796 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2797 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2798
2799 /* In case of this route need to install kernel. */
2800 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2801 && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
2802 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
2803 /* Some system need to up the interface to set IP address. */
2804 if (!if_is_up(ifp)) {
2805 if_set_flags(ifp, IFF_UP | IFF_RUNNING);
2806 if_refresh(ifp);
2807 }
2808
2809 ret = if_prefix_add_ipv6(ifp, ifc);
2810
2811 if (ret < 0) {
2812 vty_out(vty, "%% Can't set interface IP address: %s.\n",
2813 safe_strerror(errno));
2814 return CMD_WARNING_CONFIG_FAILED;
2815 }
2816
2817 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2818 /* The address will be advertised to zebra clients when the
2819 * notification
2820 * from the kernel has been received. */
2821 }
718e3744 2822
d62a17ae 2823 return CMD_SUCCESS;
718e3744 2824}
2825
b6120505 2826/* Return true if an ipv6 address is configured on ifp */
d62a17ae 2827int ipv6_address_configured(struct interface *ifp)
2828{
2829 struct connected *connected;
2830 struct listnode *node;
2831
2832 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected))
2833 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
2834 && (connected->address->family == AF_INET6))
2835 return 1;
2836
2837 return 0;
2838}
2839
2840static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp,
2841 const char *addr_str, const char *peer_str,
2842 const char *label, int secondry)
2843{
2844 struct prefix_ipv6 cp;
2845 struct connected *ifc;
2846 int ret;
2847
2848 /* Convert to prefix structure. */
2849 ret = str2prefix_ipv6(addr_str, &cp);
2850 if (ret <= 0) {
2851 vty_out(vty, "%% Malformed address \n");
2852 return CMD_WARNING_CONFIG_FAILED;
2853 }
2854
2855 /* Check current interface address. */
2856 ifc = connected_check(ifp, (struct prefix *)&cp);
2857 if (!ifc) {
2858 vty_out(vty, "%% Can't find address\n");
2859 return CMD_WARNING_CONFIG_FAILED;
2860 }
2861
2862 /* This is not configured address. */
2863 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
2864 return CMD_WARNING_CONFIG_FAILED;
2865
2866 UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
2867
2868 /* This is not real address or interface is not active. */
2869 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
2870 || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
2871 listnode_delete(ifp->connected, ifc);
2872 connected_free(ifc);
2873 return CMD_WARNING_CONFIG_FAILED;
2874 }
2875
2876 /* This is real route. */
2877 ret = if_prefix_delete_ipv6(ifp, ifc);
2878 if (ret < 0) {
2879 vty_out(vty, "%% Can't unset interface IP address: %s.\n",
2880 safe_strerror(errno));
2881 return CMD_WARNING_CONFIG_FAILED;
2882 }
2883
2884 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
2885 /* This information will be propagated to the zclients when the
2886 * kernel notification is received. */
2887 return CMD_SUCCESS;
718e3744 2888}
2889
2890DEFUN (ipv6_address,
2891 ipv6_address_cmd,
2892 "ipv6 address X:X::X:X/M",
e23949c0 2893 "Interface IPv6 config commands\n"
718e3744 2894 "Set the IP address of an interface\n"
2895 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2896{
d62a17ae 2897 int idx_ipv6_prefixlen = 2;
2898 VTY_DECLVAR_CONTEXT(interface, ifp);
2899 return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2900 NULL, NULL, 0);
718e3744 2901}
2902
2903DEFUN (no_ipv6_address,
2904 no_ipv6_address_cmd,
2905 "no ipv6 address X:X::X:X/M",
2906 NO_STR
e23949c0 2907 "Interface IPv6 config commands\n"
718e3744 2908 "Set the IP address of an interface\n"
2909 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2910{
d62a17ae 2911 int idx_ipv6_prefixlen = 3;
2912 VTY_DECLVAR_CONTEXT(interface, ifp);
2913 return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg,
2914 NULL, NULL, 0);
2915}
2916
2917static int link_params_config_write(struct vty *vty, struct interface *ifp)
2918{
2919 int i;
2920
2921 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2922 return -1;
986aa00f 2923
d62a17ae 2924 struct if_link_params *iflp = ifp->link_params;
2925
2926 vty_out(vty, " link-params\n");
2927 vty_out(vty, " enable\n");
2928 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
2929 vty_out(vty, " metric %u\n", iflp->te_metric);
2930 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
2931 vty_out(vty, " max-bw %g\n", iflp->max_bw);
2932 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)
2933 && iflp->max_rsv_bw != iflp->default_bw)
2934 vty_out(vty, " max-rsv-bw %g\n", iflp->max_rsv_bw);
2935 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
2936 for (i = 0; i < 8; i++)
2937 if (iflp->unrsv_bw[i] != iflp->default_bw)
2938 vty_out(vty, " unrsv-bw %d %g\n", i,
2939 iflp->unrsv_bw[i]);
2940 }
2941 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2942 vty_out(vty, " admin-grp 0x%x\n", iflp->admin_grp);
2943 if (IS_PARAM_SET(iflp, LP_DELAY)) {
2944 vty_out(vty, " delay %u", iflp->av_delay);
2945 if (IS_PARAM_SET(iflp, LP_MM_DELAY)) {
2946 vty_out(vty, " min %u", iflp->min_delay);
2947 vty_out(vty, " max %u", iflp->max_delay);
2948 }
2949 vty_out(vty, "\n");
bfac8dcd 2950 }
d62a17ae 2951 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2952 vty_out(vty, " delay-variation %u\n", iflp->delay_var);
2953 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2954 vty_out(vty, " packet-loss %g\n", iflp->pkt_loss);
2955 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2956 vty_out(vty, " ava-bw %g\n", iflp->ava_bw);
2957 if (IS_PARAM_SET(iflp, LP_RES_BW))
2958 vty_out(vty, " res-bw %g\n", iflp->res_bw);
2959 if (IS_PARAM_SET(iflp, LP_USE_BW))
2960 vty_out(vty, " use-bw %g\n", iflp->use_bw);
2961 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2962 vty_out(vty, " neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
2963 iflp->rmt_as);
2964 vty_out(vty, " exit-link-params\n");
2965 return 0;
2966}
2967
2968static int if_config_write(struct vty *vty)
2969{
7fe96307 2970 struct vrf *vrf0;
d62a17ae 2971 struct interface *ifp;
2972
2973 zebra_ptm_write(vty);
2974
7fe96307
A
2975 RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name)
2976 FOR_ALL_INTERFACES (vrf0, ifp) {
a2addae8
RW
2977 struct zebra_if *if_data;
2978 struct listnode *addrnode;
2979 struct connected *ifc;
2980 struct prefix *p;
2981 struct vrf *vrf;
d62a17ae 2982
a2addae8
RW
2983 if_data = ifp->info;
2984 vrf = vrf_lookup_by_id(ifp->vrf_id);
d62a17ae 2985
a2addae8
RW
2986 if (ifp->vrf_id == VRF_DEFAULT)
2987 vty_frame(vty, "interface %s\n", ifp->name);
2988 else
2989 vty_frame(vty, "interface %s vrf %s\n",
2990 ifp->name, vrf->name);
d62a17ae 2991
a2addae8
RW
2992 if (if_data) {
2993 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2994 vty_out(vty, " shutdown\n");
d62a17ae 2995
a2addae8
RW
2996 zebra_ptm_if_write(vty, if_data);
2997 }
bfac8dcd 2998
a2addae8
RW
2999 if (ifp->desc)
3000 vty_out(vty, " description %s\n", ifp->desc);
3001
3002 /* Assign bandwidth here to avoid unnecessary interface
3003 flap
3004 while processing config script */
3005 if (ifp->bandwidth != 0)
3006 vty_out(vty, " bandwidth %u\n", ifp->bandwidth);
3007
3008 if (!CHECK_FLAG(ifp->status,
3009 ZEBRA_INTERFACE_LINKDETECTION))
3010 vty_out(vty, " no link-detect\n");
3011
3012 for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode,
3013 ifc)) {
3014 if (CHECK_FLAG(ifc->conf,
3015 ZEBRA_IFC_CONFIGURED)) {
3016 char buf[INET6_ADDRSTRLEN];
3017 p = ifc->address;
3018 vty_out(vty, " ip%s address %s",
3019 p->family == AF_INET ? ""
3020 : "v6",
a07df329 3021 inet_ntop(p->family,
60466a63
QY
3022 &p->u.prefix, buf,
3023 sizeof(buf)));
a2addae8
RW
3024 if (CONNECTED_PEER(ifc)) {
3025 p = ifc->destination;
3026 vty_out(vty, " peer %s",
3027 inet_ntop(p->family,
3028 &p->u.prefix,
3029 buf,
3030 sizeof(buf)));
3031 }
3032 vty_out(vty, "/%d", p->prefixlen);
718e3744 3033
a2addae8
RW
3034 if (ifc->label)
3035 vty_out(vty, " label %s",
3036 ifc->label);
718e3744 3037
a2addae8
RW
3038 vty_out(vty, "\n");
3039 }
d62a17ae 3040 }
718e3744 3041
a2addae8
RW
3042 if (if_data) {
3043 if (if_data->multicast
3044 != IF_ZEBRA_MULTICAST_UNSPEC)
3045 vty_out(vty, " %smulticast\n",
3046 if_data->multicast
3047 == IF_ZEBRA_MULTICAST_ON
3048 ? ""
3049 : "no ");
3050 }
718e3744 3051
a2addae8 3052 hook_call(zebra_if_config_wr, vty, ifp);
ca776988 3053
a2addae8 3054 link_params_config_write(vty, ifp);
16f1b9ee 3055
a2addae8
RW
3056 vty_endframe(vty, "!\n");
3057 }
d62a17ae 3058 return 0;
718e3744 3059}
3060
3061/* Allocate and initialize interface vector. */
d62a17ae 3062void zebra_if_init(void)
3063{
3064 /* Initialize interface and new hook. */
ce19a04a
DL
3065 hook_register_prio(if_add, 0, if_zebra_new_hook);
3066 hook_register_prio(if_del, 0, if_zebra_delete_hook);
d62a17ae 3067
3068 /* Install configuration write function. */
3069 install_node(&interface_node, if_config_write);
3070 install_node(&link_params_node, NULL);
3071 if_cmd_init();
3072
3073 install_element(VIEW_NODE, &show_interface_cmd);
3074 install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
3075 install_element(VIEW_NODE, &show_interface_name_vrf_cmd);
3076 install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd);
3077
3078 install_element(ENABLE_NODE, &show_interface_desc_cmd);
3079 install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
3080 install_element(INTERFACE_NODE, &multicast_cmd);
3081 install_element(INTERFACE_NODE, &no_multicast_cmd);
3082 install_element(INTERFACE_NODE, &linkdetect_cmd);
3083 install_element(INTERFACE_NODE, &no_linkdetect_cmd);
3084 install_element(INTERFACE_NODE, &shutdown_if_cmd);
3085 install_element(INTERFACE_NODE, &no_shutdown_if_cmd);
3086 install_element(INTERFACE_NODE, &bandwidth_if_cmd);
3087 install_element(INTERFACE_NODE, &no_bandwidth_if_cmd);
3088 install_element(INTERFACE_NODE, &ip_address_cmd);
3089 install_element(INTERFACE_NODE, &no_ip_address_cmd);
a07df329
DL
3090 install_element(INTERFACE_NODE, &ip_address_peer_cmd);
3091 install_element(INTERFACE_NODE, &no_ip_address_peer_cmd);
d62a17ae 3092 install_element(INTERFACE_NODE, &ipv6_address_cmd);
3093 install_element(INTERFACE_NODE, &no_ipv6_address_cmd);
718e3744 3094#ifdef HAVE_NETLINK
d62a17ae 3095 install_element(INTERFACE_NODE, &ip_address_label_cmd);
3096 install_element(INTERFACE_NODE, &no_ip_address_label_cmd);
718e3744 3097#endif /* HAVE_NETLINK */
d62a17ae 3098 install_element(INTERFACE_NODE, &link_params_cmd);
3099 install_default(LINK_PARAMS_NODE);
3100 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
3101 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
3102 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
3103 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
3104 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
3105 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
3106 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
3107 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
3108 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
3109 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
3110 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
3111 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
3112 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
3113 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
3114 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
3115 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
3116 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
3117 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
3118 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
3119 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
3120 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
3121 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
3122 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
3123 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
718e3744 3124}