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