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