]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
Merge pull request #6920 from opensourcerouting/nb-errors-apply-phase
[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"
161e9ab7 36#include "zebra/zebra_router.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
fe257ae7 55int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, 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++) {
29a35332
DS
78
79 if (!vrf_bitmap_check(client->redist_default[afi], vrf_id))
80 continue;
81
d62a17ae 82 /* Lookup table. */
83 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
84 if (!table)
85 continue;
86
87 /* Lookup default route. */
88 memset(&p, 0, sizeof(p));
89 p.family = afi2family(afi);
90 rn = route_node_lookup(table, &p);
91 if (!rn)
92 continue;
93
a2addae8 94 RNODE_FOREACH_RE (rn, newre) {
407c87a6
DS
95 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
96 && newre->distance != DISTANCE_INFINITY)
97 zsend_redistribute_route(
a2addae8
RW
98 ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
99 &rn->p, NULL, newre);
407c87a6 100 }
d62a17ae 101
102 route_unlock_node(rn);
103 }
718e3744 104}
105
106/* Redistribute routes. */
d7c0a89a
QY
107static void zebra_redistribute(struct zserv *client, int type,
108 unsigned short instance, vrf_id_t vrf_id,
109 int afi)
718e3744 110{
d62a17ae 111 struct route_entry *newre;
112 struct route_table *table;
113 struct route_node *rn;
114
115 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
116 if (!table)
117 return;
118
f0c4b8e1 119 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
a2addae8 120 RNODE_FOREACH_RE (rn, newre) {
86391e56 121 const struct prefix *dst_p, *src_p;
3e178809
DS
122 char buf[PREFIX_STRLEN];
123
d62a17ae 124 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
125
14a4d9d0 126 if (IS_ZEBRA_DEBUG_RIB)
d62a17ae 127 zlog_debug(
38bbad1b 128 "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
d62a17ae 129 __func__,
1b6e575b 130 zebra_route_string(client->proto),
3e178809 131 prefix2str(dst_p, buf, sizeof(buf)),
1b6e575b
PZ
132 vrf_id, CHECK_FLAG(newre->flags,
133 ZEBRA_FLAG_SELECTED),
d62a17ae 134 newre->type, newre->distance,
3e178809 135 newre->metric, zebra_check_addr(dst_p));
d62a17ae 136
137 if (!CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
138 continue;
139 if ((type != ZEBRA_ROUTE_ALL
140 && (newre->type != type
141 || newre->instance != instance)))
142 continue;
143 if (newre->distance == DISTANCE_INFINITY)
144 continue;
145 if (!zebra_check_addr(dst_p))
146 continue;
147
74489921
RW
148 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
149 client, dst_p, src_p, newre);
d62a17ae 150 }
718e3744 151}
152
14fe366e
S
153/*
154 * Function to check if prefix is candidate for
155 * redistribute.
156 */
157static bool zebra_redistribute_check(const struct route_entry *re,
158 struct zserv *client,
159 const struct prefix *p, int afi)
160{
161 /* Process only if there is valid re */
162 if (!re)
163 return false;
164
165 /* If default route and redistributed */
166 if (is_default_prefix(p)
167 && vrf_bitmap_check(client->redist_default[afi], re->vrf_id))
168 return true;
169
170 /* If redistribute in enabled for zebra route all */
171 if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], re->vrf_id))
172 return true;
173
174 /*
175 * If multi-instance then check for route
176 * redistribution for given instance.
177 */
178 if (re->instance
179 && redist_check_instance(&client->mi_redist[afi][re->type],
180 re->instance))
181 return true;
182
183 /* If redistribution is enabled for give route type. */
184 if (vrf_bitmap_check(client->redist[afi][re->type], re->vrf_id))
185 return true;
186
187 return false;
188}
189
c41fc67b 190/* Either advertise a route for redistribution to registered clients or */
191/* withdraw redistribution if add cannot be done for client */
86391e56 192void redistribute_update(const struct prefix *p, const struct prefix *src_p,
40f321c0
MS
193 const struct route_entry *re,
194 const struct route_entry *prev_re)
718e3744 195{
d62a17ae 196 struct listnode *node, *nnode;
197 struct zserv *client;
d62a17ae 198 int afi;
3e178809 199 char buf[PREFIX_STRLEN];
d62a17ae 200
201 if (IS_ZEBRA_DEBUG_RIB) {
d62a17ae 202 zlog_debug(
2da33d6b 203 "%u:%s: Redist update re %p (%s), old %p (%s)",
3e178809 204 re->vrf_id, prefix2str(p, buf, sizeof(buf)),
2da33d6b
DS
205 re, zebra_route_string(re->type), prev_re,
206 prev_re ? zebra_route_string(prev_re->type) : "None");
d62a17ae 207 }
208
209 afi = family2afi(p->family);
210 if (!afi) {
e914ccbe 211 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
0767b4f3 212 "%s: Unknown AFI/SAFI prefix received\n", __func__);
d62a17ae 213 return;
c41fc67b 214 }
79becec8 215 if (!zebra_check_addr(p)) {
216 if (IS_ZEBRA_DEBUG_RIB)
217 zlog_debug("Redist update filter prefix %s",
218 prefix2str(p, buf, sizeof(buf)));
219 return;
220 }
221
d62a17ae 222
161e9ab7 223 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
14fe366e 224 if (zebra_redistribute_check(re, client, p, afi)) {
14a4d9d0 225 if (IS_ZEBRA_DEBUG_RIB) {
3e178809 226 zlog_debug(
38bbad1b 227 "%s: client %s %s(%u), type=%d, distance=%d, metric=%d",
3e178809
DS
228 __func__,
229 zebra_route_string(client->proto),
230 prefix2str(p, buf, sizeof(buf)),
231 re->vrf_id, re->type,
232 re->distance, re->metric);
233 }
74489921
RW
234 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
235 client, p, src_p, re);
14fe366e 236 } else if (zebra_redistribute_check(prev_re, client, p, afi))
74489921
RW
237 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
238 client, p, src_p, prev_re);
c41fc67b 239 }
718e3744 240}
241
40f321c0
MS
242/*
243 * During a route delete, where 'new_re' is NULL, redist a delete to all
244 * clients registered for the type of 'old_re'.
245 * During a route update, redist a delete to any clients who will not see
246 * an update when the new route is installed. There are cases when a client
247 * may have seen a redist for 'old_re', but will not see
248 * the redist for 'new_re'.
249 */
86391e56 250void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
40f321c0
MS
251 const struct route_entry *old_re,
252 const struct route_entry *new_re)
718e3744 253{
d62a17ae 254 struct listnode *node, *nnode;
255 struct zserv *client;
d62a17ae 256 int afi;
40f321c0
MS
257 char buf[PREFIX_STRLEN];
258 vrf_id_t vrfid;
259
260 if (old_re)
261 vrfid = old_re->vrf_id;
262 else if (new_re)
263 vrfid = new_re->vrf_id;
264 else
265 return;
d62a17ae 266
267 if (IS_ZEBRA_DEBUG_RIB) {
40f321c0
MS
268 zlog_debug(
269 "%u:%s: Redist del: re %p (%s), new re %p (%s)",
270 vrfid, prefix2str(p, buf, sizeof(buf)),
271 old_re,
272 old_re ? zebra_route_string(old_re->type) : "None",
273 new_re,
274 new_re ? zebra_route_string(new_re->type) : "None");
d62a17ae 275 }
276
277 /* Add DISTANCE_INFINITY check. */
0e965c67
DS
278 if (old_re && (old_re->distance == DISTANCE_INFINITY)) {
279 if (IS_ZEBRA_DEBUG_RIB)
d6951e5e 280 zlog_debug(" Skipping due to Infinite Distance");
d62a17ae 281 return;
0e965c67 282 }
d62a17ae 283
284 afi = family2afi(p->family);
285 if (!afi) {
e914ccbe 286 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
9df414fe 287 "%s: Unknown AFI/SAFI prefix received\n",
40f321c0 288 __func__);
d62a17ae 289 return;
290 }
291
40f321c0 292 /* Skip invalid (e.g. linklocal) prefix */
79becec8 293 if (!zebra_check_addr(p)) {
40f321c0
MS
294 if (IS_ZEBRA_DEBUG_RIB) {
295 zlog_debug(
296 "%u:%s: Redist del old: skipping invalid prefix",
297 vrfid, prefix2str(p, buf, sizeof(buf)));
298 }
79becec8 299 return;
300 }
301
161e9ab7 302 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
303 /* Do not send unsolicited messages to synchronous clients. */
304 if (client->synchronous)
305 continue;
14fe366e
S
306 /*
307 * Skip this client if it will receive an update for the
308 * 'new' re
309 */
310 if (zebra_redistribute_check(new_re, client, p, afi))
311 continue;
40f321c0
MS
312
313 /* Send a delete for the 'old' re to any subscribed client. */
14fe366e 314 if (zebra_redistribute_check(old_re, client, p, afi))
74489921 315 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
40f321c0 316 client, p, src_p, old_re);
1eb8ef25 317 }
718e3744 318}
319
14fe366e 320
89f4e507 321void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
718e3744 322{
ec93aa12
DS
323 afi_t afi = 0;
324 int type = 0;
d7c0a89a 325 unsigned short instance;
d62a17ae 326
1002497a
QY
327 STREAM_GETC(msg, afi);
328 STREAM_GETC(msg, type);
329 STREAM_GETW(msg, instance);
d62a17ae 330
1b6e575b
PZ
331 if (IS_ZEBRA_DEBUG_EVENT)
332 zlog_debug(
c479e756 333 "%s: client proto %s afi=%d, wants %s, vrf %s(%u), instance=%d",
1b6e575b 334 __func__, zebra_route_string(client->proto), afi,
c479e756
DS
335 zebra_route_string(type), VRF_LOGNAME(zvrf->vrf),
336 zvrf_id(zvrf), instance);
1b6e575b 337
e1fa928d 338 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 339 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 340 "%s: Specified afi %d does not exist", __func__, afi);
d62a17ae 341 return;
ec93aa12
DS
342 }
343
344 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe 345 zlog_debug("%s: Specified Route Type %d does not exist",
15569c58 346 __func__, type);
ec93aa12
DS
347 return;
348 }
d62a17ae 349
350 if (instance) {
351 if (!redist_check_instance(&client->mi_redist[afi][type],
352 instance)) {
353 redist_add_instance(&client->mi_redist[afi][type],
354 instance);
355 zebra_redistribute(client, type, instance,
356 zvrf_id(zvrf), afi);
357 }
358 } else {
359 if (!vrf_bitmap_check(client->redist[afi][type],
360 zvrf_id(zvrf))) {
1b6e575b 361 if (IS_ZEBRA_DEBUG_EVENT)
c479e756
DS
362 zlog_debug(
363 "%s: setting vrf %s(%u) redist bitmap",
364 __func__, VRF_LOGNAME(zvrf->vrf),
365 zvrf_id(zvrf));
d62a17ae 366 vrf_bitmap_set(client->redist[afi][type],
367 zvrf_id(zvrf));
368 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
369 }
4e1cadf0 370 }
ec93aa12
DS
371
372stream_failure:
373 return;
ebf08631 374}
718e3744 375
89f4e507 376void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
718e3744 377{
ec93aa12
DS
378 afi_t afi = 0;
379 int type = 0;
d7c0a89a 380 unsigned short instance;
d62a17ae 381
1002497a
QY
382 STREAM_GETC(msg, afi);
383 STREAM_GETC(msg, type);
384 STREAM_GETW(msg, instance);
d62a17ae 385
e1fa928d 386 if (afi == 0 || afi >= AFI_MAX) {
e914ccbe 387 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 388 "%s: Specified afi %d does not exist", __func__, afi);
d62a17ae 389 return;
ec93aa12
DS
390 }
391
392 if (type == 0 || type >= ZEBRA_ROUTE_MAX) {
9df414fe 393 zlog_debug("%s: Specified Route Type %d does not exist",
15569c58 394 __func__, type);
ec93aa12
DS
395 return;
396 }
d62a17ae 397
398 /*
399 * NOTE: no need to withdraw the previously advertised routes. The
400 * clients
401 * themselves should keep track of the received routes from zebra and
402 * withdraw them when necessary.
403 */
404 if (instance)
405 redist_del_instance(&client->mi_redist[afi][type], instance);
406 else
407 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
ec93aa12
DS
408
409stream_failure:
410 return;
ebf08631 411}
718e3744 412
89f4e507 413void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
718e3744 414{
49db7a7b
RW
415 afi_t afi = 0;
416
417 STREAM_GETC(msg, afi);
418
419 if (afi == 0 || afi >= AFI_MAX) {
420 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 421 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
422 return;
423 }
424
425 vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
d62a17ae 426 zebra_redistribute_default(client, zvrf_id(zvrf));
49db7a7b
RW
427
428stream_failure:
429 return;
d62a17ae 430}
718e3744 431
89f4e507 432void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
718e3744 433{
49db7a7b
RW
434 afi_t afi = 0;
435
436 STREAM_GETC(msg, afi);
437
438 if (afi == 0 || afi >= AFI_MAX) {
439 flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
15569c58 440 "%s: Specified afi %u does not exist", __func__, afi);
49db7a7b
RW
441 return;
442 }
443
444 vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
445
446stream_failure:
447 return;
d62a17ae 448}
718e3744 449
450/* Interface up information. */
d62a17ae 451void zebra_interface_up_update(struct interface *ifp)
718e3744 452{
d62a17ae 453 struct listnode *node, *nnode;
454 struct zserv *client;
455
456 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 457 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s(%u)",
a36898e7 458 ifp->name, ifp->vrf_id);
d62a17ae 459
460 if (ifp->ptm_status || !ifp->ptm_enable) {
161e9ab7 461 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode,
a8a20c4e 462 client)) {
17da84a4
KS
463 /* Do not send unsolicited messages to synchronous
464 * clients.
465 */
466 if (client->synchronous)
467 continue;
468
a8a20c4e
DS
469 zsend_interface_update(ZEBRA_INTERFACE_UP,
470 client, ifp);
471 zsend_interface_link_params(client, ifp);
472 }
16f1b9ee 473 }
718e3744 474}
475
476/* Interface down information. */
d62a17ae 477void zebra_interface_down_update(struct interface *ifp)
718e3744 478{
d62a17ae 479 struct listnode *node, *nnode;
480 struct zserv *client;
718e3744 481
d62a17ae 482 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 483 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)",
a36898e7 484 ifp->name, ifp->vrf_id);
718e3744 485
161e9ab7 486 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
487 /* Do not send unsolicited messages to synchronous clients. */
488 if (client->synchronous)
489 continue;
490
d62a17ae 491 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
492 }
718e3744 493}
494
495/* Interface information update. */
d62a17ae 496void zebra_interface_add_update(struct interface *ifp)
718e3744 497{
d62a17ae 498 struct listnode *node, *nnode;
499 struct zserv *client;
500
501 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 502 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name,
a36898e7 503 ifp->vrf_id);
d62a17ae 504
a8a20c4e 505 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
506 /* Do not send unsolicited messages to synchronous clients. */
507 if (client->synchronous)
508 continue;
509
a8a20c4e
DS
510 client->ifadd_cnt++;
511 zsend_interface_add(client, ifp);
512 zsend_interface_link_params(client, ifp);
513 }
718e3744 514}
515
d62a17ae 516void zebra_interface_delete_update(struct interface *ifp)
718e3744 517{
d62a17ae 518 struct listnode *node, *nnode;
519 struct zserv *client;
718e3744 520
d62a17ae 521 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 522 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)",
a36898e7 523 ifp->name, ifp->vrf_id);
718e3744 524
161e9ab7 525 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
526 /* Do not send unsolicited messages to synchronous clients. */
527 if (client->synchronous)
528 continue;
529
d62a17ae 530 client->ifdel_cnt++;
531 zsend_interface_delete(client, ifp);
532 }
718e3744 533}
534
535/* Interface address addition. */
d62a17ae 536void zebra_interface_address_add_update(struct interface *ifp,
537 struct connected *ifc)
718e3744 538{
d62a17ae 539 struct listnode *node, *nnode;
540 struct zserv *client;
541 struct prefix *p;
542
543 if (IS_ZEBRA_DEBUG_EVENT) {
544 char buf[PREFIX_STRLEN];
545
546 p = ifc->address;
38bbad1b
DS
547 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
548 prefix2str(p, buf, sizeof(buf)), ifp->name,
a36898e7 549 ifp->vrf_id);
d62a17ae 550 }
551
552 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
9df414fe 553 flog_warn(
e914ccbe 554 EC_ZEBRA_ADVERTISING_UNUSABLE_ADDR,
d62a17ae 555 "WARNING: advertising address to clients that is not yet usable.");
556
1a98c087
MK
557 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
558
d62a17ae 559 router_id_add_address(ifc);
560
17da84a4
KS
561 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
562 /* Do not send unsolicited messages to synchronous clients. */
563 if (client->synchronous)
564 continue;
565
d62a17ae 566 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
567 client->connected_rt_add_cnt++;
568 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
569 client, ifp, ifc);
570 }
17da84a4 571 }
718e3744 572}
573
574/* Interface address deletion. */
d62a17ae 575void zebra_interface_address_delete_update(struct interface *ifp,
576 struct connected *ifc)
718e3744 577{
d62a17ae 578 struct listnode *node, *nnode;
579 struct zserv *client;
580 struct prefix *p;
581
582 if (IS_ZEBRA_DEBUG_EVENT) {
583 char buf[PREFIX_STRLEN];
584
585 p = ifc->address;
38bbad1b
DS
586 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
587 prefix2str(p, buf, sizeof(buf)),
a36898e7 588 ifp->name, ifp->vrf_id);
d62a17ae 589 }
590
1a98c087
MK
591 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
592
d62a17ae 593 router_id_del_address(ifc);
594
17da84a4
KS
595 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
596 /* Do not send unsolicited messages to synchronous clients. */
597 if (client->synchronous)
598 continue;
599
d62a17ae 600 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
601 client->connected_rt_del_cnt++;
602 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
603 client, ifp, ifc);
604 }
17da84a4 605 }
718e3744 606}
d5a5c8f0 607
c8e264b6 608/* Interface VRF change. May need to delete from clients not interested in
609 * the new VRF. Note that this function is invoked *prior* to the VRF change.
610 */
d62a17ae 611void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
c8e264b6 612{
d62a17ae 613 struct listnode *node, *nnode;
614 struct zserv *client;
615
616 if (IS_ZEBRA_DEBUG_EVENT)
617 zlog_debug(
618 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
a36898e7 619 ifp->name, ifp->vrf_id, new_vrf_id);
d62a17ae 620
161e9ab7 621 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
622 /* Do not send unsolicited messages to synchronous clients. */
623 if (client->synchronous)
624 continue;
625
d62a17ae 626 /* Need to delete if the client is not interested in the new
627 * VRF. */
628 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
629 client->ifdel_cnt++;
630 zsend_interface_delete(client, ifp);
631 zsend_interface_vrf_update(client, ifp, new_vrf_id);
632 }
c8e264b6 633}
634
635/* Interface VRF change. This function is invoked *post* VRF change and sends an
636 * add to clients who are interested in the new VRF but not in the old VRF.
637 */
d62a17ae 638void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
c8e264b6 639{
d62a17ae 640 struct listnode *node, *nnode;
641 struct zserv *client;
642
643 if (IS_ZEBRA_DEBUG_EVENT)
644 zlog_debug(
645 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
a36898e7 646 ifp->name, old_vrf_id, ifp->vrf_id);
d62a17ae 647
161e9ab7 648 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
17da84a4
KS
649 /* Do not send unsolicited messages to synchronous clients. */
650 if (client->synchronous)
651 continue;
652
d62a17ae 653 /* Need to add if the client is interested in the new VRF. */
654 client->ifadd_cnt++;
655 zsend_interface_add(client, ifp);
656 zsend_interface_addresses(client, ifp);
657 }
c8e264b6 658}
659
fe257ae7
DS
660int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
661 struct route_entry *re, const char *rmap_name)
7a4bb9c5 662{
d62a17ae 663 struct route_entry *newre;
664 struct route_entry *same;
665 struct prefix p;
0eb97b86 666 struct nexthop_group *ng;
b68885f9 667 route_map_result_t ret = RMAP_PERMITMATCH;
f8c175f3 668 afi_t afi;
d62a17ae 669
f8c175f3 670 afi = family2afi(rn->p.family);
d62a17ae 671 if (rmap_name)
672 ret = zebra_import_table_route_map_check(
0eb97b86 673 afi, re->type, re->instance, &rn->p,
c415d895 674 re->nhe->nhg.nexthop,
fe257ae7 675 zvrf->vrf->vrf_id, re->tag, rmap_name);
d62a17ae 676
b68885f9 677 if (ret != RMAP_PERMITMATCH) {
85c615ac 678 UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 679 zebra_del_import_table_entry(zvrf, rn, re);
20796bc3
DS
680 return 0;
681 }
d62a17ae 682
f8c175f3 683 prefix_copy(&p, &rn->p);
d62a17ae 684
a2addae8
RW
685 RNODE_FOREACH_RE (rn, same) {
686 if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
f8c175f3 687 continue;
20796bc3 688
996c9314 689 if (same->type == re->type && same->instance == re->instance
f8c175f3
DS
690 && same->table == re->table
691 && same->type != ZEBRA_ROUTE_CONNECT)
692 break;
693 }
20796bc3 694
e71c84ca
DS
695 if (same) {
696 UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED);
fe257ae7 697 zebra_del_import_table_entry(zvrf, rn, same);
e71c84ca 698 }
f8c175f3 699
996c9314 700 newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
5c4b6e57
DS
701 newre->type = ZEBRA_ROUTE_TABLE;
702 newre->distance = zebra_import_table_distance[afi][re->table];
703 newre->flags = re->flags;
704 newre->metric = re->metric;
705 newre->mtu = re->mtu;
317c6a10 706 newre->table = zvrf->table_id;
98572489 707 newre->uptime = monotime(NULL);
5c4b6e57 708 newre->instance = re->table;
5c4b6e57 709
0eb97b86 710 ng = nexthop_group_new();
c415d895 711 copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL);
0eb97b86
MS
712
713 rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng);
5c4b6e57 714
d62a17ae 715 return 0;
7a4bb9c5
DS
716}
717
fe257ae7
DS
718int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
719 struct route_entry *re)
7a4bb9c5 720{
d62a17ae 721 struct prefix p;
f8c175f3 722 afi_t afi;
7a4bb9c5 723
f8c175f3
DS
724 afi = family2afi(rn->p.family);
725 prefix_copy(&p, &rn->p);
7a4bb9c5 726
fe257ae7 727 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
c415d895 728 re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
0eb97b86
MS
729 re->nhe_id, zvrf->table_id, re->metric, re->distance,
730 false);
7a4bb9c5 731
d62a17ae 732 return 0;
7a4bb9c5
DS
733}
734
735/* Assuming no one calls this with the main routing table */
fe257ae7
DS
736int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id,
737 uint32_t distance, const char *rmap_name, int add)
7a4bb9c5 738{
d62a17ae 739 struct route_table *table;
740 struct route_entry *re;
741 struct route_node *rn;
fe257ae7 742 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id);
d62a17ae 743
744 if (!is_zebra_valid_kernel_table(table_id)
c447ad08 745 || (table_id == RT_TABLE_MAIN))
95f7965d 746 return -1;
d62a17ae 747
748 if (afi >= AFI_MAX)
95f7965d 749 return -1;
d62a17ae 750
c7c0b007
SW
751 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST, vrf_id,
752 table_id);
d62a17ae 753 if (table == NULL) {
754 return 0;
755 } else if (IS_ZEBRA_DEBUG_RIB) {
756 zlog_debug("%s routes from table %d",
757 add ? "Importing" : "Unimporting", table_id);
7a4bb9c5
DS
758 }
759
d62a17ae 760 if (add) {
761 if (rmap_name)
762 zebra_add_import_table_route_map(afi, rmap_name,
763 table_id);
764 else {
765 rmap_name =
766 zebra_get_import_table_route_map(afi, table_id);
3660beec 767 if (rmap_name) {
d62a17ae 768 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
769 rmap_name = NULL;
770 }
d62a17ae 771 }
7a4bb9c5 772
d62a17ae 773 zebra_import_table_used[afi][table_id] = 1;
774 zebra_import_table_distance[afi][table_id] = distance;
775 } else {
776 zebra_import_table_used[afi][table_id] = 0;
777 zebra_import_table_distance[afi][table_id] =
778 ZEBRA_TABLE_DISTANCE_DEFAULT;
779
780 rmap_name = zebra_get_import_table_route_map(afi, table_id);
3660beec 781 if (rmap_name) {
d62a17ae 782 zebra_del_import_table_route_map(afi, table_id);
3660beec
DS
783 rmap_name = NULL;
784 }
7a4bb9c5 785 }
7a4bb9c5 786
d62a17ae 787 for (rn = route_top(table); rn; rn = route_next(rn)) {
788 /* For each entry in the non-default routing table,
789 * add the entry in the main table
790 */
791 if (!rn->info)
792 continue;
793
a2addae8 794 RNODE_FOREACH_RE (rn, re) {
d62a17ae 795 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
796 continue;
797 break;
7a4bb9c5 798 }
8902474b 799
d62a17ae 800 if (!re)
801 continue;
8902474b 802
d62a17ae 803 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
804 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
805 if (add)
fe257ae7
DS
806 zebra_add_import_table_entry(zvrf, rn, re,
807 rmap_name);
d62a17ae 808 else
fe257ae7 809 zebra_del_import_table_entry(zvrf, rn, re);
d62a17ae 810 }
811 }
812 return 0;
813}
814
fe257ae7 815int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id)
d62a17ae 816{
817 int i;
818 afi_t afi;
819 int write = 0;
820 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
821 const char *rmap_name;
822
823 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
824 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
fe257ae7 825 if (!is_zebra_import_table_enabled(afi, vrf_id, i))
20796bc3 826 continue;
d62a17ae 827
20796bc3
DS
828 if (zebra_import_table_distance[afi][i]
829 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
996c9314 830 vty_out(vty, "%s import-table %d distance %d",
20796bc3
DS
831 afi_str[afi], i,
832 zebra_import_table_distance[afi][i]);
833 } else {
996c9314
LB
834 vty_out(vty, "%s import-table %d", afi_str[afi],
835 i);
d62a17ae 836 }
20796bc3
DS
837
838 rmap_name = zebra_get_import_table_route_map(afi, i);
839 if (rmap_name)
996c9314 840 vty_out(vty, " route-map %s", rmap_name);
20796bc3
DS
841
842 vty_out(vty, "\n");
843 write = 1;
d62a17ae 844 }
7a4bb9c5 845 }
7a4bb9c5 846
d62a17ae 847 return write;
7a4bb9c5 848}
8902474b 849
fe257ae7
DS
850static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf,
851 afi_t afi, int table_id,
852 const char *rmap)
8902474b 853{
d62a17ae 854 struct route_table *table;
855 struct route_entry *re;
856 struct route_node *rn;
857 const char *rmap_name;
858
fe257ae7
DS
859 rmap_name = zebra_get_import_table_route_map(afi, table_id);
860 if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0))
861 return;
d62a17ae 862
c7c0b007
SW
863 table = zebra_vrf_get_table_with_table_id(afi, SAFI_UNICAST,
864 zvrf->vrf->vrf_id, table_id);
fe257ae7
DS
865 if (!table) {
866 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
867 zlog_debug("%s: Table id=%d not found", __func__,
868 table_id);
869 return;
870 }
871
872 for (rn = route_top(table); rn; rn = route_next(rn)) {
873 /*
874 * For each entry in the non-default routing table,
875 * add the entry in the main table
876 */
877 if (!rn->info)
878 continue;
879
880 RNODE_FOREACH_RE (rn, re) {
881 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
d5b8c216 882 continue;
fe257ae7
DS
883 break;
884 }
885
886 if (!re)
887 continue;
888
889 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
890 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
891 zebra_add_import_table_entry(zvrf, rn, re, rmap_name);
892 }
893
894 return;
895}
896
897static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf,
898 const char *rmap)
899{
900 afi_t afi;
901 int i;
902
903 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
904 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
905 if (!is_zebra_import_table_enabled(
906 afi, zvrf->vrf->vrf_id, i))
2c7ef20d 907 continue;
2c7ef20d 908
fe257ae7
DS
909 zebra_import_table_rm_update_vrf_afi(zvrf, afi, i,
910 rmap);
d62a17ae 911 }
8902474b 912 }
fe257ae7 913}
8902474b 914
fe257ae7
DS
915void zebra_import_table_rm_update(const char *rmap)
916{
917 struct vrf *vrf;
918 struct zebra_vrf *zvrf;
919
920 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
921 zvrf = vrf->info;
922
923 if (!zvrf)
924 continue;
925
926 zebra_import_table_rm_update_vrf(zvrf, rmap);
927 }
8902474b 928}
16f1b9ee
OD
929
930/* Interface parameters update */
d62a17ae 931void zebra_interface_parameters_update(struct interface *ifp)
16f1b9ee 932{
d62a17ae 933 struct listnode *node, *nnode;
934 struct zserv *client;
16f1b9ee 935
d62a17ae 936 if (IS_ZEBRA_DEBUG_EVENT)
38bbad1b 937 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)",
a36898e7 938 ifp->name, ifp->vrf_id);
16f1b9ee 939
17da84a4
KS
940 for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
941 /* Do not send unsolicited messages to synchronous clients. */
942 if (client->synchronous)
943 continue;
944
a8a20c4e 945 zsend_interface_link_params(client, ifp);
17da84a4 946 }
16f1b9ee 947}