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