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