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