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