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