]> git.proxmox.com Git - mirror_frr.git/blob - zebra/interface.c
Merge remote-tracking branch 'origin/stable/3.0'
[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 char buf[16] = "169.254.0.1";
778 struct in_addr ipv4_ll;
779 char mac[6];
780
781 inet_pton (AF_INET, buf, &ipv4_ll);
782
783 ipv6_ll_address_to_mac(address, (u_char *)mac);
784 kernel_neigh_update (add, ifp->ifindex, ipv4_ll.s_addr, mac, 6);
785 }
786
787 static void
788 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp)
789 {
790 if (listhead(ifp->nbr_connected))
791 {
792 struct nbr_connected *nbr_connected;
793 struct listnode *node;
794
795 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
796 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
797 &nbr_connected->address->u.prefix6,
798 1);
799 }
800 }
801
802 void
803 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp)
804 {
805 if (listhead(ifp->nbr_connected))
806 {
807 struct nbr_connected *nbr_connected;
808 struct listnode *node;
809
810 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
811 if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp,
812 &nbr_connected->address->u.prefix6,
813 0);
814 }
815 }
816
817 static void
818 if_down_del_nbr_connected (struct interface *ifp)
819 {
820 struct nbr_connected *nbr_connected;
821 struct listnode *node, *nnode;
822
823 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nbr_connected))
824 {
825 listnode_delete (ifp->nbr_connected, nbr_connected);
826 nbr_connected_free (nbr_connected);
827 }
828 }
829
830 /* Interface is up. */
831 void
832 if_up (struct interface *ifp)
833 {
834 struct zebra_if *zif;
835
836 zif = ifp->info;
837 zif->up_count++;
838 quagga_timestamp (2, zif->up_last, sizeof (zif->up_last));
839
840 /* Notify the protocol daemons. */
841 if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
842 zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
843 ifp->name);
844 return;
845 }
846 zebra_interface_up_update (ifp);
847
848 if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
849
850 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
851 if (zif->rtadv.AdvSendAdvertisements &&
852 (zif->rtadv.MaxRtrAdvInterval >= 1000))
853 {
854 zif->rtadv.inFastRexmit = 1;
855 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
856 }
857
858 /* Install connected routes to the kernel. */
859 if_install_connected (ifp);
860
861 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
862 zlog_debug ("%u: IF %s up, scheduling RIB processing",
863 ifp->vrf_id, ifp->name);
864 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
865
866 zebra_vrf_static_route_interface_fixup (ifp);
867 }
868
869 /* Interface goes down. We have to manage different behavior of based
870 OS. */
871 void
872 if_down (struct interface *ifp)
873 {
874 struct zebra_if *zif;
875
876 zif = ifp->info;
877 zif->down_count++;
878 quagga_timestamp (2, zif->down_last, sizeof (zif->down_last));
879
880 /* Notify to the protocol daemons. */
881 zebra_interface_down_update (ifp);
882
883 /* Uninstall connected routes from the kernel. */
884 if_uninstall_connected (ifp);
885
886 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
887 zlog_debug ("%u: IF %s down, scheduling RIB processing",
888 ifp->vrf_id, ifp->name);
889 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
890
891 if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
892
893 /* Delete all neighbor addresses learnt through IPv6 RA */
894 if_down_del_nbr_connected (ifp);
895 }
896
897 void
898 if_refresh (struct interface *ifp)
899 {
900 if_get_flags (ifp);
901 }
902
903
904 /* Output prefix string to vty. */
905 static int
906 prefix_vty_out (struct vty *vty, struct prefix *p)
907 {
908 char str[INET6_ADDRSTRLEN];
909
910 inet_ntop (p->family, &p->u.prefix, str, sizeof (str));
911 vty_out (vty, "%s", str);
912 return strlen (str);
913 }
914
915 /* Dump if address information to vty. */
916 static void
917 connected_dump_vty (struct vty *vty, struct connected *connected)
918 {
919 struct prefix *p;
920
921 /* Print interface address. */
922 p = connected->address;
923 vty_out (vty, " %s ", prefix_family_str (p));
924 prefix_vty_out (vty, p);
925 vty_out (vty, "/%d", p->prefixlen);
926
927 /* If there is destination address, print it. */
928 if (connected->destination)
929 {
930 vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast "));
931 prefix_vty_out (vty, connected->destination);
932 }
933
934 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY))
935 vty_out (vty, " secondary");
936
937 if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED))
938 vty_out (vty, " unnumbered");
939
940 if (connected->label)
941 vty_out (vty, " %s", connected->label);
942
943 vty_out (vty, "%s", VTY_NEWLINE);
944 }
945
946 /* Dump interface neighbor address information to vty. */
947 static void
948 nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected)
949 {
950 struct prefix *p;
951
952 /* Print interface address. */
953 p = connected->address;
954 vty_out (vty, " %s ", prefix_family_str (p));
955 prefix_vty_out (vty, p);
956 vty_out (vty, "/%d", p->prefixlen);
957
958 vty_out (vty, "%s", VTY_NEWLINE);
959 }
960
961 #if defined (HAVE_RTADV)
962 /* Dump interface ND information to vty. */
963 static void
964 nd_dump_vty (struct vty *vty, struct interface *ifp)
965 {
966 struct zebra_if *zif;
967 struct rtadvconf *rtadv;
968 int interval;
969
970 zif = (struct zebra_if *) ifp->info;
971 rtadv = &zif->rtadv;
972
973 if (rtadv->AdvSendAdvertisements)
974 {
975 vty_out (vty, " ND advertised reachable time is %d milliseconds%s",
976 rtadv->AdvReachableTime, VTY_NEWLINE);
977 vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s",
978 rtadv->AdvRetransTimer, VTY_NEWLINE);
979 vty_out (vty, " ND router advertisements sent: %d rcvd: %d%s",
980 zif->ra_sent, zif->ra_rcvd, VTY_NEWLINE);
981 interval = rtadv->MaxRtrAdvInterval;
982 if (interval % 1000)
983 vty_out (vty, " ND router advertisements are sent every "
984 "%d milliseconds%s", interval,
985 VTY_NEWLINE);
986 else
987 vty_out (vty, " ND router advertisements are sent every "
988 "%d seconds%s", interval / 1000,
989 VTY_NEWLINE);
990 if (rtadv->AdvDefaultLifetime != -1)
991 vty_out (vty, " ND router advertisements live for %d seconds%s",
992 rtadv->AdvDefaultLifetime, VTY_NEWLINE);
993 else
994 vty_out (vty, " ND router advertisements lifetime tracks ra-interval%s",
995 VTY_NEWLINE);
996 vty_out (vty, " ND router advertisement default router preference is "
997 "%s%s", rtadv_pref_strs[rtadv->DefaultPreference],
998 VTY_NEWLINE);
999 if (rtadv->AdvManagedFlag)
1000 vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s",
1001 VTY_NEWLINE);
1002 else
1003 vty_out (vty, " Hosts use stateless autoconfig for addresses.%s",
1004 VTY_NEWLINE);
1005 if (rtadv->AdvHomeAgentFlag)
1006 {
1007 vty_out (vty, " ND router advertisements with "
1008 "Home Agent flag bit set.%s",
1009 VTY_NEWLINE);
1010 if (rtadv->HomeAgentLifetime != -1)
1011 vty_out (vty, " Home Agent lifetime is %u seconds%s",
1012 rtadv->HomeAgentLifetime, VTY_NEWLINE);
1013 else
1014 vty_out (vty, " Home Agent lifetime tracks ra-lifetime%s",
1015 VTY_NEWLINE);
1016 vty_out (vty, " Home Agent preference is %u%s",
1017 rtadv->HomeAgentPreference, VTY_NEWLINE);
1018 }
1019 if (rtadv->AdvIntervalOption)
1020 vty_out (vty, " ND router advertisements with Adv. Interval option.%s",
1021 VTY_NEWLINE);
1022 }
1023 }
1024 #endif /* HAVE_RTADV */
1025
1026 /* Interface's information print out to vty interface. */
1027 static void
1028 if_dump_vty (struct vty *vty, struct interface *ifp)
1029 {
1030 struct connected *connected;
1031 struct nbr_connected *nbr_connected;
1032 struct listnode *node;
1033 struct route_node *rn;
1034 struct zebra_if *zebra_if;
1035 struct vrf *vrf;
1036
1037 zebra_if = ifp->info;
1038
1039 vty_out (vty, "Interface %s is ", ifp->name);
1040 if (if_is_up(ifp)) {
1041 vty_out (vty, "up, line protocol ");
1042
1043 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
1044 if (if_is_running(ifp))
1045 vty_out (vty, "is up%s", VTY_NEWLINE);
1046 else
1047 vty_out (vty, "is down%s", VTY_NEWLINE);
1048 } else {
1049 vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
1050 }
1051 } else {
1052 vty_out (vty, "down%s", VTY_NEWLINE);
1053 }
1054
1055 vty_out (vty, " Link ups: %5u last: %s%s", zebra_if->up_count,
1056 zebra_if->up_last[0] ? zebra_if->up_last : "(never)", VTY_NEWLINE);
1057 vty_out (vty, " Link downs: %5u last: %s%s", zebra_if->down_count,
1058 zebra_if->down_last[0] ? zebra_if->down_last : "(never)", VTY_NEWLINE);
1059
1060 zebra_ptm_show_status(vty, ifp);
1061
1062 vrf = vrf_lookup_by_id (ifp->vrf_id);
1063 vty_out (vty, " vrf: %s%s", vrf->name, VTY_NEWLINE);
1064
1065 if (ifp->desc)
1066 vty_out (vty, " Description: %s%s", ifp->desc,
1067 VTY_NEWLINE);
1068 if (ifp->ifindex == IFINDEX_INTERNAL)
1069 {
1070 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
1071 return;
1072 }
1073 else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1074 {
1075 vty_out(vty, " index %d inactive interface%s",
1076 ifp->ifindex,
1077 VTY_NEWLINE);
1078 return;
1079 }
1080
1081 vty_out (vty, " index %d metric %d mtu %d speed %u ",
1082 ifp->ifindex, ifp->metric, ifp->mtu, ifp->speed);
1083 if (ifp->mtu6 != ifp->mtu)
1084 vty_out (vty, "mtu6 %d ", ifp->mtu6);
1085 vty_out (vty, "%s flags: %s%s", VTY_NEWLINE,
1086 if_flag_dump (ifp->flags), VTY_NEWLINE);
1087
1088 /* Hardware address. */
1089 vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
1090 if (ifp->hw_addr_len != 0)
1091 {
1092 int i;
1093
1094 vty_out (vty, " HWaddr: ");
1095 for (i = 0; i < ifp->hw_addr_len; i++)
1096 vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
1097 vty_out (vty, "%s", VTY_NEWLINE);
1098 }
1099
1100 /* Bandwidth in Mbps */
1101 if (ifp->bandwidth != 0)
1102 {
1103 vty_out(vty, " bandwidth %u Mbps", ifp->bandwidth);
1104 vty_out(vty, "%s", VTY_NEWLINE);
1105 }
1106
1107 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
1108 {
1109 if (! rn->info)
1110 continue;
1111
1112 for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected))
1113 connected_dump_vty (vty, connected);
1114 }
1115
1116 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
1117 {
1118 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
1119 (connected->address->family == AF_INET6))
1120 connected_dump_vty (vty, connected);
1121 }
1122
1123 if (HAS_LINK_PARAMS(ifp))
1124 {
1125 int i;
1126 struct if_link_params *iflp = ifp->link_params;
1127 vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
1128 if (IS_PARAM_SET(iflp, LP_TE_METRIC))
1129 vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
1130 if (IS_PARAM_SET(iflp, LP_MAX_BW))
1131 vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
1132 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
1133 vty_out(vty, " Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
1134 if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
1135 vty_out(vty, " Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
1136 for (i = 0; i < MAX_CLASS_TYPE; i+=2)
1137 vty_out(vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
1138 i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
1139 }
1140
1141 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
1142 vty_out(vty, " Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
1143 if (IS_PARAM_SET(iflp, LP_DELAY))
1144 {
1145 vty_out(vty, " Link Delay Average: %u (micro-sec.)", iflp->av_delay);
1146 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
1147 {
1148 vty_out(vty, " Min: %u (micro-sec.)", iflp->min_delay);
1149 vty_out(vty, " Max: %u (micro-sec.)", iflp->max_delay);
1150 }
1151 vty_out(vty, "%s", VTY_NEWLINE);
1152 }
1153 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
1154 vty_out(vty, " Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
1155 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
1156 vty_out(vty, " Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
1157 if (IS_PARAM_SET(iflp, LP_AVA_BW))
1158 vty_out(vty, " Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
1159 if (IS_PARAM_SET(iflp, LP_RES_BW))
1160 vty_out(vty, " Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
1161 if (IS_PARAM_SET(iflp, LP_USE_BW))
1162 vty_out(vty, " Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
1163 if (IS_PARAM_SET(iflp, LP_RMT_AS))
1164 vty_out(vty, " Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
1165 }
1166
1167 #ifdef RTADV
1168 nd_dump_vty (vty, ifp);
1169 #endif /* RTADV */
1170 #if defined (HAVE_RTADV)
1171 nd_dump_vty (vty, ifp);
1172 #endif /* HAVE_RTADV */
1173 if (listhead(ifp->nbr_connected))
1174 vty_out (vty, " Neighbor address(s):%s", VTY_NEWLINE);
1175 for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected))
1176 nbr_connected_dump_vty (vty, nbr_connected);
1177
1178 #ifdef HAVE_PROC_NET_DEV
1179 /* Statistics print out using proc file system. */
1180 vty_out (vty, " %lu input packets (%lu multicast), %lu bytes, "
1181 "%lu dropped%s",
1182 ifp->stats.rx_packets, ifp->stats.rx_multicast,
1183 ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE);
1184
1185 vty_out (vty, " %lu input errors, %lu length, %lu overrun,"
1186 " %lu CRC, %lu frame%s",
1187 ifp->stats.rx_errors, ifp->stats.rx_length_errors,
1188 ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors,
1189 ifp->stats.rx_frame_errors, VTY_NEWLINE);
1190
1191 vty_out (vty, " %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors,
1192 ifp->stats.rx_missed_errors, VTY_NEWLINE);
1193
1194 vty_out (vty, " %lu output packets, %lu bytes, %lu dropped%s",
1195 ifp->stats.tx_packets, ifp->stats.tx_bytes,
1196 ifp->stats.tx_dropped, VTY_NEWLINE);
1197
1198 vty_out (vty, " %lu output errors, %lu aborted, %lu carrier,"
1199 " %lu fifo, %lu heartbeat%s",
1200 ifp->stats.tx_errors, ifp->stats.tx_aborted_errors,
1201 ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors,
1202 ifp->stats.tx_heartbeat_errors, VTY_NEWLINE);
1203
1204 vty_out (vty, " %lu window, %lu collisions%s",
1205 ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE);
1206 #endif /* HAVE_PROC_NET_DEV */
1207
1208 #ifdef HAVE_NET_RT_IFLIST
1209 #if defined (__bsdi__) || defined (__NetBSD__)
1210 /* Statistics print out using sysctl (). */
1211 vty_out (vty, " input packets %llu, bytes %llu, dropped %llu,"
1212 " multicast packets %llu%s",
1213 (unsigned long long)ifp->stats.ifi_ipackets,
1214 (unsigned long long)ifp->stats.ifi_ibytes,
1215 (unsigned long long)ifp->stats.ifi_iqdrops,
1216 (unsigned long long)ifp->stats.ifi_imcasts,
1217 VTY_NEWLINE);
1218
1219 vty_out (vty, " input errors %llu%s",
1220 (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE);
1221
1222 vty_out (vty, " output packets %llu, bytes %llu,"
1223 " multicast packets %llu%s",
1224 (unsigned long long)ifp->stats.ifi_opackets,
1225 (unsigned long long)ifp->stats.ifi_obytes,
1226 (unsigned long long)ifp->stats.ifi_omcasts,
1227 VTY_NEWLINE);
1228
1229 vty_out (vty, " output errors %llu%s",
1230 (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE);
1231
1232 vty_out (vty, " collisions %llu%s",
1233 (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);
1234 #else
1235 /* Statistics print out using sysctl (). */
1236 vty_out (vty, " input packets %lu, bytes %lu, dropped %lu,"
1237 " multicast packets %lu%s",
1238 ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes,
1239 ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts,
1240 VTY_NEWLINE);
1241
1242 vty_out (vty, " input errors %lu%s",
1243 ifp->stats.ifi_ierrors, VTY_NEWLINE);
1244
1245 vty_out (vty, " output packets %lu, bytes %lu, multicast packets %lu%s",
1246 ifp->stats.ifi_opackets, ifp->stats.ifi_obytes,
1247 ifp->stats.ifi_omcasts, VTY_NEWLINE);
1248
1249 vty_out (vty, " output errors %lu%s",
1250 ifp->stats.ifi_oerrors, VTY_NEWLINE);
1251
1252 vty_out (vty, " collisions %lu%s",
1253 ifp->stats.ifi_collisions, VTY_NEWLINE);
1254 #endif /* __bsdi__ || __NetBSD__ */
1255 #endif /* HAVE_NET_RT_IFLIST */
1256 }
1257
1258 static void
1259 interface_update_stats (void)
1260 {
1261 #ifdef HAVE_PROC_NET_DEV
1262 /* If system has interface statistics via proc file system, update
1263 statistics. */
1264 ifstat_update_proc ();
1265 #endif /* HAVE_PROC_NET_DEV */
1266 #ifdef HAVE_NET_RT_IFLIST
1267 ifstat_update_sysctl ();
1268 #endif /* HAVE_NET_RT_IFLIST */
1269 }
1270
1271 struct cmd_node interface_node =
1272 {
1273 INTERFACE_NODE,
1274 "%s(config-if)# ",
1275 1
1276 };
1277
1278 /* Show all interfaces to vty. */
1279 DEFUN (show_interface,
1280 show_interface_cmd,
1281 "show interface [vrf NAME]",
1282 SHOW_STR
1283 "Interface status and configuration\n"
1284 VRF_CMD_HELP_STR)
1285 {
1286 struct listnode *node;
1287 struct interface *ifp;
1288 vrf_id_t vrf_id = VRF_DEFAULT;
1289
1290 interface_update_stats ();
1291
1292 if (argc > 2)
1293 VRF_GET_ID (vrf_id, argv[3]->arg);
1294
1295 /* All interface print. */
1296 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1297 if_dump_vty (vty, ifp);
1298
1299 return CMD_SUCCESS;
1300 }
1301
1302
1303 /* Show all interfaces to vty. */
1304 DEFUN (show_interface_vrf_all,
1305 show_interface_vrf_all_cmd,
1306 "show interface vrf all",
1307 SHOW_STR
1308 "Interface status and configuration\n"
1309 VRF_ALL_CMD_HELP_STR)
1310 {
1311 struct vrf *vrf;
1312 struct listnode *node;
1313 struct interface *ifp;
1314
1315 interface_update_stats ();
1316
1317 /* All interface print. */
1318 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1319 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
1320 if_dump_vty (vty, ifp);
1321
1322 return CMD_SUCCESS;
1323 }
1324
1325 /* Show specified interface to vty. */
1326
1327 DEFUN (show_interface_name_vrf,
1328 show_interface_name_vrf_cmd,
1329 "show interface IFNAME vrf NAME",
1330 SHOW_STR
1331 "Interface status and configuration\n"
1332 "Interface name\n"
1333 VRF_CMD_HELP_STR)
1334 {
1335 int idx_ifname = 2;
1336 int idx_name = 4;
1337 struct interface *ifp;
1338 vrf_id_t vrf_id = VRF_DEFAULT;
1339
1340 interface_update_stats ();
1341
1342 VRF_GET_ID (vrf_id, argv[idx_name]->arg);
1343
1344 /* Specified interface print. */
1345 ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf_id);
1346 if (ifp == NULL)
1347 {
1348 vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg,
1349 VTY_NEWLINE);
1350 return CMD_WARNING;
1351 }
1352 if_dump_vty (vty, ifp);
1353
1354 return CMD_SUCCESS;
1355 }
1356
1357 /* Show specified interface to vty. */
1358 DEFUN (show_interface_name_vrf_all,
1359 show_interface_name_vrf_all_cmd,
1360 "show interface IFNAME [vrf all]",
1361 SHOW_STR
1362 "Interface status and configuration\n"
1363 "Interface name\n"
1364 VRF_ALL_CMD_HELP_STR)
1365 {
1366 int idx_ifname = 2;
1367 struct vrf *vrf;
1368 struct interface *ifp;
1369 int found = 0;
1370
1371 interface_update_stats ();
1372
1373 /* All interface print. */
1374 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1375 {
1376 /* Specified interface print. */
1377 ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf->vrf_id);
1378 if (ifp)
1379 {
1380 if_dump_vty (vty, ifp);
1381 found++;
1382 }
1383 }
1384
1385 if (!found)
1386 {
1387 vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg, VTY_NEWLINE);
1388 return CMD_WARNING;
1389 }
1390
1391 return CMD_SUCCESS;
1392 }
1393
1394
1395 static void
1396 if_show_description (struct vty *vty, vrf_id_t vrf_id)
1397 {
1398 struct listnode *node;
1399 struct interface *ifp;
1400
1401 vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
1402 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
1403 {
1404 int len;
1405
1406 len = vty_out (vty, "%s", ifp->name);
1407 vty_out (vty, "%*s", (16 - len), " ");
1408
1409 if (if_is_up(ifp))
1410 {
1411 vty_out (vty, "up ");
1412 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
1413 {
1414 if (if_is_running(ifp))
1415 vty_out (vty, "up ");
1416 else
1417 vty_out (vty, "down ");
1418 }
1419 else
1420 {
1421 vty_out (vty, "unknown ");
1422 }
1423 }
1424 else
1425 {
1426 vty_out (vty, "down down ");
1427 }
1428
1429 if (ifp->desc)
1430 vty_out (vty, "%s", ifp->desc);
1431 vty_out (vty, "%s", VTY_NEWLINE);
1432 }
1433 }
1434
1435 DEFUN (show_interface_desc,
1436 show_interface_desc_cmd,
1437 "show interface description [vrf NAME]",
1438 SHOW_STR
1439 "Interface status and configuration\n"
1440 "Interface description\n"
1441 VRF_CMD_HELP_STR)
1442 {
1443 vrf_id_t vrf_id = VRF_DEFAULT;
1444
1445 if (argc > 3)
1446 VRF_GET_ID (vrf_id, argv[4]->arg);
1447
1448 if_show_description (vty, vrf_id);
1449
1450 return CMD_SUCCESS;
1451 }
1452
1453
1454 DEFUN (show_interface_desc_vrf_all,
1455 show_interface_desc_vrf_all_cmd,
1456 "show interface description vrf all",
1457 SHOW_STR
1458 "Interface status and configuration\n"
1459 "Interface description\n"
1460 VRF_ALL_CMD_HELP_STR)
1461 {
1462 struct vrf *vrf;
1463
1464 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1465 if (!list_isempty (vrf->iflist))
1466 {
1467 vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id,
1468 VTY_NEWLINE, VTY_NEWLINE);
1469 if_show_description (vty, vrf->vrf_id);
1470 }
1471
1472 return CMD_SUCCESS;
1473 }
1474
1475 DEFUN (multicast,
1476 multicast_cmd,
1477 "multicast",
1478 "Set multicast flag to interface\n")
1479 {
1480 VTY_DECLVAR_CONTEXT (interface, ifp);
1481 int ret;
1482 struct zebra_if *if_data;
1483
1484 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1485 {
1486 ret = if_set_flags (ifp, IFF_MULTICAST);
1487 if (ret < 0)
1488 {
1489 vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE);
1490 return CMD_WARNING;
1491 }
1492 if_refresh (ifp);
1493 }
1494 if_data = ifp->info;
1495 if_data->multicast = IF_ZEBRA_MULTICAST_ON;
1496
1497 return CMD_SUCCESS;
1498 }
1499
1500 DEFUN (no_multicast,
1501 no_multicast_cmd,
1502 "no multicast",
1503 NO_STR
1504 "Unset multicast flag to interface\n")
1505 {
1506 VTY_DECLVAR_CONTEXT (interface, ifp);
1507 int ret;
1508 struct zebra_if *if_data;
1509
1510 if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1511 {
1512 ret = if_unset_flags (ifp, IFF_MULTICAST);
1513 if (ret < 0)
1514 {
1515 vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE);
1516 return CMD_WARNING;
1517 }
1518 if_refresh (ifp);
1519 }
1520 if_data = ifp->info;
1521 if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
1522
1523 return CMD_SUCCESS;
1524 }
1525
1526 DEFUN (linkdetect,
1527 linkdetect_cmd,
1528 "link-detect",
1529 "Enable link detection on interface\n")
1530 {
1531 VTY_DECLVAR_CONTEXT (interface, ifp);
1532 int if_was_operative;
1533
1534 if_was_operative = if_is_no_ptm_operative(ifp);
1535 SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1536
1537 /* When linkdetection is enabled, if might come down */
1538 if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp);
1539
1540 /* FIXME: Will defer status change forwarding if interface
1541 does not come down! */
1542
1543 return CMD_SUCCESS;
1544 }
1545
1546
1547 DEFUN (no_linkdetect,
1548 no_linkdetect_cmd,
1549 "no link-detect",
1550 NO_STR
1551 "Disable link detection on interface\n")
1552 {
1553 VTY_DECLVAR_CONTEXT (interface, ifp);
1554 int if_was_operative;
1555
1556 if_was_operative = if_is_no_ptm_operative(ifp);
1557 UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
1558
1559 /* Interface may come up after disabling link detection */
1560 if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
1561
1562 /* FIXME: see linkdetect_cmd */
1563
1564 return CMD_SUCCESS;
1565 }
1566
1567 DEFUN (shutdown_if,
1568 shutdown_if_cmd,
1569 "shutdown",
1570 "Shutdown the selected interface\n")
1571 {
1572 VTY_DECLVAR_CONTEXT (interface, ifp);
1573 int ret;
1574 struct zebra_if *if_data;
1575
1576 if (ifp->ifindex != IFINDEX_INTERNAL)
1577 {
1578 ret = if_unset_flags (ifp, IFF_UP);
1579 if (ret < 0)
1580 {
1581 vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE);
1582 return CMD_WARNING;
1583 }
1584 if_refresh (ifp);
1585 }
1586 if_data = ifp->info;
1587 if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
1588
1589 return CMD_SUCCESS;
1590 }
1591
1592 DEFUN (no_shutdown_if,
1593 no_shutdown_if_cmd,
1594 "no shutdown",
1595 NO_STR
1596 "Shutdown the selected interface\n")
1597 {
1598 VTY_DECLVAR_CONTEXT (interface, ifp);
1599 int ret;
1600 struct zebra_if *if_data;
1601
1602 if (ifp->ifindex != IFINDEX_INTERNAL)
1603 {
1604 ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING);
1605 if (ret < 0)
1606 {
1607 vty_out (vty, "Can't up interface%s", VTY_NEWLINE);
1608 return CMD_WARNING;
1609 }
1610 if_refresh (ifp);
1611
1612 /* Some addresses (in particular, IPv6 addresses on Linux) get
1613 * removed when the interface goes down. They need to be readded.
1614 */
1615 if_addr_wakeup(ifp);
1616 }
1617
1618 if_data = ifp->info;
1619 if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
1620
1621 return CMD_SUCCESS;
1622 }
1623
1624 DEFUN (bandwidth_if,
1625 bandwidth_if_cmd,
1626 "bandwidth (1-100000)",
1627 "Set bandwidth informational parameter\n"
1628 "Bandwidth in megabits\n")
1629 {
1630 int idx_number = 1;
1631 VTY_DECLVAR_CONTEXT (interface, ifp);
1632 unsigned int bandwidth;
1633
1634 bandwidth = strtol(argv[idx_number]->arg, NULL, 10);
1635
1636 /* bandwidth range is <1-100000> */
1637 if (bandwidth < 1 || bandwidth > 100000)
1638 {
1639 vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE);
1640 return CMD_WARNING;
1641 }
1642
1643 ifp->bandwidth = bandwidth;
1644
1645 /* force protocols to recalculate routes due to cost change */
1646 if (if_is_operative (ifp))
1647 zebra_interface_up_update (ifp);
1648
1649 return CMD_SUCCESS;
1650 }
1651
1652 DEFUN (no_bandwidth_if,
1653 no_bandwidth_if_cmd,
1654 "no bandwidth [(1-100000)]",
1655 NO_STR
1656 "Set bandwidth informational parameter\n"
1657 "Bandwidth in megabits\n")
1658 {
1659 VTY_DECLVAR_CONTEXT (interface, ifp);
1660
1661 ifp->bandwidth = 0;
1662
1663 /* force protocols to recalculate routes due to cost change */
1664 if (if_is_operative (ifp))
1665 zebra_interface_up_update (ifp);
1666
1667 return CMD_SUCCESS;
1668 }
1669
1670
1671 struct cmd_node link_params_node =
1672 {
1673 LINK_PARAMS_NODE,
1674 "%s(config-link-params)# ",
1675 1,
1676 };
1677
1678 static void
1679 link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field,
1680 uint32_t type, uint32_t value)
1681 {
1682 /* Update field as needed */
1683 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1684 {
1685 *field = value;
1686 SET_PARAM(ifp->link_params, type);
1687
1688 /* force protocols to update LINK STATE due to parameters change */
1689 if (if_is_operative (ifp))
1690 zebra_interface_parameters_update (ifp);
1691 }
1692 }
1693 static void
1694 link_param_cmd_set_float (struct interface *ifp, float *field,
1695 uint32_t type, float value)
1696 {
1697
1698 /* Update field as needed */
1699 if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
1700 {
1701 *field = value;
1702 SET_PARAM(ifp->link_params, type);
1703
1704 /* force protocols to update LINK STATE due to parameters change */
1705 if (if_is_operative (ifp))
1706 zebra_interface_parameters_update (ifp);
1707 }
1708 }
1709
1710 static void
1711 link_param_cmd_unset (struct interface *ifp, uint32_t type)
1712 {
1713 if (ifp->link_params == NULL)
1714 return;
1715
1716 /* Unset field */
1717 UNSET_PARAM(ifp->link_params, type);
1718
1719 /* force protocols to update LINK STATE due to parameters change */
1720 if (if_is_operative (ifp))
1721 zebra_interface_parameters_update (ifp);
1722 }
1723
1724 DEFUN_NOSH (link_params,
1725 link_params_cmd,
1726 "link-params",
1727 LINK_PARAMS_STR)
1728 {
1729 /* vty->qobj_index stays the same @ interface pointer */
1730 vty->node = LINK_PARAMS_NODE;
1731
1732 return CMD_SUCCESS;
1733 }
1734
1735 DEFUN_NOSH (exit_link_params,
1736 exit_link_params_cmd,
1737 "exit-link-params",
1738 "Exit from Link Params configuration mode\n")
1739 {
1740 if (vty->node == LINK_PARAMS_NODE)
1741 vty->node = INTERFACE_NODE;
1742 return CMD_SUCCESS;
1743 }
1744
1745 /* Specific Traffic Engineering parameters commands */
1746 DEFUN (link_params_enable,
1747 link_params_enable_cmd,
1748 "enable",
1749 "Activate link parameters on this interface\n")
1750 {
1751 VTY_DECLVAR_CONTEXT (interface, ifp);
1752
1753 /* This command could be issue at startup, when activate MPLS TE */
1754 /* on a new interface or after a ON / OFF / ON toggle */
1755 /* In all case, TE parameters are reset to their default factory */
1756 if (IS_ZEBRA_DEBUG_EVENT)
1757 zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
1758
1759 if (!if_link_params_get (ifp))
1760 {
1761 if (IS_ZEBRA_DEBUG_EVENT)
1762 zlog_debug ("Link-params: failed to init TE link parameters %s", ifp->name);
1763
1764 return CMD_WARNING;
1765 }
1766
1767 /* force protocols to update LINK STATE due to parameters change */
1768 if (if_is_operative (ifp))
1769 zebra_interface_parameters_update (ifp);
1770
1771 return CMD_SUCCESS;
1772 }
1773
1774 DEFUN (no_link_params_enable,
1775 no_link_params_enable_cmd,
1776 "no enable",
1777 NO_STR
1778 "Disable link parameters on this interface\n")
1779 {
1780 VTY_DECLVAR_CONTEXT (interface, ifp);
1781
1782 zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
1783
1784 if_link_params_free (ifp);
1785
1786 /* force protocols to update LINK STATE due to parameters change */
1787 if (if_is_operative (ifp))
1788 zebra_interface_parameters_update (ifp);
1789
1790 return CMD_SUCCESS;
1791 }
1792
1793 /* STANDARD TE metrics */
1794 DEFUN (link_params_metric,
1795 link_params_metric_cmd,
1796 "metric (0-4294967295)",
1797 "Link metric for MPLS-TE purpose\n"
1798 "Metric value in decimal\n")
1799 {
1800 int idx_number = 1;
1801 VTY_DECLVAR_CONTEXT (interface, ifp);
1802 struct if_link_params *iflp = if_link_params_get (ifp);
1803 u_int32_t metric;
1804
1805 VTY_GET_ULONG("metric", metric, argv[idx_number]->arg);
1806
1807 /* Update TE metric if needed */
1808 link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE_METRIC, metric);
1809
1810 return CMD_SUCCESS;
1811 }
1812
1813 DEFUN (no_link_params_metric,
1814 no_link_params_metric_cmd,
1815 "no metric",
1816 NO_STR
1817 "Disable Link Metric on this interface\n")
1818 {
1819 VTY_DECLVAR_CONTEXT (interface, ifp);
1820
1821 /* Unset TE Metric */
1822 link_param_cmd_unset(ifp, LP_TE_METRIC);
1823
1824 return CMD_SUCCESS;
1825 }
1826
1827 DEFUN (link_params_maxbw,
1828 link_params_maxbw_cmd,
1829 "max-bw BANDWIDTH",
1830 "Maximum bandwidth that can be used\n"
1831 "Bytes/second (IEEE floating point format)\n")
1832 {
1833 int idx_bandwidth = 1;
1834 VTY_DECLVAR_CONTEXT (interface, ifp);
1835 struct if_link_params *iflp = if_link_params_get (ifp);
1836
1837 float bw;
1838
1839 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
1840 {
1841 vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
1842 VTY_NEWLINE);
1843 return CMD_WARNING;
1844 }
1845
1846 /* Check that Maximum bandwidth is not lower than other bandwidth parameters */
1847 if ((bw <= iflp->max_rsv_bw)
1848 || (bw <= iflp->unrsv_bw[0])
1849 || (bw <= iflp->unrsv_bw[1])
1850 || (bw <= iflp->unrsv_bw[2])
1851 || (bw <= iflp->unrsv_bw[3])
1852 || (bw <= iflp->unrsv_bw[4])
1853 || (bw <= iflp->unrsv_bw[5])
1854 || (bw <= iflp->unrsv_bw[6])
1855 || (bw <= iflp->unrsv_bw[7])
1856 || (bw <= iflp->ava_bw)
1857 || (bw <= iflp->res_bw)
1858 || (bw <= iflp->use_bw))
1859 {
1860 vty_out (vty,
1861 "Maximum Bandwidth could not be lower than others bandwidth%s",
1862 VTY_NEWLINE);
1863 return CMD_WARNING;
1864 }
1865
1866 /* Update Maximum Bandwidth if needed */
1867 link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
1868
1869 return CMD_SUCCESS;
1870 }
1871
1872 DEFUN (link_params_max_rsv_bw,
1873 link_params_max_rsv_bw_cmd,
1874 "max-rsv-bw BANDWIDTH",
1875 "Maximum bandwidth that may be reserved\n"
1876 "Bytes/second (IEEE floating point format)\n")
1877 {
1878 int idx_bandwidth = 1;
1879 VTY_DECLVAR_CONTEXT (interface, ifp);
1880 struct if_link_params *iflp = if_link_params_get (ifp);
1881 float bw;
1882
1883 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
1884 {
1885 vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
1886 VTY_NEWLINE);
1887 return CMD_WARNING;
1888 }
1889
1890 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1891 if (bw > iflp->max_bw)
1892 {
1893 vty_out (vty,
1894 "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1895 iflp->max_bw, VTY_NEWLINE);
1896 return CMD_WARNING;
1897 }
1898
1899 /* Update Maximum Reservable Bandwidth if needed */
1900 link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
1901
1902 return CMD_SUCCESS;
1903 }
1904
1905 DEFUN (link_params_unrsv_bw,
1906 link_params_unrsv_bw_cmd,
1907 "unrsv-bw (0-7) BANDWIDTH",
1908 "Unreserved bandwidth at each priority level\n"
1909 "Priority\n"
1910 "Bytes/second (IEEE floating point format)\n")
1911 {
1912 int idx_number = 1;
1913 int idx_bandwidth = 2;
1914 VTY_DECLVAR_CONTEXT (interface, ifp);
1915 struct if_link_params *iflp = if_link_params_get (ifp);
1916 int priority;
1917 float bw;
1918
1919 /* We don't have to consider about range check here. */
1920 if (sscanf (argv[idx_number]->arg, "%d", &priority) != 1)
1921 {
1922 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1923 VTY_NEWLINE);
1924 return CMD_WARNING;
1925 }
1926
1927 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
1928 {
1929 vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
1930 VTY_NEWLINE);
1931 return CMD_WARNING;
1932 }
1933
1934 /* Check that bandwidth is not greater than maximum bandwidth parameter */
1935 if (bw > iflp->max_bw)
1936 {
1937 vty_out (vty,
1938 "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
1939 iflp->max_bw, VTY_NEWLINE);
1940 return CMD_WARNING;
1941 }
1942
1943 /* Update Unreserved Bandwidth if needed */
1944 link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
1945
1946 return CMD_SUCCESS;
1947 }
1948
1949 DEFUN (link_params_admin_grp,
1950 link_params_admin_grp_cmd,
1951 "admin-grp BITPATTERN",
1952 "Administrative group membership\n"
1953 "32-bit Hexadecimal value (e.g. 0xa1)\n")
1954 {
1955 int idx_bitpattern = 1;
1956 VTY_DECLVAR_CONTEXT (interface, ifp);
1957 struct if_link_params *iflp = if_link_params_get (ifp);
1958 unsigned long value;
1959
1960 if (sscanf (argv[idx_bitpattern]->arg, "0x%lx", &value) != 1)
1961 {
1962 vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
1963 safe_strerror (errno), VTY_NEWLINE);
1964 return CMD_WARNING;
1965 }
1966
1967 /* Update Administrative Group if needed */
1968 link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
1969
1970 return CMD_SUCCESS;
1971 }
1972
1973 DEFUN (no_link_params_admin_grp,
1974 no_link_params_admin_grp_cmd,
1975 "no admin-grp",
1976 NO_STR
1977 "Disable Administrative group membership on this interface\n")
1978 {
1979 VTY_DECLVAR_CONTEXT (interface, ifp);
1980
1981 /* Unset Admin Group */
1982 link_param_cmd_unset(ifp, LP_ADM_GRP);
1983
1984 return CMD_SUCCESS;
1985 }
1986
1987 /* RFC5392 & RFC5316: INTER-AS */
1988 DEFUN (link_params_inter_as,
1989 link_params_inter_as_cmd,
1990 "neighbor A.B.C.D as (1-4294967295)",
1991 "Configure remote ASBR information (Neighbor IP address and AS number)\n"
1992 "Remote IP address in dot decimal A.B.C.D\n"
1993 "Remote AS number\n"
1994 "AS number in the range <1-4294967295>\n")
1995 {
1996 int idx_ipv4 = 1;
1997 int idx_number = 3;
1998
1999 VTY_DECLVAR_CONTEXT (interface, ifp);
2000 struct if_link_params *iflp = if_link_params_get (ifp);
2001 struct in_addr addr;
2002 u_int32_t as;
2003
2004 if (!inet_aton (argv[idx_ipv4]->arg, &addr))
2005 {
2006 vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
2007 return CMD_WARNING;
2008 }
2009
2010 VTY_GET_ULONG("AS number", as, argv[idx_number]->arg);
2011
2012 /* Update Remote IP and Remote AS fields if needed */
2013 if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
2014 || iflp->rmt_as != as
2015 || iflp->rmt_ip.s_addr != addr.s_addr)
2016 {
2017
2018 iflp->rmt_as = as;
2019 iflp->rmt_ip.s_addr = addr.s_addr;
2020 SET_PARAM(iflp, LP_RMT_AS);
2021
2022 /* force protocols to update LINK STATE due to parameters change */
2023 if (if_is_operative (ifp))
2024 zebra_interface_parameters_update (ifp);
2025 }
2026 return CMD_SUCCESS;
2027 }
2028
2029 DEFUN (no_link_params_inter_as,
2030 no_link_params_inter_as_cmd,
2031 "no neighbor",
2032 NO_STR
2033 "Remove Neighbor IP address and AS number for Inter-AS TE\n")
2034 {
2035 VTY_DECLVAR_CONTEXT (interface, ifp);
2036 struct if_link_params *iflp = if_link_params_get (ifp);
2037
2038 /* Reset Remote IP and AS neighbor */
2039 iflp->rmt_as = 0;
2040 iflp->rmt_ip.s_addr = 0;
2041 UNSET_PARAM(iflp, LP_RMT_AS);
2042
2043 /* force protocols to update LINK STATE due to parameters change */
2044 if (if_is_operative (ifp))
2045 zebra_interface_parameters_update (ifp);
2046
2047 return CMD_SUCCESS;
2048 }
2049
2050 /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
2051 DEFUN (link_params_delay,
2052 link_params_delay_cmd,
2053 "delay (0-16777215) [min (0-16777215) max (0-16777215)]",
2054 "Unidirectional Average Link Delay\n"
2055 "Average delay in micro-second as decimal (0...16777215)\n"
2056 "Minimum delay\n"
2057 "Minimum delay in micro-second as decimal (0...16777215)\n"
2058 "Maximum delay\n"
2059 "Maximum delay in micro-second as decimal (0...16777215)\n")
2060 {
2061 /* Get and Check new delay values */
2062 u_int32_t delay = 0, low = 0, high = 0;
2063 VTY_GET_ULONG("delay", delay, argv[1]->arg);
2064 if (argc == 6)
2065 {
2066 VTY_GET_ULONG("minimum delay", low, argv[3]->arg);
2067 VTY_GET_ULONG("maximum delay", high, argv[5]->arg);
2068 }
2069
2070 VTY_DECLVAR_CONTEXT (interface, ifp);
2071 struct if_link_params *iflp = if_link_params_get (ifp);
2072 u_int8_t update = 0;
2073
2074 if (argc == 2)
2075 {
2076 /* Check new delay value against old Min and Max delays if set */
2077 if (IS_PARAM_SET(iflp, LP_MM_DELAY)
2078 && (delay <= iflp->min_delay || delay >= iflp->max_delay))
2079 {
2080 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
2081 iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
2082 return CMD_WARNING;
2083 }
2084 /* Update delay if value is not set or change */
2085 if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
2086 {
2087 iflp->av_delay = delay;
2088 SET_PARAM(iflp, LP_DELAY);
2089 update = 1;
2090 }
2091 /* Unset Min and Max delays if already set */
2092 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2093 {
2094 iflp->min_delay = 0;
2095 iflp->max_delay = 0;
2096 UNSET_PARAM(iflp, LP_MM_DELAY);
2097 update = 1;
2098 }
2099 }
2100 else
2101 {
2102 /* Check new delays value coherency */
2103 if (delay <= low || delay >= high)
2104 {
2105 vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
2106 low, high, VTY_NEWLINE);
2107 return CMD_WARNING;
2108 }
2109 /* Update Delays if needed */
2110 if (IS_PARAM_UNSET(iflp, LP_DELAY)
2111 || IS_PARAM_UNSET(iflp, LP_MM_DELAY)
2112 || iflp->av_delay != delay
2113 || iflp->min_delay != low
2114 || iflp->max_delay != high)
2115 {
2116 iflp->av_delay = delay;
2117 SET_PARAM(iflp, LP_DELAY);
2118 iflp->min_delay = low;
2119 iflp->max_delay = high;
2120 SET_PARAM(iflp, LP_MM_DELAY);
2121 update = 1;
2122 }
2123 }
2124
2125 /* force protocols to update LINK STATE due to parameters change */
2126 if (update == 1 && if_is_operative (ifp))
2127 zebra_interface_parameters_update (ifp);
2128
2129 return CMD_SUCCESS;
2130 }
2131
2132 DEFUN (no_link_params_delay,
2133 no_link_params_delay_cmd,
2134 "no delay",
2135 NO_STR
2136 "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")
2137 {
2138 VTY_DECLVAR_CONTEXT (interface, ifp);
2139 struct if_link_params *iflp = if_link_params_get (ifp);
2140
2141 /* Unset Delays */
2142 iflp->av_delay = 0;
2143 UNSET_PARAM(iflp, LP_DELAY);
2144 iflp->min_delay = 0;
2145 iflp->max_delay = 0;
2146 UNSET_PARAM(iflp, LP_MM_DELAY);
2147
2148 /* force protocols to update LINK STATE due to parameters change */
2149 if (if_is_operative (ifp))
2150 zebra_interface_parameters_update (ifp);
2151
2152 return CMD_SUCCESS;
2153 }
2154
2155 DEFUN (link_params_delay_var,
2156 link_params_delay_var_cmd,
2157 "delay-variation (0-16777215)",
2158 "Unidirectional Link Delay Variation\n"
2159 "delay variation in micro-second as decimal (0...16777215)\n")
2160 {
2161 int idx_number = 1;
2162 VTY_DECLVAR_CONTEXT (interface, ifp);
2163 struct if_link_params *iflp = if_link_params_get (ifp);
2164 u_int32_t value;
2165
2166 VTY_GET_ULONG("delay variation", value, argv[idx_number]->arg);
2167
2168 /* Update Delay Variation if needed */
2169 link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
2170
2171 return CMD_SUCCESS;
2172 }
2173
2174 DEFUN (no_link_params_delay_var,
2175 no_link_params_delay_var_cmd,
2176 "no delay-variation",
2177 NO_STR
2178 "Disable Unidirectional Delay Variation on this interface\n")
2179 {
2180 VTY_DECLVAR_CONTEXT (interface, ifp);
2181
2182 /* Unset Delay Variation */
2183 link_param_cmd_unset(ifp, LP_DELAY_VAR);
2184
2185 return CMD_SUCCESS;
2186 }
2187
2188 DEFUN (link_params_pkt_loss,
2189 link_params_pkt_loss_cmd,
2190 "packet-loss PERCENTAGE",
2191 "Unidirectional Link Packet Loss\n"
2192 "percentage of total traffic by 0.000003% step and less than 50.331642%\n")
2193 {
2194 int idx_percentage = 1;
2195 VTY_DECLVAR_CONTEXT (interface, ifp);
2196 struct if_link_params *iflp = if_link_params_get (ifp);
2197 float fval;
2198
2199 if (sscanf (argv[idx_percentage]->arg, "%g", &fval) != 1)
2200 {
2201 vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
2202 VTY_NEWLINE);
2203 return CMD_WARNING;
2204 }
2205
2206 if (fval > MAX_PKT_LOSS)
2207 fval = MAX_PKT_LOSS;
2208
2209 /* Update Packet Loss if needed */
2210 link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
2211
2212 return CMD_SUCCESS;
2213 }
2214
2215 DEFUN (no_link_params_pkt_loss,
2216 no_link_params_pkt_loss_cmd,
2217 "no packet-loss",
2218 NO_STR
2219 "Disable Unidirectional Link Packet Loss on this interface\n")
2220 {
2221 VTY_DECLVAR_CONTEXT (interface, ifp);
2222
2223 /* Unset Packet Loss */
2224 link_param_cmd_unset(ifp, LP_PKT_LOSS);
2225
2226 return CMD_SUCCESS;
2227 }
2228
2229 DEFUN (link_params_res_bw,
2230 link_params_res_bw_cmd,
2231 "res-bw BANDWIDTH",
2232 "Unidirectional Residual Bandwidth\n"
2233 "Bytes/second (IEEE floating point format)\n")
2234 {
2235 int idx_bandwidth = 1;
2236 VTY_DECLVAR_CONTEXT (interface, ifp);
2237 struct if_link_params *iflp = if_link_params_get (ifp);
2238 float bw;
2239
2240 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
2241 {
2242 vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
2243 VTY_NEWLINE);
2244 return CMD_WARNING;
2245 }
2246
2247 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2248 if (bw > iflp->max_bw)
2249 {
2250 vty_out (vty,
2251 "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2252 iflp->max_bw, VTY_NEWLINE);
2253 return CMD_WARNING;
2254 }
2255
2256 /* Update Residual Bandwidth if needed */
2257 link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
2258
2259 return CMD_SUCCESS;
2260 }
2261
2262 DEFUN (no_link_params_res_bw,
2263 no_link_params_res_bw_cmd,
2264 "no res-bw",
2265 NO_STR
2266 "Disable Unidirectional Residual Bandwidth on this interface\n")
2267 {
2268 VTY_DECLVAR_CONTEXT (interface, ifp);
2269
2270 /* Unset Residual Bandwidth */
2271 link_param_cmd_unset(ifp, LP_RES_BW);
2272
2273 return CMD_SUCCESS;
2274 }
2275
2276 DEFUN (link_params_ava_bw,
2277 link_params_ava_bw_cmd,
2278 "ava-bw BANDWIDTH",
2279 "Unidirectional Available Bandwidth\n"
2280 "Bytes/second (IEEE floating point format)\n")
2281 {
2282 int idx_bandwidth = 1;
2283 VTY_DECLVAR_CONTEXT (interface, ifp);
2284 struct if_link_params *iflp = if_link_params_get (ifp);
2285 float bw;
2286
2287 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
2288 {
2289 vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
2290 VTY_NEWLINE);
2291 return CMD_WARNING;
2292 }
2293
2294 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2295 if (bw > iflp->max_bw)
2296 {
2297 vty_out (vty,
2298 "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2299 iflp->max_bw, VTY_NEWLINE);
2300 return CMD_WARNING;
2301 }
2302
2303 /* Update Residual Bandwidth if needed */
2304 link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
2305
2306 return CMD_SUCCESS;
2307 }
2308
2309 DEFUN (no_link_params_ava_bw,
2310 no_link_params_ava_bw_cmd,
2311 "no ava-bw",
2312 NO_STR
2313 "Disable Unidirectional Available Bandwidth on this interface\n")
2314 {
2315 VTY_DECLVAR_CONTEXT (interface, ifp);
2316
2317 /* Unset Available Bandwidth */
2318 link_param_cmd_unset(ifp, LP_AVA_BW);
2319
2320 return CMD_SUCCESS;
2321 }
2322
2323 DEFUN (link_params_use_bw,
2324 link_params_use_bw_cmd,
2325 "use-bw BANDWIDTH",
2326 "Unidirectional Utilised Bandwidth\n"
2327 "Bytes/second (IEEE floating point format)\n")
2328 {
2329 int idx_bandwidth = 1;
2330 VTY_DECLVAR_CONTEXT (interface, ifp);
2331 struct if_link_params *iflp = if_link_params_get (ifp);
2332 float bw;
2333
2334 if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1)
2335 {
2336 vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
2337 VTY_NEWLINE);
2338 return CMD_WARNING;
2339 }
2340
2341 /* Check that bandwidth is not greater than maximum bandwidth parameter */
2342 if (bw > iflp->max_bw)
2343 {
2344 vty_out (vty,
2345 "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
2346 iflp->max_bw, VTY_NEWLINE);
2347 return CMD_WARNING;
2348 }
2349
2350 /* Update Utilized Bandwidth if needed */
2351 link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
2352
2353 return CMD_SUCCESS;
2354 }
2355
2356 DEFUN (no_link_params_use_bw,
2357 no_link_params_use_bw_cmd,
2358 "no use-bw",
2359 NO_STR
2360 "Disable Unidirectional Utilised Bandwidth on this interface\n")
2361 {
2362 VTY_DECLVAR_CONTEXT (interface, ifp);
2363
2364 /* Unset Utilised Bandwidth */
2365 link_param_cmd_unset(ifp, LP_USE_BW);
2366
2367 return CMD_SUCCESS;
2368 }
2369
2370 static int
2371 ip_address_install (struct vty *vty, struct interface *ifp,
2372 const char *addr_str, const char *peer_str,
2373 const char *label)
2374 {
2375 struct zebra_if *if_data;
2376 struct prefix_ipv4 cp;
2377 struct connected *ifc;
2378 struct prefix_ipv4 *p;
2379 int ret;
2380
2381 if_data = ifp->info;
2382
2383 ret = str2prefix_ipv4 (addr_str, &cp);
2384 if (ret <= 0)
2385 {
2386 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2387 return CMD_WARNING;
2388 }
2389
2390 if (ipv4_martian(&cp.prefix))
2391 {
2392 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
2393 return CMD_WARNING;
2394 }
2395
2396 ifc = connected_check (ifp, (struct prefix *) &cp);
2397 if (! ifc)
2398 {
2399 ifc = connected_new ();
2400 ifc->ifp = ifp;
2401
2402 /* Address. */
2403 p = prefix_ipv4_new ();
2404 *p = cp;
2405 ifc->address = (struct prefix *) p;
2406
2407 /* Broadcast. */
2408 if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2)
2409 {
2410 p = prefix_ipv4_new ();
2411 *p = cp;
2412 p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen);
2413 ifc->destination = (struct prefix *) p;
2414 }
2415
2416 /* Label. */
2417 if (label)
2418 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
2419
2420 /* Add to linked list. */
2421 listnode_add (ifp->connected, ifc);
2422 }
2423
2424 /* This address is configured from zebra. */
2425 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2426 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2427
2428 /* In case of this route need to install kernel. */
2429 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2430 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2431 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
2432 {
2433 /* Some system need to up the interface to set IP address. */
2434 if (! if_is_up (ifp))
2435 {
2436 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2437 if_refresh (ifp);
2438 }
2439
2440 ret = if_set_prefix (ifp, ifc);
2441 if (ret < 0)
2442 {
2443 vty_out (vty, "%% Can't set interface IP address: %s.%s",
2444 safe_strerror(errno), VTY_NEWLINE);
2445 return CMD_WARNING;
2446 }
2447
2448 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2449 /* The address will be advertised to zebra clients when the notification
2450 * from the kernel has been received.
2451 * It will also be added to the subnet chain list, then. */
2452 }
2453
2454 return CMD_SUCCESS;
2455 }
2456
2457 static int
2458 ip_address_uninstall (struct vty *vty, struct interface *ifp,
2459 const char *addr_str, const char *peer_str,
2460 const char *label)
2461 {
2462 struct prefix_ipv4 cp;
2463 struct connected *ifc;
2464 int ret;
2465
2466 /* Convert to prefix structure. */
2467 ret = str2prefix_ipv4 (addr_str, &cp);
2468 if (ret <= 0)
2469 {
2470 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2471 return CMD_WARNING;
2472 }
2473
2474 /* Check current interface address. */
2475 ifc = connected_check (ifp, (struct prefix *) &cp);
2476 if (! ifc)
2477 {
2478 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2479 return CMD_WARNING;
2480 }
2481
2482 /* This is not configured address. */
2483 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2484 return CMD_WARNING;
2485
2486 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2487
2488 /* This is not real address or interface is not active. */
2489 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2490 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2491 {
2492 listnode_delete (ifp->connected, ifc);
2493 connected_free (ifc);
2494 return CMD_WARNING;
2495 }
2496
2497 /* This is real route. */
2498 ret = if_unset_prefix (ifp, ifc);
2499 if (ret < 0)
2500 {
2501 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
2502 safe_strerror(errno), VTY_NEWLINE);
2503 return CMD_WARNING;
2504 }
2505 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2506 /* we will receive a kernel notification about this route being removed.
2507 * this will trigger its removal from the connected list. */
2508 return CMD_SUCCESS;
2509 }
2510
2511 DEFUN (ip_address,
2512 ip_address_cmd,
2513 "ip address A.B.C.D/M",
2514 "Interface Internet Protocol config commands\n"
2515 "Set the IP address of an interface\n"
2516 "IP address (e.g. 10.0.0.1/8)\n")
2517 {
2518 int idx_ipv4_prefixlen = 2;
2519 VTY_DECLVAR_CONTEXT (interface, ifp);
2520 return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
2521 }
2522
2523 DEFUN (no_ip_address,
2524 no_ip_address_cmd,
2525 "no ip address A.B.C.D/M",
2526 NO_STR
2527 "Interface Internet Protocol config commands\n"
2528 "Set the IP address of an interface\n"
2529 "IP Address (e.g. 10.0.0.1/8)")
2530 {
2531 int idx_ipv4_prefixlen = 3;
2532 VTY_DECLVAR_CONTEXT (interface, ifp);
2533 return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL);
2534 }
2535
2536
2537 #ifdef HAVE_NETLINK
2538 DEFUN (ip_address_label,
2539 ip_address_label_cmd,
2540 "ip address A.B.C.D/M label LINE",
2541 "Interface Internet Protocol config commands\n"
2542 "Set the IP address of an interface\n"
2543 "IP address (e.g. 10.0.0.1/8)\n"
2544 "Label of this address\n"
2545 "Label\n")
2546 {
2547 int idx_ipv4_prefixlen = 2;
2548 int idx_line = 4;
2549 VTY_DECLVAR_CONTEXT (interface, ifp);
2550 return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
2551 }
2552
2553 DEFUN (no_ip_address_label,
2554 no_ip_address_label_cmd,
2555 "no ip address A.B.C.D/M label LINE",
2556 NO_STR
2557 "Interface Internet Protocol config commands\n"
2558 "Set the IP address of an interface\n"
2559 "IP address (e.g. 10.0.0.1/8)\n"
2560 "Label of this address\n"
2561 "Label\n")
2562 {
2563 int idx_ipv4_prefixlen = 3;
2564 int idx_line = 5;
2565 VTY_DECLVAR_CONTEXT (interface, ifp);
2566 return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg);
2567 }
2568 #endif /* HAVE_NETLINK */
2569
2570 static int
2571 ipv6_address_install (struct vty *vty, struct interface *ifp,
2572 const char *addr_str, const char *peer_str,
2573 const char *label, int secondary)
2574 {
2575 struct zebra_if *if_data;
2576 struct prefix_ipv6 cp;
2577 struct connected *ifc;
2578 struct prefix_ipv6 *p;
2579 int ret;
2580
2581 if_data = ifp->info;
2582
2583 ret = str2prefix_ipv6 (addr_str, &cp);
2584 if (ret <= 0)
2585 {
2586 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2587 return CMD_WARNING;
2588 }
2589
2590 if (ipv6_martian(&cp.prefix))
2591 {
2592 vty_out (vty, "%% Invalid address%s", VTY_NEWLINE);
2593 return CMD_WARNING;
2594 }
2595
2596 ifc = connected_check (ifp, (struct prefix *) &cp);
2597 if (! ifc)
2598 {
2599 ifc = connected_new ();
2600 ifc->ifp = ifp;
2601
2602 /* Address. */
2603 p = prefix_ipv6_new ();
2604 *p = cp;
2605 ifc->address = (struct prefix *) p;
2606
2607 /* Secondary. */
2608 if (secondary)
2609 SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
2610
2611 /* Label. */
2612 if (label)
2613 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
2614
2615 /* Add to linked list. */
2616 listnode_add (ifp->connected, ifc);
2617 }
2618
2619 /* This address is configured from zebra. */
2620 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2621 SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2622
2623 /* In case of this route need to install kernel. */
2624 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2625 && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)
2626 && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON))
2627 {
2628 /* Some system need to up the interface to set IP address. */
2629 if (! if_is_up (ifp))
2630 {
2631 if_set_flags (ifp, IFF_UP | IFF_RUNNING);
2632 if_refresh (ifp);
2633 }
2634
2635 ret = if_prefix_add_ipv6 (ifp, ifc);
2636
2637 if (ret < 0)
2638 {
2639 vty_out (vty, "%% Can't set interface IP address: %s.%s",
2640 safe_strerror(errno), VTY_NEWLINE);
2641 return CMD_WARNING;
2642 }
2643
2644 SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2645 /* The address will be advertised to zebra clients when the notification
2646 * from the kernel has been received. */
2647 }
2648
2649 return CMD_SUCCESS;
2650 }
2651
2652 /* Return true if an ipv6 address is configured on ifp */
2653 int
2654 ipv6_address_configured (struct interface *ifp)
2655 {
2656 struct connected *connected;
2657 struct listnode *node;
2658
2659 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
2660 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && (connected->address->family == AF_INET6))
2661 return 1;
2662
2663 return 0;
2664 }
2665
2666 static int
2667 ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
2668 const char *addr_str, const char *peer_str,
2669 const char *label, int secondry)
2670 {
2671 struct prefix_ipv6 cp;
2672 struct connected *ifc;
2673 int ret;
2674
2675 /* Convert to prefix structure. */
2676 ret = str2prefix_ipv6 (addr_str, &cp);
2677 if (ret <= 0)
2678 {
2679 vty_out (vty, "%% Malformed address %s", VTY_NEWLINE);
2680 return CMD_WARNING;
2681 }
2682
2683 /* Check current interface address. */
2684 ifc = connected_check (ifp, (struct prefix *) &cp);
2685 if (! ifc)
2686 {
2687 vty_out (vty, "%% Can't find address%s", VTY_NEWLINE);
2688 return CMD_WARNING;
2689 }
2690
2691 /* This is not configured address. */
2692 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2693 return CMD_WARNING;
2694
2695 UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
2696
2697 /* This is not real address or interface is not active. */
2698 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)
2699 || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
2700 {
2701 listnode_delete (ifp->connected, ifc);
2702 connected_free (ifc);
2703 return CMD_WARNING;
2704 }
2705
2706 /* This is real route. */
2707 ret = if_prefix_delete_ipv6 (ifp, ifc);
2708 if (ret < 0)
2709 {
2710 vty_out (vty, "%% Can't unset interface IP address: %s.%s",
2711 safe_strerror(errno), VTY_NEWLINE);
2712 return CMD_WARNING;
2713 }
2714
2715 UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
2716 /* This information will be propagated to the zclients when the
2717 * kernel notification is received. */
2718 return CMD_SUCCESS;
2719 }
2720
2721 DEFUN (ipv6_address,
2722 ipv6_address_cmd,
2723 "ipv6 address X:X::X:X/M",
2724 "Interface IPv6 config commands\n"
2725 "Set the IP address of an interface\n"
2726 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2727 {
2728 int idx_ipv6_prefixlen = 2;
2729 VTY_DECLVAR_CONTEXT (interface, ifp);
2730 return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
2731 }
2732
2733 DEFUN (no_ipv6_address,
2734 no_ipv6_address_cmd,
2735 "no ipv6 address X:X::X:X/M",
2736 NO_STR
2737 "Interface IPv6 config commands\n"
2738 "Set the IP address of an interface\n"
2739 "IPv6 address (e.g. 3ffe:506::1/48)\n")
2740 {
2741 int idx_ipv6_prefixlen = 3;
2742 VTY_DECLVAR_CONTEXT (interface, ifp);
2743 return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0);
2744 }
2745
2746 static int
2747 link_params_config_write (struct vty *vty, struct interface *ifp)
2748 {
2749 int i;
2750
2751 if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
2752 return -1;
2753
2754 struct if_link_params *iflp = ifp->link_params;
2755
2756 vty_out (vty, " link-params%s", VTY_NEWLINE);
2757 vty_out(vty, " enable%s", VTY_NEWLINE);
2758 if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric)
2759 vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
2760 if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw)
2761 vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
2762 if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) && iflp->max_rsv_bw != iflp->default_bw)
2763 vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
2764 if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
2765 {
2766 for (i = 0; i < 8; i++)
2767 if (iflp->unrsv_bw[i] != iflp->default_bw)
2768 vty_out(vty, " unrsv-bw %d %g%s",
2769 i, iflp->unrsv_bw[i], VTY_NEWLINE);
2770 }
2771 if (IS_PARAM_SET(iflp, LP_ADM_GRP))
2772 vty_out(vty, " admin-grp 0x%x%s", iflp->admin_grp, VTY_NEWLINE);
2773 if (IS_PARAM_SET(iflp, LP_DELAY))
2774 {
2775 vty_out(vty, " delay %u", iflp->av_delay);
2776 if (IS_PARAM_SET(iflp, LP_MM_DELAY))
2777 {
2778 vty_out(vty, " min %u", iflp->min_delay);
2779 vty_out(vty, " max %u", iflp->max_delay);
2780 }
2781 vty_out(vty, "%s", VTY_NEWLINE);
2782 }
2783 if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
2784 vty_out(vty, " delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
2785 if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
2786 vty_out(vty, " packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
2787 if (IS_PARAM_SET(iflp, LP_AVA_BW))
2788 vty_out(vty, " ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
2789 if (IS_PARAM_SET(iflp, LP_RES_BW))
2790 vty_out(vty, " res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
2791 if (IS_PARAM_SET(iflp, LP_USE_BW))
2792 vty_out(vty, " use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
2793 if (IS_PARAM_SET(iflp, LP_RMT_AS))
2794 vty_out(vty, " neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
2795 iflp->rmt_as, VTY_NEWLINE);
2796 vty_out(vty, " exit-link-params%s", VTY_NEWLINE);
2797 return 0;
2798 }
2799
2800 static int
2801 if_config_write (struct vty *vty)
2802 {
2803 struct vrf *vrf;
2804 struct listnode *node;
2805 struct interface *ifp;
2806
2807 zebra_ptm_write (vty);
2808
2809 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
2810 for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
2811 {
2812 struct zebra_if *if_data;
2813 struct listnode *addrnode;
2814 struct connected *ifc;
2815 struct prefix *p;
2816 struct vrf *vrf;
2817
2818 if_data = ifp->info;
2819 vrf = vrf_lookup_by_id (ifp->vrf_id);
2820
2821 if (ifp->vrf_id == VRF_DEFAULT)
2822 vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
2823 else
2824 vty_out (vty, "interface %s vrf %s%s", ifp->name, vrf->name,
2825 VTY_NEWLINE);
2826
2827 if (if_data)
2828 {
2829 if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
2830 vty_out (vty, " shutdown%s", VTY_NEWLINE);
2831
2832 zebra_ptm_if_write(vty, if_data);
2833 }
2834
2835 if (ifp->desc)
2836 vty_out (vty, " description %s%s", ifp->desc,
2837 VTY_NEWLINE);
2838
2839 /* Assign bandwidth here to avoid unnecessary interface flap
2840 while processing config script */
2841 if (ifp->bandwidth != 0)
2842 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
2843
2844 if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
2845 vty_out(vty, " no link-detect%s", VTY_NEWLINE);
2846
2847 for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
2848 {
2849 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
2850 {
2851 char buf[INET6_ADDRSTRLEN];
2852 p = ifc->address;
2853 vty_out (vty, " ip%s address %s",
2854 p->family == AF_INET ? "" : "v6",
2855 prefix2str (p, buf, sizeof(buf)));
2856
2857 if (ifc->label)
2858 vty_out (vty, " label %s", ifc->label);
2859
2860 vty_out (vty, "%s", VTY_NEWLINE);
2861 }
2862 }
2863
2864 if (if_data)
2865 {
2866 if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC)
2867 vty_out (vty, " %smulticast%s",
2868 if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ",
2869 VTY_NEWLINE);
2870 }
2871
2872 #if defined (HAVE_RTADV)
2873 rtadv_config_write (vty, ifp);
2874 #endif /* HAVE_RTADV */
2875
2876 #ifdef HAVE_IRDP
2877 irdp_config_write (vty, ifp);
2878 #endif /* IRDP */
2879
2880 link_params_config_write (vty, ifp);
2881
2882 vty_out (vty, "!%s", VTY_NEWLINE);
2883 }
2884 return 0;
2885 }
2886
2887 /* Allocate and initialize interface vector. */
2888 void
2889 zebra_if_init (void)
2890 {
2891 /* Initialize interface and new hook. */
2892 if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
2893 if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
2894
2895 /* Install configuration write function. */
2896 install_node (&interface_node, if_config_write);
2897 install_node (&link_params_node, NULL);
2898 if_cmd_init ();
2899
2900 install_element (VIEW_NODE, &show_interface_cmd);
2901 install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
2902 install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
2903 install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
2904
2905 install_element (ENABLE_NODE, &show_interface_desc_cmd);
2906 install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
2907 install_element (INTERFACE_NODE, &multicast_cmd);
2908 install_element (INTERFACE_NODE, &no_multicast_cmd);
2909 install_element (INTERFACE_NODE, &linkdetect_cmd);
2910 install_element (INTERFACE_NODE, &no_linkdetect_cmd);
2911 install_element (INTERFACE_NODE, &shutdown_if_cmd);
2912 install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
2913 install_element (INTERFACE_NODE, &bandwidth_if_cmd);
2914 install_element (INTERFACE_NODE, &no_bandwidth_if_cmd);
2915 install_element (INTERFACE_NODE, &ip_address_cmd);
2916 install_element (INTERFACE_NODE, &no_ip_address_cmd);
2917 install_element (INTERFACE_NODE, &ipv6_address_cmd);
2918 install_element (INTERFACE_NODE, &no_ipv6_address_cmd);
2919 #ifdef HAVE_NETLINK
2920 install_element (INTERFACE_NODE, &ip_address_label_cmd);
2921 install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
2922 #endif /* HAVE_NETLINK */
2923 install_element(INTERFACE_NODE, &link_params_cmd);
2924 install_default(LINK_PARAMS_NODE);
2925 install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
2926 install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
2927 install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
2928 install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd);
2929 install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
2930 install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
2931 install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
2932 install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
2933 install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd);
2934 install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
2935 install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
2936 install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
2937 install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd);
2938 install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
2939 install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd);
2940 install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
2941 install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd);
2942 install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
2943 install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd);
2944 install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
2945 install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd);
2946 install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
2947 install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd);
2948 install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);
2949 }