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