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