]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
3a66aea45f897ef6d9f7d1b61987d0c50c129669
[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(ZAPI_HANDLER_ARGS)
248 {
249 afi_t afi = 0;
250 int type = 0;
251 u_short instance;
252
253 STREAM_GETC(msg, afi);
254 STREAM_GETC(msg, type);
255 STREAM_GETW(msg, instance);
256
257 if (IS_ZEBRA_DEBUG_EVENT)
258 zlog_debug(
259 "%s: client proto %s afi=%d, wants %s, vrf %d, instance=%d",
260 __func__, zebra_route_string(client->proto), afi,
261 zebra_route_string(type), zvrf_id(zvrf), instance);
262
263 if (afi == 0 || afi > AFI_MAX) {
264 zlog_warn("%s: Specified afi %d does not exist",
265 __PRETTY_FUNCTION__, afi);
266 return;
267 }
268
269 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
270 zlog_warn("%s: Specified Route Type %d does not exist",
271 __PRETTY_FUNCTION__, type);
272 return;
273 }
274
275 if (instance) {
276 if (!redist_check_instance(&client->mi_redist[afi][type],
277 instance)) {
278 redist_add_instance(&client->mi_redist[afi][type],
279 instance);
280 zebra_redistribute(client, type, instance,
281 zvrf_id(zvrf), afi);
282 }
283 } else {
284 if (!vrf_bitmap_check(client->redist[afi][type],
285 zvrf_id(zvrf))) {
286 if (IS_ZEBRA_DEBUG_EVENT)
287 zlog_debug("%s: setting vrf %d redist bitmap",
288 __func__, zvrf_id(zvrf));
289 vrf_bitmap_set(client->redist[afi][type],
290 zvrf_id(zvrf));
291 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
292 }
293 }
294
295 stream_failure:
296 return;
297 }
298
299 void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
300 {
301 afi_t afi = 0;
302 int type = 0;
303 u_short instance;
304
305 STREAM_GETC(msg, afi);
306 STREAM_GETC(msg, type);
307 STREAM_GETW(msg, instance);
308
309 if (afi == 0 || afi > AFI_MAX) {
310 zlog_warn("%s: Specified afi %d does not exist",
311 __PRETTY_FUNCTION__, afi);
312 return;
313 }
314
315 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
316 zlog_warn("%s: Specified Route Type %d does not exist",
317 __PRETTY_FUNCTION__, type);
318 return;
319 }
320
321 /*
322 * NOTE: no need to withdraw the previously advertised routes. The
323 * clients
324 * themselves should keep track of the received routes from zebra and
325 * withdraw them when necessary.
326 */
327 if (instance)
328 redist_del_instance(&client->mi_redist[afi][type], instance);
329 else
330 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
331
332 stream_failure:
333 return;
334 }
335
336 void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
337 {
338 vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
339 zebra_redistribute_default(client, zvrf_id(zvrf));
340 }
341
342 void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
343 {
344 vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
345 }
346
347 /* Interface up information. */
348 void zebra_interface_up_update(struct interface *ifp)
349 {
350 struct listnode *node, *nnode;
351 struct zserv *client;
352
353 if (IS_ZEBRA_DEBUG_EVENT)
354 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
355
356 if (ifp->ptm_status || !ifp->ptm_enable) {
357 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
358 if (client->ifinfo) {
359 zsend_interface_update(ZEBRA_INTERFACE_UP,
360 client, ifp);
361 zsend_interface_link_params(client, ifp);
362 }
363 }
364 }
365
366 /* Interface down information. */
367 void zebra_interface_down_update(struct interface *ifp)
368 {
369 struct listnode *node, *nnode;
370 struct zserv *client;
371
372 if (IS_ZEBRA_DEBUG_EVENT)
373 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
374
375 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
376 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
377 }
378 }
379
380 /* Interface information update. */
381 void zebra_interface_add_update(struct interface *ifp)
382 {
383 struct listnode *node, *nnode;
384 struct zserv *client;
385
386 if (IS_ZEBRA_DEBUG_EVENT)
387 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name,
388 ifp->vrf_id);
389
390 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
391 if (client->ifinfo) {
392 client->ifadd_cnt++;
393 zsend_interface_add(client, ifp);
394 zsend_interface_link_params(client, ifp);
395 }
396 }
397
398 void zebra_interface_delete_update(struct interface *ifp)
399 {
400 struct listnode *node, *nnode;
401 struct zserv *client;
402
403 if (IS_ZEBRA_DEBUG_EVENT)
404 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
405
406 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
407 client->ifdel_cnt++;
408 zsend_interface_delete(client, ifp);
409 }
410 }
411
412 /* Interface address addition. */
413 void zebra_interface_address_add_update(struct interface *ifp,
414 struct connected *ifc)
415 {
416 struct listnode *node, *nnode;
417 struct zserv *client;
418 struct prefix *p;
419
420 if (IS_ZEBRA_DEBUG_EVENT) {
421 char buf[PREFIX_STRLEN];
422
423 p = ifc->address;
424 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
425 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
426 }
427
428 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
429 zlog_warn(
430 "WARNING: advertising address to clients that is not yet usable.");
431
432 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
433
434 router_id_add_address(ifc);
435
436 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
437 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
438 client->connected_rt_add_cnt++;
439 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
440 client, ifp, ifc);
441 }
442 }
443
444 /* Interface address deletion. */
445 void zebra_interface_address_delete_update(struct interface *ifp,
446 struct connected *ifc)
447 {
448 struct listnode *node, *nnode;
449 struct zserv *client;
450 struct prefix *p;
451
452 if (IS_ZEBRA_DEBUG_EVENT) {
453 char buf[PREFIX_STRLEN];
454
455 p = ifc->address;
456 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
457 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
458 }
459
460 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
461
462 router_id_del_address(ifc);
463
464 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
465 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
466 client->connected_rt_del_cnt++;
467 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
468 client, ifp, ifc);
469 }
470 }
471
472 /* Interface VRF change. May need to delete from clients not interested in
473 * the new VRF. Note that this function is invoked *prior* to the VRF change.
474 */
475 void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
476 {
477 struct listnode *node, *nnode;
478 struct zserv *client;
479
480 if (IS_ZEBRA_DEBUG_EVENT)
481 zlog_debug(
482 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
483 ifp->name, ifp->vrf_id, new_vrf_id);
484
485 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
486 /* Need to delete if the client is not interested in the new
487 * VRF. */
488 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
489 client->ifdel_cnt++;
490 zsend_interface_delete(client, ifp);
491 zsend_interface_vrf_update(client, ifp, new_vrf_id);
492 }
493 }
494
495 /* Interface VRF change. This function is invoked *post* VRF change and sends an
496 * add to clients who are interested in the new VRF but not in the old VRF.
497 */
498 void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
499 {
500 struct listnode *node, *nnode;
501 struct zserv *client;
502
503 if (IS_ZEBRA_DEBUG_EVENT)
504 zlog_debug(
505 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
506 ifp->name, old_vrf_id, ifp->vrf_id);
507
508 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
509 /* Need to add if the client is interested in the new VRF. */
510 client->ifadd_cnt++;
511 zsend_interface_add(client, ifp);
512 zsend_interface_addresses(client, ifp);
513 }
514 }
515
516 int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
517 const char *rmap_name)
518 {
519 struct route_entry *newre;
520 struct route_entry *same;
521 struct prefix p;
522 route_map_result_t ret = RMAP_MATCH;
523 afi_t afi;
524
525 afi = family2afi(rn->p.family);
526 if (rmap_name)
527 ret = zebra_import_table_route_map_check(
528 afi, re->type, &rn->p, re->ng.nexthop, re->vrf_id,
529 re->tag, rmap_name);
530
531 if (ret != RMAP_MATCH) {
532 zebra_del_import_table_entry(rn, re);
533 return 0;
534 }
535
536 prefix_copy(&p, &rn->p);
537
538 RNODE_FOREACH_RE (rn, same) {
539 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
540 continue;
541
542 if (same->type == re->type && same->instance == re->instance
543 && same->table == re->table
544 && same->type != ZEBRA_ROUTE_CONNECT)
545 break;
546 }
547
548 if (same)
549 zebra_del_import_table_entry(rn, same);
550
551 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
552 newre->type = ZEBRA_ROUTE_TABLE;
553 newre->distance = zebra_import_table_distance[afi][re->table];
554 newre->flags = re->flags;
555 newre->metric = re->metric;
556 newre->mtu = re->mtu;
557 newre->table = zebrad.rtm_table_default;
558 newre->nexthop_num = 0;
559 newre->uptime = time(NULL);
560 newre->instance = re->table;
561 route_entry_copy_nexthops(newre, re->ng.nexthop);
562
563 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
564
565 return 0;
566 }
567
568 int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
569 {
570 struct prefix p;
571 afi_t afi;
572
573 afi = family2afi(rn->p.family);
574 prefix_copy(&p, &rn->p);
575
576 rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
577 re->flags, &p, NULL, re->ng.nexthop,
578 zebrad.rtm_table_default, re->metric, false, NULL);
579
580 return 0;
581 }
582
583 /* Assuming no one calls this with the main routing table */
584 int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance,
585 const char *rmap_name, int add)
586 {
587 struct route_table *table;
588 struct route_entry *re;
589 struct route_node *rn;
590
591 if (!is_zebra_valid_kernel_table(table_id)
592 || ((table_id == RT_TABLE_MAIN)
593 || (table_id == zebrad.rtm_table_default)))
594 return (-1);
595
596 if (afi >= AFI_MAX)
597 return (-1);
598
599 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
600 if (table == NULL) {
601 return 0;
602 } else if (IS_ZEBRA_DEBUG_RIB) {
603 zlog_debug("%s routes from table %d",
604 add ? "Importing" : "Unimporting", table_id);
605 }
606
607 if (add) {
608 if (rmap_name)
609 zebra_add_import_table_route_map(afi, rmap_name,
610 table_id);
611 else {
612 rmap_name =
613 zebra_get_import_table_route_map(afi, table_id);
614 if (rmap_name)
615 zebra_del_import_table_route_map(afi, table_id);
616 }
617
618 zebra_import_table_used[afi][table_id] = 1;
619 zebra_import_table_distance[afi][table_id] = distance;
620 } else {
621 zebra_import_table_used[afi][table_id] = 0;
622 zebra_import_table_distance[afi][table_id] =
623 ZEBRA_TABLE_DISTANCE_DEFAULT;
624
625 rmap_name = zebra_get_import_table_route_map(afi, table_id);
626 if (rmap_name)
627 zebra_del_import_table_route_map(afi, table_id);
628 }
629
630 for (rn = route_top(table); rn; rn = route_next(rn)) {
631 /* For each entry in the non-default routing table,
632 * add the entry in the main table
633 */
634 if (!rn->info)
635 continue;
636
637 RNODE_FOREACH_RE (rn, re) {
638 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
639 continue;
640 break;
641 }
642
643 if (!re)
644 continue;
645
646 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
647 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
648 if (add)
649 zebra_add_import_table_entry(rn, re, rmap_name);
650 else
651 zebra_del_import_table_entry(rn, re);
652 }
653 }
654 return 0;
655 }
656
657 int zebra_import_table_config(struct vty *vty)
658 {
659 int i;
660 afi_t afi;
661 int write = 0;
662 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
663 const char *rmap_name;
664
665 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
666 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
667 if (!is_zebra_import_table_enabled(afi, i))
668 continue;
669
670 if (zebra_import_table_distance[afi][i]
671 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
672 vty_out(vty, "%s import-table %d distance %d",
673 afi_str[afi], i,
674 zebra_import_table_distance[afi][i]);
675 } else {
676 vty_out(vty, "%s import-table %d", afi_str[afi],
677 i);
678 }
679
680 rmap_name = zebra_get_import_table_route_map(afi, i);
681 if (rmap_name)
682 vty_out(vty, " route-map %s", rmap_name);
683
684 vty_out(vty, "\n");
685 write = 1;
686 }
687 }
688
689 return write;
690 }
691
692 void zebra_import_table_rm_update()
693 {
694 afi_t afi;
695 int i;
696 struct route_table *table;
697 struct route_entry *re;
698 struct route_node *rn;
699 const char *rmap_name;
700
701 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
702 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
703 if (!is_zebra_import_table_enabled(afi, i))
704 continue;
705
706 rmap_name = zebra_get_import_table_route_map(afi, i);
707 if (!rmap_name)
708 return;
709
710 table = zebra_vrf_other_route_table(afi, i,
711 VRF_DEFAULT);
712 for (rn = route_top(table); rn; rn = route_next(rn)) {
713 /* For each entry in the non-default
714 * routing table,
715 * add the entry in the main table
716 */
717 if (!rn->info)
718 continue;
719
720 RNODE_FOREACH_RE (rn, re) {
721 if (CHECK_FLAG(re->status,
722 ROUTE_ENTRY_REMOVED))
723 continue;
724 break;
725 }
726
727 if (!re)
728 continue;
729
730 if (((afi == AFI_IP)
731 && (rn->p.family == AF_INET))
732 || ((afi == AFI_IP6)
733 && (rn->p.family == AF_INET6)))
734 zebra_add_import_table_entry(rn, re,
735 rmap_name);
736 }
737 }
738 }
739
740 return;
741 }
742
743 /* Interface parameters update */
744 void zebra_interface_parameters_update(struct interface *ifp)
745 {
746 struct listnode *node, *nnode;
747 struct zserv *client;
748
749 if (IS_ZEBRA_DEBUG_EVENT)
750 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s",
751 ifp->name);
752
753 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
754 if (client->ifinfo)
755 zsend_interface_link_params(client, ifp);
756 }