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