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