1 /* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "srcdest_table.h"
35 #include "zebra/rib.h"
36 #include "zebra/zserv.h"
37 #include "zebra/zebra_ns.h"
38 #include "zebra/zebra_vrf.h"
39 #include "zebra/zebra_routemap.h"
40 #include "zebra/redistribute.h"
41 #include "zebra/debug.h"
42 #include "zebra/router-id.h"
43 #include "zebra/zapi_msg.h"
44 #include "zebra/zebra_memory.h"
45 #include "zebra/zebra_vxlan.h"
47 #define ZEBRA_PTM_SUPPORT
49 /* array holding redistribute info about table redistribution */
50 /* bit AFI is set if that AFI is redistributing routes from this table */
51 static int zebra_import_table_used
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
52 static uint32_t zebra_import_table_distance
[AFI_MAX
][ZEBRA_KERNEL_TABLE_MAX
];
54 int is_zebra_import_table_enabled(afi_t afi
, uint32_t table_id
)
57 * Make sure that what we are called with actualy makes sense
62 if (is_zebra_valid_kernel_table(table_id
) &&
63 table_id
< ZEBRA_KERNEL_TABLE_MAX
)
64 return zebra_import_table_used
[afi
][table_id
];
68 static void zebra_redistribute_default(struct zserv
*client
, vrf_id_t vrf_id
)
72 struct route_table
*table
;
73 struct route_node
*rn
;
74 struct route_entry
*newre
;
76 for (afi
= AFI_IP
; afi
<= AFI_IP6
; afi
++) {
78 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
82 /* Lookup default route. */
83 memset(&p
, 0, sizeof(p
));
84 p
.family
= afi2family(afi
);
85 rn
= route_node_lookup(table
, &p
);
89 RNODE_FOREACH_RE (rn
, newre
) {
90 if (CHECK_FLAG(newre
->flags
, ZEBRA_FLAG_SELECTED
)
91 && newre
->distance
!= DISTANCE_INFINITY
)
92 zsend_redistribute_route(
93 ZEBRA_REDISTRIBUTE_ROUTE_ADD
, client
,
97 route_unlock_node(rn
);
101 /* Redistribute routes. */
102 static void zebra_redistribute(struct zserv
*client
, int type
,
103 unsigned short instance
, vrf_id_t vrf_id
,
106 struct route_entry
*newre
;
107 struct route_table
*table
;
108 struct route_node
*rn
;
110 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
114 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
115 RNODE_FOREACH_RE (rn
, newre
) {
116 const struct prefix
*dst_p
, *src_p
;
117 char buf
[PREFIX_STRLEN
];
119 srcdest_rnode_prefixes(rn
, &dst_p
, &src_p
);
121 if (IS_ZEBRA_DEBUG_EVENT
)
123 "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
125 zebra_route_string(client
->proto
),
126 prefix2str(dst_p
, buf
, sizeof(buf
)),
127 vrf_id
, CHECK_FLAG(newre
->flags
,
128 ZEBRA_FLAG_SELECTED
),
129 newre
->type
, newre
->distance
,
130 newre
->metric
, zebra_check_addr(dst_p
));
132 if (!CHECK_FLAG(newre
->flags
, ZEBRA_FLAG_SELECTED
))
134 if ((type
!= ZEBRA_ROUTE_ALL
135 && (newre
->type
!= type
136 || newre
->instance
!= instance
)))
138 if (newre
->distance
== DISTANCE_INFINITY
)
140 if (!zebra_check_addr(dst_p
))
143 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD
,
144 client
, dst_p
, src_p
, newre
);
148 /* Either advertise a route for redistribution to registered clients or */
149 /* withdraw redistribution if add cannot be done for client */
150 void redistribute_update(const struct prefix
*p
, const struct prefix
*src_p
,
151 struct route_entry
*re
, struct route_entry
*prev_re
)
153 struct listnode
*node
, *nnode
;
154 struct zserv
*client
;
155 int send_redistribute
;
157 char buf
[PREFIX_STRLEN
];
159 if (IS_ZEBRA_DEBUG_RIB
) {
161 "%u:%s: Redist update re %p (type %d), old %p (type %d)",
162 re
->vrf_id
, prefix2str(p
, buf
, sizeof(buf
)),
163 re
, re
->type
, prev_re
,
164 prev_re
? prev_re
->type
: -1);
167 afi
= family2afi(p
->family
);
169 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
174 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
175 send_redistribute
= 0;
177 if (is_default_prefix(p
)
178 && vrf_bitmap_check(client
->redist_default
, re
->vrf_id
))
179 send_redistribute
= 1;
180 else if (vrf_bitmap_check(client
->redist
[afi
][ZEBRA_ROUTE_ALL
],
182 send_redistribute
= 1;
183 else if (re
->instance
184 && redist_check_instance(
185 &client
->mi_redist
[afi
][re
->type
],
187 send_redistribute
= 1;
188 else if (vrf_bitmap_check(client
->redist
[afi
][re
->type
],
190 send_redistribute
= 1;
192 if (send_redistribute
) {
193 if (IS_ZEBRA_DEBUG_EVENT
) {
195 "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
197 zebra_route_string(client
->proto
),
198 prefix2str(p
, buf
, sizeof(buf
)),
199 re
->vrf_id
, re
->type
,
200 re
->distance
, re
->metric
);
202 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD
,
203 client
, p
, src_p
, re
);
206 && redist_check_instance(
207 &client
->mi_redist
[afi
]
211 client
->redist
[afi
][prev_re
->type
],
213 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL
,
214 client
, p
, src_p
, prev_re
);
219 void redistribute_delete(const struct prefix
*p
, const struct prefix
*src_p
,
220 struct route_entry
*re
)
222 struct listnode
*node
, *nnode
;
223 struct zserv
*client
;
224 char buf
[INET6_ADDRSTRLEN
];
227 if (IS_ZEBRA_DEBUG_RIB
) {
228 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, INET6_ADDRSTRLEN
);
229 zlog_debug("%u:%s/%d: Redist delete re %p (type %d)",
230 re
->vrf_id
, buf
, p
->prefixlen
, re
, re
->type
);
233 /* Add DISTANCE_INFINITY check. */
234 if (re
->distance
== DISTANCE_INFINITY
)
237 afi
= family2afi(p
->family
);
239 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
244 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
245 if ((is_default_prefix(p
)
246 && vrf_bitmap_check(client
->redist_default
, re
->vrf_id
))
247 || vrf_bitmap_check(client
->redist
[afi
][ZEBRA_ROUTE_ALL
],
250 && redist_check_instance(
251 &client
->mi_redist
[afi
][re
->type
],
253 || vrf_bitmap_check(client
->redist
[afi
][re
->type
],
255 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL
,
256 client
, p
, src_p
, re
);
261 void zebra_redistribute_add(ZAPI_HANDLER_ARGS
)
265 unsigned short instance
;
267 STREAM_GETC(msg
, afi
);
268 STREAM_GETC(msg
, type
);
269 STREAM_GETW(msg
, instance
);
271 if (IS_ZEBRA_DEBUG_EVENT
)
273 "%s: client proto %s afi=%d, wants %s, vrf %u, instance=%d",
274 __func__
, zebra_route_string(client
->proto
), afi
,
275 zebra_route_string(type
), zvrf_id(zvrf
), instance
);
277 if (afi
== 0 || afi
>= AFI_MAX
) {
278 zlog_warn("%s: Specified afi %d does not exist",
279 __PRETTY_FUNCTION__
, afi
);
283 if (type
== 0 || type
>= ZEBRA_ROUTE_MAX
) {
284 zlog_warn("%s: Specified Route Type %d does not exist",
285 __PRETTY_FUNCTION__
, type
);
290 if (!redist_check_instance(&client
->mi_redist
[afi
][type
],
292 redist_add_instance(&client
->mi_redist
[afi
][type
],
294 zebra_redistribute(client
, type
, instance
,
298 if (!vrf_bitmap_check(client
->redist
[afi
][type
],
300 if (IS_ZEBRA_DEBUG_EVENT
)
301 zlog_debug("%s: setting vrf %u redist bitmap",
302 __func__
, zvrf_id(zvrf
));
303 vrf_bitmap_set(client
->redist
[afi
][type
],
305 zebra_redistribute(client
, type
, 0, zvrf_id(zvrf
), afi
);
313 void zebra_redistribute_delete(ZAPI_HANDLER_ARGS
)
317 unsigned short instance
;
319 STREAM_GETC(msg
, afi
);
320 STREAM_GETC(msg
, type
);
321 STREAM_GETW(msg
, instance
);
323 if (afi
== 0 || afi
>= AFI_MAX
) {
324 zlog_warn("%s: Specified afi %d does not exist",
325 __PRETTY_FUNCTION__
, afi
);
329 if (type
== 0 || type
>= ZEBRA_ROUTE_MAX
) {
330 zlog_warn("%s: Specified Route Type %d does not exist",
331 __PRETTY_FUNCTION__
, type
);
336 * NOTE: no need to withdraw the previously advertised routes. The
338 * themselves should keep track of the received routes from zebra and
339 * withdraw them when necessary.
342 redist_del_instance(&client
->mi_redist
[afi
][type
], instance
);
344 vrf_bitmap_unset(client
->redist
[afi
][type
], zvrf_id(zvrf
));
350 void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS
)
352 vrf_bitmap_set(client
->redist_default
, zvrf_id(zvrf
));
353 zebra_redistribute_default(client
, zvrf_id(zvrf
));
356 void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS
)
358 vrf_bitmap_unset(client
->redist_default
, zvrf_id(zvrf
));
361 /* Interface up information. */
362 void zebra_interface_up_update(struct interface
*ifp
)
364 struct listnode
*node
, *nnode
;
365 struct zserv
*client
;
367 if (IS_ZEBRA_DEBUG_EVENT
)
368 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
369 ifp
->name
, ifp
->vrf_id
);
371 if (ifp
->ptm_status
|| !ifp
->ptm_enable
) {
372 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
))
373 if (client
->ifinfo
) {
374 zsend_interface_update(ZEBRA_INTERFACE_UP
,
376 zsend_interface_link_params(client
, ifp
);
381 /* Interface down information. */
382 void zebra_interface_down_update(struct interface
*ifp
)
384 struct listnode
*node
, *nnode
;
385 struct zserv
*client
;
387 if (IS_ZEBRA_DEBUG_EVENT
)
388 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
389 ifp
->name
, ifp
->vrf_id
);
391 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
392 zsend_interface_update(ZEBRA_INTERFACE_DOWN
, client
, ifp
);
396 /* Interface information update. */
397 void zebra_interface_add_update(struct interface
*ifp
)
399 struct listnode
*node
, *nnode
;
400 struct zserv
*client
;
402 if (IS_ZEBRA_DEBUG_EVENT
)
403 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp
->name
,
406 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
))
407 if (client
->ifinfo
) {
409 zsend_interface_add(client
, ifp
);
410 zsend_interface_link_params(client
, ifp
);
414 void zebra_interface_delete_update(struct interface
*ifp
)
416 struct listnode
*node
, *nnode
;
417 struct zserv
*client
;
419 if (IS_ZEBRA_DEBUG_EVENT
)
420 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
421 ifp
->name
, ifp
->vrf_id
);
423 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
425 zsend_interface_delete(client
, ifp
);
429 /* Interface address addition. */
430 void zebra_interface_address_add_update(struct interface
*ifp
,
431 struct connected
*ifc
)
433 struct listnode
*node
, *nnode
;
434 struct zserv
*client
;
437 if (IS_ZEBRA_DEBUG_EVENT
) {
438 char buf
[PREFIX_STRLEN
];
441 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
442 prefix2str(p
, buf
, sizeof(buf
)), ifp
->name
,
446 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
448 "WARNING: advertising address to clients that is not yet usable.");
450 zebra_vxlan_add_del_gw_macip(ifp
, ifc
->address
, 1);
452 router_id_add_address(ifc
);
454 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
))
455 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
)) {
456 client
->connected_rt_add_cnt
++;
457 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD
,
462 /* Interface address deletion. */
463 void zebra_interface_address_delete_update(struct interface
*ifp
,
464 struct connected
*ifc
)
466 struct listnode
*node
, *nnode
;
467 struct zserv
*client
;
470 if (IS_ZEBRA_DEBUG_EVENT
) {
471 char buf
[PREFIX_STRLEN
];
474 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
475 prefix2str(p
, buf
, sizeof(buf
)),
476 ifp
->name
, ifp
->vrf_id
);
479 zebra_vxlan_add_del_gw_macip(ifp
, ifc
->address
, 0);
481 router_id_del_address(ifc
);
483 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
))
484 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
)) {
485 client
->connected_rt_del_cnt
++;
486 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE
,
491 /* Interface VRF change. May need to delete from clients not interested in
492 * the new VRF. Note that this function is invoked *prior* to the VRF change.
494 void zebra_interface_vrf_update_del(struct interface
*ifp
, vrf_id_t new_vrf_id
)
496 struct listnode
*node
, *nnode
;
497 struct zserv
*client
;
499 if (IS_ZEBRA_DEBUG_EVENT
)
501 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
502 ifp
->name
, ifp
->vrf_id
, new_vrf_id
);
504 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
505 /* Need to delete if the client is not interested in the new
507 zsend_interface_update(ZEBRA_INTERFACE_DOWN
, client
, ifp
);
509 zsend_interface_delete(client
, ifp
);
510 zsend_interface_vrf_update(client
, ifp
, new_vrf_id
);
514 /* Interface VRF change. This function is invoked *post* VRF change and sends an
515 * add to clients who are interested in the new VRF but not in the old VRF.
517 void zebra_interface_vrf_update_add(struct interface
*ifp
, vrf_id_t old_vrf_id
)
519 struct listnode
*node
, *nnode
;
520 struct zserv
*client
;
522 if (IS_ZEBRA_DEBUG_EVENT
)
524 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
525 ifp
->name
, old_vrf_id
, ifp
->vrf_id
);
527 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
)) {
528 /* Need to add if the client is interested in the new VRF. */
530 zsend_interface_add(client
, ifp
);
531 zsend_interface_addresses(client
, ifp
);
535 int zebra_add_import_table_entry(struct route_node
*rn
, struct route_entry
*re
,
536 const char *rmap_name
)
538 struct route_entry
*newre
;
539 struct route_entry
*same
;
541 route_map_result_t ret
= RMAP_MATCH
;
544 afi
= family2afi(rn
->p
.family
);
546 ret
= zebra_import_table_route_map_check(
547 afi
, re
->type
, re
->instance
, &rn
->p
, re
->ng
.nexthop
,
548 re
->vrf_id
, re
->tag
, rmap_name
);
550 if (ret
!= RMAP_MATCH
) {
551 UNSET_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
);
552 zebra_del_import_table_entry(rn
, re
);
556 prefix_copy(&p
, &rn
->p
);
558 RNODE_FOREACH_RE (rn
, same
) {
559 if (CHECK_FLAG(same
->status
, ROUTE_ENTRY_REMOVED
))
562 if (same
->type
== re
->type
&& same
->instance
== re
->instance
563 && same
->table
== re
->table
564 && same
->type
!= ZEBRA_ROUTE_CONNECT
)
569 UNSET_FLAG(same
->flags
, ZEBRA_FLAG_SELECTED
);
570 zebra_del_import_table_entry(rn
, same
);
573 newre
= XCALLOC(MTYPE_RE
, sizeof(struct route_entry
));
574 newre
->type
= ZEBRA_ROUTE_TABLE
;
575 newre
->distance
= zebra_import_table_distance
[afi
][re
->table
];
576 newre
->flags
= re
->flags
;
577 newre
->metric
= re
->metric
;
578 newre
->mtu
= re
->mtu
;
579 newre
->table
= zebrad
.rtm_table_default
;
580 newre
->nexthop_num
= 0;
581 newre
->uptime
= time(NULL
);
582 newre
->instance
= re
->table
;
583 route_entry_copy_nexthops(newre
, re
->ng
.nexthop
);
585 rib_add_multipath(afi
, SAFI_UNICAST
, &p
, NULL
, newre
);
590 int zebra_del_import_table_entry(struct route_node
*rn
, struct route_entry
*re
)
595 afi
= family2afi(rn
->p
.family
);
596 prefix_copy(&p
, &rn
->p
);
598 rib_delete(afi
, SAFI_UNICAST
, re
->vrf_id
, ZEBRA_ROUTE_TABLE
, re
->table
,
599 re
->flags
, &p
, NULL
, re
->ng
.nexthop
,
600 zebrad
.rtm_table_default
, re
->metric
, false);
605 /* Assuming no one calls this with the main routing table */
606 int zebra_import_table(afi_t afi
, uint32_t table_id
, uint32_t distance
,
607 const char *rmap_name
, int add
)
609 struct route_table
*table
;
610 struct route_entry
*re
;
611 struct route_node
*rn
;
613 if (!is_zebra_valid_kernel_table(table_id
)
614 || ((table_id
== RT_TABLE_MAIN
)
615 || (table_id
== zebrad
.rtm_table_default
)))
621 table
= zebra_vrf_other_route_table(afi
, table_id
, VRF_DEFAULT
);
624 } else if (IS_ZEBRA_DEBUG_RIB
) {
625 zlog_debug("%s routes from table %d",
626 add
? "Importing" : "Unimporting", table_id
);
631 zebra_add_import_table_route_map(afi
, rmap_name
,
635 zebra_get_import_table_route_map(afi
, table_id
);
637 zebra_del_import_table_route_map(afi
, table_id
);
642 zebra_import_table_used
[afi
][table_id
] = 1;
643 zebra_import_table_distance
[afi
][table_id
] = distance
;
645 zebra_import_table_used
[afi
][table_id
] = 0;
646 zebra_import_table_distance
[afi
][table_id
] =
647 ZEBRA_TABLE_DISTANCE_DEFAULT
;
649 rmap_name
= zebra_get_import_table_route_map(afi
, table_id
);
651 zebra_del_import_table_route_map(afi
, table_id
);
656 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
657 /* For each entry in the non-default routing table,
658 * add the entry in the main table
663 RNODE_FOREACH_RE (rn
, re
) {
664 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_REMOVED
))
672 if (((afi
== AFI_IP
) && (rn
->p
.family
== AF_INET
))
673 || ((afi
== AFI_IP6
) && (rn
->p
.family
== AF_INET6
))) {
675 zebra_add_import_table_entry(rn
, re
, rmap_name
);
677 zebra_del_import_table_entry(rn
, re
);
683 int zebra_import_table_config(struct vty
*vty
)
688 char afi_str
[AFI_MAX
][10] = {"", "ip", "ipv6", "ethernet"};
689 const char *rmap_name
;
691 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
692 for (i
= 1; i
< ZEBRA_KERNEL_TABLE_MAX
; i
++) {
693 if (!is_zebra_import_table_enabled(afi
, i
))
696 if (zebra_import_table_distance
[afi
][i
]
697 != ZEBRA_TABLE_DISTANCE_DEFAULT
) {
698 vty_out(vty
, "%s import-table %d distance %d",
700 zebra_import_table_distance
[afi
][i
]);
702 vty_out(vty
, "%s import-table %d", afi_str
[afi
],
706 rmap_name
= zebra_get_import_table_route_map(afi
, i
);
708 vty_out(vty
, " route-map %s", rmap_name
);
718 void zebra_import_table_rm_update()
722 struct route_table
*table
;
723 struct route_entry
*re
;
724 struct route_node
*rn
;
725 const char *rmap_name
;
727 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
728 for (i
= 1; i
< ZEBRA_KERNEL_TABLE_MAX
; i
++) {
729 if (!is_zebra_import_table_enabled(afi
, i
))
732 rmap_name
= zebra_get_import_table_route_map(afi
, i
);
736 table
= zebra_vrf_other_route_table(afi
, i
,
738 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
739 /* For each entry in the non-default
741 * add the entry in the main table
746 RNODE_FOREACH_RE (rn
, re
) {
747 if (CHECK_FLAG(re
->status
,
748 ROUTE_ENTRY_REMOVED
))
757 && (rn
->p
.family
== AF_INET
))
759 && (rn
->p
.family
== AF_INET6
)))
760 zebra_add_import_table_entry(rn
, re
,
769 /* Interface parameters update */
770 void zebra_interface_parameters_update(struct interface
*ifp
)
772 struct listnode
*node
, *nnode
;
773 struct zserv
*client
;
775 if (IS_ZEBRA_DEBUG_EVENT
)
776 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
777 ifp
->name
, ifp
->vrf_id
);
779 for (ALL_LIST_ELEMENTS(zebrad
.client_list
, node
, nnode
, client
))
781 zsend_interface_link_params(client
, ifp
);