]> git.proxmox.com Git - mirror_frr.git/blob - zebra/redistribute.c
Merge pull request #2595 from pguibert6WIND/fix_netlink_rx_route_vrfnetns
[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/zapi_msg.h"
44 #include "zebra/zebra_memory.h"
45 #include "zebra/zebra_vxlan.h"
46
47 #define ZEBRA_PTM_SUPPORT
48
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];
53
54 int is_zebra_import_table_enabled(afi_t afi, uint32_t table_id)
55 {
56 /*
57 * Make sure that what we are called with actualy makes sense
58 */
59 if (afi == AFI_MAX)
60 return 0;
61
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];
65 return 0;
66 }
67
68 static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
69 {
70 int afi;
71 struct prefix p;
72 struct route_table *table;
73 struct route_node *rn;
74 struct route_entry *newre;
75
76 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
77 /* Lookup table. */
78 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
79 if (!table)
80 continue;
81
82 /* Lookup default route. */
83 memset(&p, 0, sizeof(p));
84 p.family = afi2family(afi);
85 rn = route_node_lookup(table, &p);
86 if (!rn)
87 continue;
88
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,
94 &rn->p, NULL, newre);
95 }
96
97 route_unlock_node(rn);
98 }
99 }
100
101 /* Redistribute routes. */
102 static void zebra_redistribute(struct zserv *client, int type,
103 unsigned short instance, vrf_id_t vrf_id,
104 int afi)
105 {
106 struct route_entry *newre;
107 struct route_table *table;
108 struct route_node *rn;
109
110 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
111 if (!table)
112 return;
113
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];
118
119 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
120
121 if (IS_ZEBRA_DEBUG_EVENT)
122 zlog_debug(
123 "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
124 __func__,
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));
131
132 if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
133 continue;
134 if ((type != ZEBRA_ROUTE_ALL
135 && (newre->type != type
136 || newre->instance != instance)))
137 continue;
138 if (newre->distance == DISTANCE_INFINITY)
139 continue;
140 if (!zebra_check_addr(dst_p))
141 continue;
142
143 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
144 client, dst_p, src_p, newre);
145 }
146 }
147
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)
152 {
153 struct listnode *node, *nnode;
154 struct zserv *client;
155 int send_redistribute;
156 int afi;
157 char buf[PREFIX_STRLEN];
158
159 if (IS_ZEBRA_DEBUG_RIB) {
160 zlog_debug(
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);
165 }
166
167 afi = family2afi(p->family);
168 if (!afi) {
169 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
170 __FUNCTION__);
171 return;
172 }
173
174 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
175 send_redistribute = 0;
176
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],
181 re->vrf_id))
182 send_redistribute = 1;
183 else if (re->instance
184 && redist_check_instance(
185 &client->mi_redist[afi][re->type],
186 re->instance))
187 send_redistribute = 1;
188 else if (vrf_bitmap_check(client->redist[afi][re->type],
189 re->vrf_id))
190 send_redistribute = 1;
191
192 if (send_redistribute) {
193 if (IS_ZEBRA_DEBUG_EVENT) {
194 zlog_debug(
195 "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
196 __func__,
197 zebra_route_string(client->proto),
198 prefix2str(p, buf, sizeof(buf)),
199 re->vrf_id, re->type,
200 re->distance, re->metric);
201 }
202 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
203 client, p, src_p, re);
204 } else if (prev_re
205 && ((re->instance
206 && redist_check_instance(
207 &client->mi_redist[afi]
208 [prev_re->type],
209 re->instance))
210 || vrf_bitmap_check(
211 client->redist[afi][prev_re->type],
212 re->vrf_id))) {
213 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
214 client, p, src_p, prev_re);
215 }
216 }
217 }
218
219 void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
220 struct route_entry *re)
221 {
222 struct listnode *node, *nnode;
223 struct zserv *client;
224 char buf[INET6_ADDRSTRLEN];
225 int afi;
226
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);
231 }
232
233 /* Add DISTANCE_INFINITY check. */
234 if (re->distance == DISTANCE_INFINITY)
235 return;
236
237 afi = family2afi(p->family);
238 if (!afi) {
239 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
240 __FUNCTION__);
241 return;
242 }
243
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],
248 re->vrf_id)
249 || (re->instance
250 && redist_check_instance(
251 &client->mi_redist[afi][re->type],
252 re->instance))
253 || vrf_bitmap_check(client->redist[afi][re->type],
254 re->vrf_id)) {
255 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
256 client, p, src_p, re);
257 }
258 }
259 }
260
261 void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
262 {
263 afi_t afi = 0;
264 int type = 0;
265 unsigned short instance;
266
267 STREAM_GETC(msg, afi);
268 STREAM_GETC(msg, type);
269 STREAM_GETW(msg, instance);
270
271 if (IS_ZEBRA_DEBUG_EVENT)
272 zlog_debug(
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);
276
277 if (afi == 0 || afi >= AFI_MAX) {
278 zlog_warn("%s: Specified afi %d does not exist",
279 __PRETTY_FUNCTION__, afi);
280 return;
281 }
282
283 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
284 zlog_warn("%s: Specified Route Type %d does not exist",
285 __PRETTY_FUNCTION__, type);
286 return;
287 }
288
289 if (instance) {
290 if (!redist_check_instance(&client->mi_redist[afi][type],
291 instance)) {
292 redist_add_instance(&client->mi_redist[afi][type],
293 instance);
294 zebra_redistribute(client, type, instance,
295 zvrf_id(zvrf), afi);
296 }
297 } else {
298 if (!vrf_bitmap_check(client->redist[afi][type],
299 zvrf_id(zvrf))) {
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],
304 zvrf_id(zvrf));
305 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
306 }
307 }
308
309 stream_failure:
310 return;
311 }
312
313 void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
314 {
315 afi_t afi = 0;
316 int type = 0;
317 unsigned short instance;
318
319 STREAM_GETC(msg, afi);
320 STREAM_GETC(msg, type);
321 STREAM_GETW(msg, instance);
322
323 if (afi == 0 || afi >= AFI_MAX) {
324 zlog_warn("%s: Specified afi %d does not exist",
325 __PRETTY_FUNCTION__, afi);
326 return;
327 }
328
329 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
330 zlog_warn("%s: Specified Route Type %d does not exist",
331 __PRETTY_FUNCTION__, type);
332 return;
333 }
334
335 /*
336 * NOTE: no need to withdraw the previously advertised routes. The
337 * clients
338 * themselves should keep track of the received routes from zebra and
339 * withdraw them when necessary.
340 */
341 if (instance)
342 redist_del_instance(&client->mi_redist[afi][type], instance);
343 else
344 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
345
346 stream_failure:
347 return;
348 }
349
350 void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
351 {
352 vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
353 zebra_redistribute_default(client, zvrf_id(zvrf));
354 }
355
356 void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
357 {
358 vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
359 }
360
361 /* Interface up information. */
362 void zebra_interface_up_update(struct interface *ifp)
363 {
364 struct listnode *node, *nnode;
365 struct zserv *client;
366
367 if (IS_ZEBRA_DEBUG_EVENT)
368 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
369 ifp->name, ifp->vrf_id);
370
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,
375 client, ifp);
376 zsend_interface_link_params(client, ifp);
377 }
378 }
379 }
380
381 /* Interface down information. */
382 void zebra_interface_down_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_DOWN %s(%u)",
389 ifp->name, ifp->vrf_id);
390
391 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
392 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
393 }
394 }
395
396 /* Interface information update. */
397 void zebra_interface_add_update(struct interface *ifp)
398 {
399 struct listnode *node, *nnode;
400 struct zserv *client;
401
402 if (IS_ZEBRA_DEBUG_EVENT)
403 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
404 ifp->vrf_id);
405
406 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
407 if (client->ifinfo) {
408 client->ifadd_cnt++;
409 zsend_interface_add(client, ifp);
410 zsend_interface_link_params(client, ifp);
411 }
412 }
413
414 void zebra_interface_delete_update(struct interface *ifp)
415 {
416 struct listnode *node, *nnode;
417 struct zserv *client;
418
419 if (IS_ZEBRA_DEBUG_EVENT)
420 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
421 ifp->name, ifp->vrf_id);
422
423 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
424 client->ifdel_cnt++;
425 zsend_interface_delete(client, ifp);
426 }
427 }
428
429 /* Interface address addition. */
430 void zebra_interface_address_add_update(struct interface *ifp,
431 struct connected *ifc)
432 {
433 struct listnode *node, *nnode;
434 struct zserv *client;
435 struct prefix *p;
436
437 if (IS_ZEBRA_DEBUG_EVENT) {
438 char buf[PREFIX_STRLEN];
439
440 p = ifc->address;
441 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
442 prefix2str(p, buf, sizeof(buf)), ifp->name,
443 ifp->vrf_id);
444 }
445
446 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
447 zlog_warn(
448 "WARNING: advertising address to clients that is not yet usable.");
449
450 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
451
452 router_id_add_address(ifc);
453
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,
458 client, ifp, ifc);
459 }
460 }
461
462 /* Interface address deletion. */
463 void zebra_interface_address_delete_update(struct interface *ifp,
464 struct connected *ifc)
465 {
466 struct listnode *node, *nnode;
467 struct zserv *client;
468 struct prefix *p;
469
470 if (IS_ZEBRA_DEBUG_EVENT) {
471 char buf[PREFIX_STRLEN];
472
473 p = ifc->address;
474 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
475 prefix2str(p, buf, sizeof(buf)),
476 ifp->name, ifp->vrf_id);
477 }
478
479 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
480
481 router_id_del_address(ifc);
482
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,
487 client, ifp, ifc);
488 }
489 }
490
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.
493 */
494 void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
495 {
496 struct listnode *node, *nnode;
497 struct zserv *client;
498
499 if (IS_ZEBRA_DEBUG_EVENT)
500 zlog_debug(
501 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
502 ifp->name, ifp->vrf_id, new_vrf_id);
503
504 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
505 /* Need to delete if the client is not interested in the new
506 * VRF. */
507 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
508 client->ifdel_cnt++;
509 zsend_interface_delete(client, ifp);
510 zsend_interface_vrf_update(client, ifp, new_vrf_id);
511 }
512 }
513
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.
516 */
517 void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
518 {
519 struct listnode *node, *nnode;
520 struct zserv *client;
521
522 if (IS_ZEBRA_DEBUG_EVENT)
523 zlog_debug(
524 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
525 ifp->name, old_vrf_id, ifp->vrf_id);
526
527 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
528 /* Need to add if the client is interested in the new VRF. */
529 client->ifadd_cnt++;
530 zsend_interface_add(client, ifp);
531 zsend_interface_addresses(client, ifp);
532 }
533 }
534
535 int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
536 const char *rmap_name)
537 {
538 struct route_entry *newre;
539 struct route_entry *same;
540 struct prefix p;
541 route_map_result_t ret = RMAP_MATCH;
542 afi_t afi;
543
544 afi = family2afi(rn->p.family);
545 if (rmap_name)
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);
549
550 if (ret != RMAP_MATCH) {
551 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
552 zebra_del_import_table_entry(rn, re);
553 return 0;
554 }
555
556 prefix_copy(&p, &rn->p);
557
558 RNODE_FOREACH_RE (rn, same) {
559 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
560 continue;
561
562 if (same->type == re->type && same->instance == re->instance
563 && same->table == re->table
564 && same->type != ZEBRA_ROUTE_CONNECT)
565 break;
566 }
567
568 if (same) {
569 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
570 zebra_del_import_table_entry(rn, same);
571 }
572
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);
584
585 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre);
586
587 return 0;
588 }
589
590 int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
591 {
592 struct prefix p;
593 afi_t afi;
594
595 afi = family2afi(rn->p.family);
596 prefix_copy(&p, &rn->p);
597
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);
601
602 return 0;
603 }
604
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)
608 {
609 struct route_table *table;
610 struct route_entry *re;
611 struct route_node *rn;
612
613 if (!is_zebra_valid_kernel_table(table_id)
614 || ((table_id == RT_TABLE_MAIN)
615 || (table_id == zebrad.rtm_table_default)))
616 return (-1);
617
618 if (afi >= AFI_MAX)
619 return (-1);
620
621 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
622 if (table == NULL) {
623 return 0;
624 } else if (IS_ZEBRA_DEBUG_RIB) {
625 zlog_debug("%s routes from table %d",
626 add ? "Importing" : "Unimporting", table_id);
627 }
628
629 if (add) {
630 if (rmap_name)
631 zebra_add_import_table_route_map(afi, rmap_name,
632 table_id);
633 else {
634 rmap_name =
635 zebra_get_import_table_route_map(afi, table_id);
636 if (rmap_name) {
637 zebra_del_import_table_route_map(afi, table_id);
638 rmap_name = NULL;
639 }
640 }
641
642 zebra_import_table_used[afi][table_id] = 1;
643 zebra_import_table_distance[afi][table_id] = distance;
644 } else {
645 zebra_import_table_used[afi][table_id] = 0;
646 zebra_import_table_distance[afi][table_id] =
647 ZEBRA_TABLE_DISTANCE_DEFAULT;
648
649 rmap_name = zebra_get_import_table_route_map(afi, table_id);
650 if (rmap_name) {
651 zebra_del_import_table_route_map(afi, table_id);
652 rmap_name = NULL;
653 }
654 }
655
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
659 */
660 if (!rn->info)
661 continue;
662
663 RNODE_FOREACH_RE (rn, re) {
664 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
665 continue;
666 break;
667 }
668
669 if (!re)
670 continue;
671
672 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
673 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
674 if (add)
675 zebra_add_import_table_entry(rn, re, rmap_name);
676 else
677 zebra_del_import_table_entry(rn, re);
678 }
679 }
680 return 0;
681 }
682
683 int zebra_import_table_config(struct vty *vty)
684 {
685 int i;
686 afi_t afi;
687 int write = 0;
688 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
689 const char *rmap_name;
690
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))
694 continue;
695
696 if (zebra_import_table_distance[afi][i]
697 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
698 vty_out(vty, "%s import-table %d distance %d",
699 afi_str[afi], i,
700 zebra_import_table_distance[afi][i]);
701 } else {
702 vty_out(vty, "%s import-table %d", afi_str[afi],
703 i);
704 }
705
706 rmap_name = zebra_get_import_table_route_map(afi, i);
707 if (rmap_name)
708 vty_out(vty, " route-map %s", rmap_name);
709
710 vty_out(vty, "\n");
711 write = 1;
712 }
713 }
714
715 return write;
716 }
717
718 void zebra_import_table_rm_update()
719 {
720 afi_t afi;
721 int i;
722 struct route_table *table;
723 struct route_entry *re;
724 struct route_node *rn;
725 const char *rmap_name;
726
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))
730 continue;
731
732 rmap_name = zebra_get_import_table_route_map(afi, i);
733 if (!rmap_name)
734 return;
735
736 table = zebra_vrf_other_route_table(afi, i,
737 VRF_DEFAULT);
738 for (rn = route_top(table); rn; rn = route_next(rn)) {
739 /* For each entry in the non-default
740 * routing table,
741 * add the entry in the main table
742 */
743 if (!rn->info)
744 continue;
745
746 RNODE_FOREACH_RE (rn, re) {
747 if (CHECK_FLAG(re->status,
748 ROUTE_ENTRY_REMOVED))
749 continue;
750 break;
751 }
752
753 if (!re)
754 continue;
755
756 if (((afi == AFI_IP)
757 && (rn->p.family == AF_INET))
758 || ((afi == AFI_IP6)
759 && (rn->p.family == AF_INET6)))
760 zebra_add_import_table_entry(rn, re,
761 rmap_name);
762 }
763 }
764 }
765
766 return;
767 }
768
769 /* Interface parameters update */
770 void zebra_interface_parameters_update(struct interface *ifp)
771 {
772 struct listnode *node, *nnode;
773 struct zserv *client;
774
775 if (IS_ZEBRA_DEBUG_EVENT)
776 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
777 ifp->name, ifp->vrf_id);
778
779 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
780 if (client->ifinfo)
781 zsend_interface_link_params(client, ifp);
782 }