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