]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
zebra: debug additional detail for route announce/redist
[mirror_frr.git] / zebra / redistribute.c
1 /* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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
19 */
20
21 #include <zebra.h>
22
23 #include "vector.h"
24 #include "vty.h"
25 #include "command.h"
26 #include "prefix.h"
27 #include "table.h"
28 #include "stream.h"
29 #include "zclient.h"
30 #include "linklist.h"
31 #include "log.h"
32 #include "vrf.h"
33 #include "srcdest_table.h"
34
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/zebra_memory.h"
44 #include "zebra/zebra_vxlan.h"
45
46 #define ZEBRA_PTM_SUPPORT
47
48 /* array holding redistribute info about table redistribution */
49 /* bit AFI is set if that AFI is redistributing routes from this table */
50 static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
51 static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
52
53 int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
54 {
55 /*
56 * Make sure that what we are called with actualy makes sense
57 */
58 if (afi == AFI_MAX)
59 return 0;
60
61 if (is_zebra_valid_kernel_table(table_id))
62 return zebra_import_table_used[afi][table_id];
63 return 0;
64 }
65
66 static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
67 {
68 int afi;
69 struct prefix p;
70 struct route_table *table;
71 struct route_node *rn;
72 struct route_entry *newre;
73
74 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
75 /* Lookup table. */
76 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
77 if (!table)
78 continue;
79
80 /* Lookup default route. */
81 memset(&p, 0, sizeof(p));
82 p.family = afi2family(afi);
83 rn = route_node_lookup(table, &p);
84 if (!rn)
85 continue;
86
87 RNODE_FOREACH_RE (rn, newre) {
88 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
89 && newre->distance != DISTANCE_INFINITY)
90 zsend_redistribute_route(
91 ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
92 &rn->p, NULL, newre);
93 }
94
95 route_unlock_node(rn);
96 }
97 }
98
99 /* Redistribute routes. */
100 static void zebra_redistribute(struct zserv *client, int type, u_short instance,
101 vrf_id_t vrf_id, int afi)
102 {
103 struct route_entry *newre;
104 struct route_table *table;
105 struct route_node *rn;
106
107 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
108 if (!table)
109 return;
110
111 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
112 RNODE_FOREACH_RE (rn, newre) {
113 struct prefix *dst_p, *src_p;
114 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
115
116 if (IS_ZEBRA_DEBUG_EVENT)
117 zlog_debug(
118 "%s: client %s vrf %d checking: selected=%d, type=%d, distance=%d, "
119 "zebra_check_addr=%d",
120 __func__,
121 zebra_route_string(client->proto),
122 vrf_id, CHECK_FLAG(newre->flags,
123 ZEBRA_FLAG_SELECTED),
124 newre->type, newre->distance,
125 zebra_check_addr(dst_p));
126
127 if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
128 continue;
129 if ((type != ZEBRA_ROUTE_ALL
130 && (newre->type != type
131 || newre->instance != instance)))
132 continue;
133 if (newre->distance == DISTANCE_INFINITY)
134 continue;
135 if (!zebra_check_addr(dst_p))
136 continue;
137
138 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
139 client, dst_p, src_p, newre);
140 }
141 }
142
143 /* Either advertise a route for redistribution to registered clients or */
144 /* withdraw redistribution if add cannot be done for client */
145 void redistribute_update(struct prefix *p, struct prefix *src_p,
146 struct route_entry *re, struct route_entry *prev_re)
147 {
148 struct listnode *node, *nnode;
149 struct zserv *client;
150 int send_redistribute;
151 int afi;
152 char buf[INET6_ADDRSTRLEN];
153
154 if (IS_ZEBRA_DEBUG_RIB) {
155 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
156 zlog_debug(
157 "%u:%s/%d: Redist update re %p (type %d), old %p (type %d)",
158 re->vrf_id, buf, p->prefixlen, re, re->type, prev_re,
159 prev_re ? prev_re->type : -1);
160 }
161
162 afi = family2afi(p->family);
163 if (!afi) {
164 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
165 __FUNCTION__);
166 return;
167 }
168
169 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
170 send_redistribute = 0;
171
172 if (is_default_prefix(p)
173 && vrf_bitmap_check(client->redist_default, re->vrf_id))
174 send_redistribute = 1;
175 else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
176 re->vrf_id))
177 send_redistribute = 1;
178 else if (re->instance
179 && redist_check_instance(
180 &client->mi_redist[afi][re->type],
181 re->instance))
182 send_redistribute = 1;
183 else if (vrf_bitmap_check(client->redist[afi][re->type],
184 re->vrf_id))
185 send_redistribute = 1;
186
187 if (send_redistribute) {
188 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
189 client, p, src_p, re);
190 } else if (prev_re
191 && ((re->instance
192 && redist_check_instance(
193 &client->mi_redist[afi]
194 [prev_re->type],
195 re->instance))
196 || vrf_bitmap_check(
197 client->redist[afi][prev_re->type],
198 re->vrf_id))) {
199 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
200 client, p, src_p, prev_re);
201 }
202 }
203 }
204
205 void redistribute_delete(struct prefix *p, struct prefix *src_p,
206 struct route_entry *re)
207 {
208 struct listnode *node, *nnode;
209 struct zserv *client;
210 char buf[INET6_ADDRSTRLEN];
211 int afi;
212
213 if (IS_ZEBRA_DEBUG_RIB) {
214 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
215 zlog_debug("%u:%s/%d: Redist delete re %p (type %d)",
216 re->vrf_id, buf, p->prefixlen, re, re->type);
217 }
218
219 /* Add DISTANCE_INFINITY check. */
220 if (re->distance == DISTANCE_INFINITY)
221 return;
222
223 afi = family2afi(p->family);
224 if (!afi) {
225 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
226 __FUNCTION__);
227 return;
228 }
229
230 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
231 if ((is_default_prefix(p)
232 && vrf_bitmap_check(client->redist_default, re->vrf_id))
233 || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
234 re->vrf_id)
235 || (re->instance
236 && redist_check_instance(
237 &client->mi_redist[afi][re->type],
238 re->instance))
239 || vrf_bitmap_check(client->redist[afi][re->type],
240 re->vrf_id)) {
241 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
242 client, p, src_p, re);
243 }
244 }
245 }
246
247 void zebra_redistribute_add(int command, struct zserv *client, int length,
248 struct zebra_vrf *zvrf)
249 {
250 afi_t afi = 0;
251 int type = 0;
252 u_short instance;
253
254 STREAM_GETC(client->ibuf, afi);
255 STREAM_GETC(client->ibuf, type);
256 STREAM_GETW(client->ibuf, instance);
257
258 if (IS_ZEBRA_DEBUG_EVENT)
259 zlog_debug(
260 "%s: client proto %s afi=%d, wants %s, vrf %d, instance=%d",
261 __func__, zebra_route_string(client->proto), afi,
262 zebra_route_string(type), zvrf_id(zvrf), instance);
263
264 if (afi == 0 || afi > AFI_MAX) {
265 zlog_warn("%s: Specified afi %d does not exist",
266 __PRETTY_FUNCTION__, afi);
267 return;
268 }
269
270 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
271 zlog_warn("%s: Specified Route Type %d does not exist",
272 __PRETTY_FUNCTION__, type);
273 return;
274 }
275
276 if (instance) {
277 if (!redist_check_instance(&client->mi_redist[afi][type],
278 instance)) {
279 redist_add_instance(&client->mi_redist[afi][type],
280 instance);
281 zebra_redistribute(client, type, instance,
282 zvrf_id(zvrf), afi);
283 }
284 } else {
285 if (!vrf_bitmap_check(client->redist[afi][type],
286 zvrf_id(zvrf))) {
287 if (IS_ZEBRA_DEBUG_EVENT)
288 zlog_debug("%s: setting vrf %d redist bitmap",
289 __func__, zvrf_id(zvrf));
290 vrf_bitmap_set(client->redist[afi][type],
291 zvrf_id(zvrf));
292 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
293 }
294 }
295
296 stream_failure:
297 return;
298 }
299
300 void zebra_redistribute_delete(int command, struct zserv *client, int length,
301 struct zebra_vrf *zvrf)
302 {
303 afi_t afi = 0;
304 int type = 0;
305 u_short instance;
306
307 STREAM_GETC(client->ibuf, afi);
308 STREAM_GETC(client->ibuf, type);
309 STREAM_GETW(client->ibuf, instance);
310
311 if (afi == 0 || afi > AFI_MAX) {
312 zlog_warn("%s: Specified afi %d does not exist",
313 __PRETTY_FUNCTION__, afi);
314 return;
315 }
316
317 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
318 zlog_warn("%s: Specified Route Type %d does not exist",
319 __PRETTY_FUNCTION__, type);
320 return;
321 }
322
323 /*
324 * NOTE: no need to withdraw the previously advertised routes. The
325 * clients
326 * themselves should keep track of the received routes from zebra and
327 * withdraw them when necessary.
328 */
329 if (instance)
330 redist_del_instance(&client->mi_redist[afi][type], instance);
331 else
332 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
333
334 stream_failure:
335 return;
336 }
337
338 void zebra_redistribute_default_add(int command, struct zserv *client,
339 int length, struct zebra_vrf *zvrf)
340 {
341 vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
342 zebra_redistribute_default(client, zvrf_id(zvrf));
343 }
344
345 void zebra_redistribute_default_delete(int command, struct zserv *client,
346 int length, struct zebra_vrf *zvrf)
347 {
348 vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
349 }
350
351 /* Interface up information. */
352 void zebra_interface_up_update(struct interface *ifp)
353 {
354 struct listnode *node, *nnode;
355 struct zserv *client;
356
357 if (IS_ZEBRA_DEBUG_EVENT)
358 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
359
360 if (ifp->ptm_status || !ifp->ptm_enable) {
361 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
362 if (client->ifinfo) {
363 zsend_interface_update(ZEBRA_INTERFACE_UP,
364 client, ifp);
365 zsend_interface_link_params(client, ifp);
366 }
367 }
368 }
369
370 /* Interface down information. */
371 void zebra_interface_down_update(struct interface *ifp)
372 {
373 struct listnode *node, *nnode;
374 struct zserv *client;
375
376 if (IS_ZEBRA_DEBUG_EVENT)
377 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
378
379 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
380 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
381 }
382 }
383
384 /* Interface information update. */
385 void zebra_interface_add_update(struct interface *ifp)
386 {
387 struct listnode *node, *nnode;
388 struct zserv *client;
389
390 if (IS_ZEBRA_DEBUG_EVENT)
391 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name,
392 ifp->vrf_id);
393
394 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
395 if (client->ifinfo) {
396 client->ifadd_cnt++;
397 zsend_interface_add(client, ifp);
398 zsend_interface_link_params(client, ifp);
399 }
400 }
401
402 void zebra_interface_delete_update(struct interface *ifp)
403 {
404 struct listnode *node, *nnode;
405 struct zserv *client;
406
407 if (IS_ZEBRA_DEBUG_EVENT)
408 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
409
410 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
411 client->ifdel_cnt++;
412 zsend_interface_delete(client, ifp);
413 }
414 }
415
416 /* Interface address addition. */
417 void zebra_interface_address_add_update(struct interface *ifp,
418 struct connected *ifc)
419 {
420 struct listnode *node, *nnode;
421 struct zserv *client;
422 struct prefix *p;
423
424 if (IS_ZEBRA_DEBUG_EVENT) {
425 char buf[PREFIX_STRLEN];
426
427 p = ifc->address;
428 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
429 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
430 }
431
432 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
433 zlog_warn(
434 "WARNING: advertising address to clients that is not yet usable.");
435
436 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
437
438 router_id_add_address(ifc);
439
440 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
441 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
442 client->connected_rt_add_cnt++;
443 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
444 client, ifp, ifc);
445 }
446 }
447
448 /* Interface address deletion. */
449 void zebra_interface_address_delete_update(struct interface *ifp,
450 struct connected *ifc)
451 {
452 struct listnode *node, *nnode;
453 struct zserv *client;
454 struct prefix *p;
455
456 if (IS_ZEBRA_DEBUG_EVENT) {
457 char buf[PREFIX_STRLEN];
458
459 p = ifc->address;
460 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
461 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
462 }
463
464 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
465
466 router_id_del_address(ifc);
467
468 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
469 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
470 client->connected_rt_del_cnt++;
471 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
472 client, ifp, ifc);
473 }
474 }
475
476 /* Interface VRF change. May need to delete from clients not interested in
477 * the new VRF. Note that this function is invoked *prior* to the VRF change.
478 */
479 void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
480 {
481 struct listnode *node, *nnode;
482 struct zserv *client;
483
484 if (IS_ZEBRA_DEBUG_EVENT)
485 zlog_debug(
486 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
487 ifp->name, ifp->vrf_id, new_vrf_id);
488
489 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
490 /* Need to delete if the client is not interested in the new
491 * VRF. */
492 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
493 client->ifdel_cnt++;
494 zsend_interface_delete(client, ifp);
495 zsend_interface_vrf_update(client, ifp, new_vrf_id);
496 }
497 }
498
499 /* Interface VRF change. This function is invoked *post* VRF change and sends an
500 * add to clients who are interested in the new VRF but not in the old VRF.
501 */
502 void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
503 {
504 struct listnode *node, *nnode;
505 struct zserv *client;
506
507 if (IS_ZEBRA_DEBUG_EVENT)
508 zlog_debug(
509 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
510 ifp->name, old_vrf_id, ifp->vrf_id);
511
512 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
513 /* Need to add if the client is interested in the new VRF. */
514 client->ifadd_cnt++;
515 zsend_interface_add(client, ifp);
516 zsend_interface_addresses(client, ifp);
517 }
518 }
519
520 int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
521 const char *rmap_name)
522 {
523 struct route_entry *newre;
524 struct route_entry *same;
525 struct prefix p;
526 route_map_result_t ret = RMAP_MATCH;
527 afi_t afi;
528
529 afi = family2afi(rn->p.family);
530 if (rmap_name)
531 ret = zebra_import_table_route_map_check(
532 afi, re->type, &rn->p, re->ng.nexthop, re->vrf_id,
533 re->tag, rmap_name);
534
535 if (ret != RMAP_MATCH) {
536 zebra_del_import_table_entry(rn, re);
537 return 0;
538 }
539
540 prefix_copy(&p, &rn->p);
541
542 RNODE_FOREACH_RE (rn, same) {
543 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
544 continue;
545
546 if (same->type == re->type && same->instance == re->instance
547 && same->table == re->table
548 && same->type != ZEBRA_ROUTE_CONNECT)
549 break;
550 }
551
552 if (same)
553 zebra_del_import_table_entry(rn, same);
554
555 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
556 newre->type = ZEBRA_ROUTE_TABLE;
557 newre->distance = zebra_import_table_distance[afi][re->table];
558 newre->flags = re->flags;
559 newre->metric = re->metric;
560 newre->mtu = re->mtu;
561 newre->table = zebrad.rtm_table_default;
562 newre->nexthop_num = 0;
563 newre->uptime = time(NULL);
564 newre->instance = re->table;
565 route_entry_copy_nexthops(newre, re->ng.nexthop);
566
567 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
568
569 return 0;
570 }
571
572 int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
573 {
574 struct prefix p;
575 afi_t afi;
576
577 afi = family2afi(rn->p.family);
578 prefix_copy(&p, &rn->p);
579
580 rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
581 re->flags, &p, NULL, re->ng.nexthop,
582 zebrad.rtm_table_default, re->metric, false, NULL);
583
584 return 0;
585 }
586
587 /* Assuming no one calls this with the main routing table */
588 int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance,
589 const char *rmap_name, int add)
590 {
591 struct route_table *table;
592 struct route_entry *re;
593 struct route_node *rn;
594
595 if (!is_zebra_valid_kernel_table(table_id)
596 || ((table_id == RT_TABLE_MAIN)
597 || (table_id == zebrad.rtm_table_default)))
598 return (-1);
599
600 if (afi >= AFI_MAX)
601 return (-1);
602
603 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
604 if (table == NULL) {
605 return 0;
606 } else if (IS_ZEBRA_DEBUG_RIB) {
607 zlog_debug("%s routes from table %d",
608 add ? "Importing" : "Unimporting", table_id);
609 }
610
611 if (add) {
612 if (rmap_name)
613 zebra_add_import_table_route_map(afi, rmap_name,
614 table_id);
615 else {
616 rmap_name =
617 zebra_get_import_table_route_map(afi, table_id);
618 if (rmap_name)
619 zebra_del_import_table_route_map(afi, table_id);
620 }
621
622 zebra_import_table_used[afi][table_id] = 1;
623 zebra_import_table_distance[afi][table_id] = distance;
624 } else {
625 zebra_import_table_used[afi][table_id] = 0;
626 zebra_import_table_distance[afi][table_id] =
627 ZEBRA_TABLE_DISTANCE_DEFAULT;
628
629 rmap_name = zebra_get_import_table_route_map(afi, table_id);
630 if (rmap_name)
631 zebra_del_import_table_route_map(afi, table_id);
632 }
633
634 for (rn = route_top(table); rn; rn = route_next(rn)) {
635 /* For each entry in the non-default routing table,
636 * add the entry in the main table
637 */
638 if (!rn->info)
639 continue;
640
641 RNODE_FOREACH_RE (rn, re) {
642 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
643 continue;
644 break;
645 }
646
647 if (!re)
648 continue;
649
650 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
651 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
652 if (add)
653 zebra_add_import_table_entry(rn, re, rmap_name);
654 else
655 zebra_del_import_table_entry(rn, re);
656 }
657 }
658 return 0;
659 }
660
661 int zebra_import_table_config(struct vty *vty)
662 {
663 int i;
664 afi_t afi;
665 int write = 0;
666 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
667 const char *rmap_name;
668
669 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
670 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
671 if (!is_zebra_import_table_enabled(afi, i))
672 continue;
673
674 if (zebra_import_table_distance[afi][i]
675 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
676 vty_out(vty, "%s import-table %d distance %d",
677 afi_str[afi], i,
678 zebra_import_table_distance[afi][i]);
679 } else {
680 vty_out(vty, "%s import-table %d", afi_str[afi],
681 i);
682 }
683
684 rmap_name = zebra_get_import_table_route_map(afi, i);
685 if (rmap_name)
686 vty_out(vty, " route-map %s", rmap_name);
687
688 vty_out(vty, "\n");
689 write = 1;
690 }
691 }
692
693 return write;
694 }
695
696 void zebra_import_table_rm_update()
697 {
698 afi_t afi;
699 int i;
700 struct route_table *table;
701 struct route_entry *re;
702 struct route_node *rn;
703 const char *rmap_name;
704
705 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
706 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
707 if (!is_zebra_import_table_enabled(afi, i))
708 continue;
709
710 rmap_name = zebra_get_import_table_route_map(afi, i);
711 if (!rmap_name)
712 return;
713
714 table = zebra_vrf_other_route_table(afi, i,
715 VRF_DEFAULT);
716 for (rn = route_top(table); rn; rn = route_next(rn)) {
717 /* For each entry in the non-default
718 * routing table,
719 * add the entry in the main table
720 */
721 if (!rn->info)
722 continue;
723
724 RNODE_FOREACH_RE (rn, re) {
725 if (CHECK_FLAG(re->status,
726 ROUTE_ENTRY_REMOVED))
727 continue;
728 break;
729 }
730
731 if (!re)
732 continue;
733
734 if (((afi == AFI_IP)
735 && (rn->p.family == AF_INET))
736 || ((afi == AFI_IP6)
737 && (rn->p.family == AF_INET6)))
738 zebra_add_import_table_entry(rn, re,
739 rmap_name);
740 }
741 }
742 }
743
744 return;
745 }
746
747 /* Interface parameters update */
748 void zebra_interface_parameters_update(struct interface *ifp)
749 {
750 struct listnode *node, *nnode;
751 struct zserv *client;
752
753 if (IS_ZEBRA_DEBUG_EVENT)
754 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s",
755 ifp->name);
756
757 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
758 if (client->ifinfo)
759 zsend_interface_link_params(client, ifp);
760 }