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