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