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