]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
zebra: rib: use nexthop ptr in rib_add/delete
[mirror_frr.git] / zebra / redistribute.c
CommitLineData
718e3744 1/* Redistribution Handler
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 19 */
20
21#include <zebra.h>
22
23#include "vector.h"
24#include "vty.h"
25#include "command.h"
26#include "prefix.h"
27#include "table.h"
28#include "stream.h"
29#include "zclient.h"
30#include "linklist.h"
31#include "log.h"
b72ede27 32#include "vrf.h"
05737783 33#include "srcdest_table.h"
718e3744 34
35#include "zebra/rib.h"
36#include "zebra/zserv.h"
7c551956
DS
37#include "zebra/zebra_ns.h"
38#include "zebra/zebra_vrf.h"
8902474b 39#include "zebra/zebra_routemap.h"
718e3744 40#include "zebra/redistribute.h"
41#include "zebra/debug.h"
18a6dce6 42#include "zebra/router-id.h"
4a1ab8e4 43#include "zebra/zebra_memory.h"
1a98c087 44#include "zebra/zebra_vxlan.h"
718e3744 45
244c1cdc
DS
46#define ZEBRA_PTM_SUPPORT
47
7a4bb9c5
DS
48/* array holding redistribute info about table redistribution */
49/* bit AFI is set if that AFI is redistributing routes from this table */
032bfaaf 50static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
7a4bb9c5
DS
51static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
52
d62a17ae 53int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
7a4bb9c5 54{
d62a17ae 55 if (is_zebra_valid_kernel_table(table_id))
56 return zebra_import_table_used[afi][table_id];
57 return 0;
7a4bb9c5
DS
58}
59
d62a17ae 60int is_default(struct prefix *p)
718e3744 61{
d62a17ae 62 if (p->family == AF_INET)
63 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
64 return 1;
65#if 0 /* IPv6 default separation is now pending until protocol daemon \
66 can handle that. */
718e3744 67 if (p->family == AF_INET6)
68 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
69 return 1;
70#endif /* 0 */
d62a17ae 71 return 0;
718e3744 72}
73
d62a17ae 74static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
718e3744 75{
d62a17ae 76 int afi;
77 struct prefix p;
78 struct route_table *table;
79 struct route_node *rn;
80 struct route_entry *newre;
81
82 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
83 /* Lookup table. */
84 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
85 if (!table)
86 continue;
87
88 /* Lookup default route. */
89 memset(&p, 0, sizeof(p));
90 p.family = afi2family(afi);
91 rn = route_node_lookup(table, &p);
92 if (!rn)
93 continue;
94
95 RNODE_FOREACH_RE(rn, newre)
96 if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
97 && newre->distance != DISTANCE_INFINITY)
74489921
RW
98 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
99 client, &rn->p, NULL, newre);
d62a17ae 100
101 route_unlock_node(rn);
102 }
718e3744 103}
104
105/* Redistribute routes. */
d62a17ae 106static void zebra_redistribute(struct zserv *client, int type, u_short instance,
107 vrf_id_t vrf_id, 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))
d62a17ae 118 RNODE_FOREACH_RE(rn, newre)
119 {
120 struct prefix *dst_p, *src_p;
121 srcdest_rnode_prefixes(rn, &dst_p, &src_p);
122
123 if (IS_ZEBRA_DEBUG_EVENT)
124 zlog_debug(
125 "%s: checking: selected=%d, type=%d, distance=%d, "
126 "zebra_check_addr=%d",
127 __func__,
128 CHECK_FLAG(newre->flags,
129 ZEBRA_FLAG_SELECTED),
130 newre->type, newre->distance,
131 zebra_check_addr(dst_p));
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 */
d62a17ae 151void redistribute_update(struct prefix *p, struct prefix *src_p,
152 struct route_entry *re, struct route_entry *prev_re)
718e3744 153{
d62a17ae 154 struct listnode *node, *nnode;
155 struct zserv *client;
156 int send_redistribute;
157 int afi;
158 char buf[INET6_ADDRSTRLEN];
159
160 if (IS_ZEBRA_DEBUG_RIB) {
161 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
162 zlog_debug(
163 "%u:%s/%d: Redist update re %p (type %d), old %p (type %d)",
164 re->vrf_id, buf, p->prefixlen, re, re->type, prev_re,
165 prev_re ? prev_re->type : -1);
166 }
167
168 afi = family2afi(p->family);
169 if (!afi) {
170 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
171 __FUNCTION__);
172 return;
c41fc67b 173 }
d62a17ae 174
175 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
176 send_redistribute = 0;
177
178 if (is_default(p)
179 && vrf_bitmap_check(client->redist_default, re->vrf_id))
180 send_redistribute = 1;
181 else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
182 re->vrf_id))
183 send_redistribute = 1;
184 else if (re->instance
185 && redist_check_instance(
186 &client->mi_redist[afi][re->type],
187 re->instance))
188 send_redistribute = 1;
189 else if (vrf_bitmap_check(client->redist[afi][re->type],
190 re->vrf_id))
191 send_redistribute = 1;
192
193 if (send_redistribute) {
74489921
RW
194 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
195 client, p, src_p, re);
d62a17ae 196 } else if (prev_re
197 && ((re->instance
198 && redist_check_instance(
199 &client->mi_redist[afi]
200 [prev_re->type],
201 re->instance))
202 || vrf_bitmap_check(
203 client->redist[afi][prev_re->type],
204 re->vrf_id))) {
74489921
RW
205 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
206 client, p, src_p, prev_re);
d62a17ae 207 }
c41fc67b 208 }
718e3744 209}
210
d62a17ae 211void redistribute_delete(struct prefix *p, struct prefix *src_p,
212 struct route_entry *re)
718e3744 213{
d62a17ae 214 struct listnode *node, *nnode;
215 struct zserv *client;
216 char buf[INET6_ADDRSTRLEN];
217 int afi;
218
219 if (IS_ZEBRA_DEBUG_RIB) {
220 inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
221 zlog_debug("%u:%s/%d: Redist delete re %p (type %d)",
222 re->vrf_id, buf, p->prefixlen, re, re->type);
223 }
224
225 /* Add DISTANCE_INFINITY check. */
226 if (re->distance == DISTANCE_INFINITY)
227 return;
228
229 afi = family2afi(p->family);
230 if (!afi) {
231 zlog_warn("%s: Unknown AFI/SAFI prefix received\n",
232 __FUNCTION__);
233 return;
234 }
235
236 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
237 if ((is_default(p)
238 && vrf_bitmap_check(client->redist_default, re->vrf_id))
239 || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
240 re->vrf_id)
241 || (re->instance
242 && redist_check_instance(
243 &client->mi_redist[afi][re->type],
244 re->instance))
245 || vrf_bitmap_check(client->redist[afi][re->type],
246 re->vrf_id)) {
74489921
RW
247 zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_DEL,
248 client, p, src_p, re);
d62a17ae 249 }
1eb8ef25 250 }
718e3744 251}
252
d62a17ae 253void zebra_redistribute_add(int command, struct zserv *client, int length,
254 struct zebra_vrf *zvrf)
718e3744 255{
d62a17ae 256 afi_t afi;
257 int type;
258 u_short instance;
259
260 afi = stream_getc(client->ibuf);
261 type = stream_getc(client->ibuf);
262 instance = stream_getw(client->ibuf);
263
264 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
265 return;
266
267 if (instance) {
268 if (!redist_check_instance(&client->mi_redist[afi][type],
269 instance)) {
270 redist_add_instance(&client->mi_redist[afi][type],
271 instance);
272 zebra_redistribute(client, type, instance,
273 zvrf_id(zvrf), afi);
274 }
275 } else {
276 if (!vrf_bitmap_check(client->redist[afi][type],
277 zvrf_id(zvrf))) {
278 vrf_bitmap_set(client->redist[afi][type],
279 zvrf_id(zvrf));
280 zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
281 }
4e1cadf0 282 }
ebf08631 283}
718e3744 284
d62a17ae 285void zebra_redistribute_delete(int command, struct zserv *client, int length,
286 struct zebra_vrf *zvrf)
718e3744 287{
d62a17ae 288 afi_t afi;
289 int type;
290 u_short instance;
291
292 afi = stream_getc(client->ibuf);
293 type = stream_getc(client->ibuf);
294 instance = stream_getw(client->ibuf);
295
296 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
297 return;
298
299 /*
300 * NOTE: no need to withdraw the previously advertised routes. The
301 * clients
302 * themselves should keep track of the received routes from zebra and
303 * withdraw them when necessary.
304 */
305 if (instance)
306 redist_del_instance(&client->mi_redist[afi][type], instance);
307 else
308 vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));
ebf08631 309}
718e3744 310
d62a17ae 311void zebra_redistribute_default_add(int command, struct zserv *client,
312 int length, struct zebra_vrf *zvrf)
718e3744 313{
d62a17ae 314 vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
315 zebra_redistribute_default(client, zvrf_id(zvrf));
316}
718e3744 317
d62a17ae 318void zebra_redistribute_default_delete(int command, struct zserv *client,
319 int length, struct zebra_vrf *zvrf)
718e3744 320{
d62a17ae 321 vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
322}
718e3744 323
324/* Interface up information. */
d62a17ae 325void zebra_interface_up_update(struct interface *ifp)
718e3744 326{
d62a17ae 327 struct listnode *node, *nnode;
328 struct zserv *client;
329
330 if (IS_ZEBRA_DEBUG_EVENT)
331 zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
332
333 if (ifp->ptm_status || !ifp->ptm_enable) {
334 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
335 if (client->ifinfo) {
336 zsend_interface_update(ZEBRA_INTERFACE_UP,
337 client, ifp);
338 zsend_interface_link_params(client, ifp);
339 }
16f1b9ee 340 }
718e3744 341}
342
343/* Interface down information. */
d62a17ae 344void zebra_interface_down_update(struct interface *ifp)
718e3744 345{
d62a17ae 346 struct listnode *node, *nnode;
347 struct zserv *client;
718e3744 348
d62a17ae 349 if (IS_ZEBRA_DEBUG_EVENT)
350 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
718e3744 351
d62a17ae 352 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
353 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
354 }
718e3744 355}
356
357/* Interface information update. */
d62a17ae 358void zebra_interface_add_update(struct interface *ifp)
718e3744 359{
d62a17ae 360 struct listnode *node, *nnode;
361 struct zserv *client;
362
363 if (IS_ZEBRA_DEBUG_EVENT)
364 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name,
365 ifp->vrf_id);
366
367 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
368 if (client->ifinfo) {
369 client->ifadd_cnt++;
370 zsend_interface_add(client, ifp);
371 zsend_interface_link_params(client, ifp);
372 }
718e3744 373}
374
d62a17ae 375void zebra_interface_delete_update(struct interface *ifp)
718e3744 376{
d62a17ae 377 struct listnode *node, *nnode;
378 struct zserv *client;
718e3744 379
d62a17ae 380 if (IS_ZEBRA_DEBUG_EVENT)
381 zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
718e3744 382
d62a17ae 383 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
384 client->ifdel_cnt++;
385 zsend_interface_delete(client, ifp);
386 }
718e3744 387}
388
389/* Interface address addition. */
d62a17ae 390void zebra_interface_address_add_update(struct interface *ifp,
391 struct connected *ifc)
718e3744 392{
d62a17ae 393 struct listnode *node, *nnode;
394 struct zserv *client;
395 struct prefix *p;
396
397 if (IS_ZEBRA_DEBUG_EVENT) {
398 char buf[PREFIX_STRLEN];
399
400 p = ifc->address;
401 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s",
402 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
403 }
404
405 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
406 zlog_warn(
407 "WARNING: advertising address to clients that is not yet usable.");
408
1a98c087
MK
409 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 1);
410
d62a17ae 411 router_id_add_address(ifc);
412
413 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
414 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
415 client->connected_rt_add_cnt++;
416 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD,
417 client, ifp, ifc);
418 }
718e3744 419}
420
421/* Interface address deletion. */
d62a17ae 422void zebra_interface_address_delete_update(struct interface *ifp,
423 struct connected *ifc)
718e3744 424{
d62a17ae 425 struct listnode *node, *nnode;
426 struct zserv *client;
427 struct prefix *p;
428
429 if (IS_ZEBRA_DEBUG_EVENT) {
430 char buf[PREFIX_STRLEN];
431
432 p = ifc->address;
433 zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s",
434 prefix2str(p, buf, sizeof(buf)), ifc->ifp->name);
435 }
436
1a98c087
MK
437 zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
438
d62a17ae 439 router_id_del_address(ifc);
440
441 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
442 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
443 client->connected_rt_del_cnt++;
444 zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE,
445 client, ifp, ifc);
446 }
718e3744 447}
d5a5c8f0 448
c8e264b6 449/* Interface VRF change. May need to delete from clients not interested in
450 * the new VRF. Note that this function is invoked *prior* to the VRF change.
451 */
d62a17ae 452void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)
c8e264b6 453{
d62a17ae 454 struct listnode *node, *nnode;
455 struct zserv *client;
456
457 if (IS_ZEBRA_DEBUG_EVENT)
458 zlog_debug(
459 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
460 ifp->name, ifp->vrf_id, new_vrf_id);
461
462 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
463 /* Need to delete if the client is not interested in the new
464 * VRF. */
465 zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp);
466 client->ifdel_cnt++;
467 zsend_interface_delete(client, ifp);
468 zsend_interface_vrf_update(client, ifp, new_vrf_id);
469 }
c8e264b6 470}
471
472/* Interface VRF change. This function is invoked *post* VRF change and sends an
473 * add to clients who are interested in the new VRF but not in the old VRF.
474 */
d62a17ae 475void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)
c8e264b6 476{
d62a17ae 477 struct listnode *node, *nnode;
478 struct zserv *client;
479
480 if (IS_ZEBRA_DEBUG_EVENT)
481 zlog_debug(
482 "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
483 ifp->name, old_vrf_id, ifp->vrf_id);
484
485 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
486 /* Need to add if the client is interested in the new VRF. */
487 client->ifadd_cnt++;
488 zsend_interface_add(client, ifp);
489 zsend_interface_addresses(client, ifp);
490 }
c8e264b6 491}
492
d62a17ae 493int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
494 const char *rmap_name)
7a4bb9c5 495{
d62a17ae 496 struct route_entry *newre;
497 struct route_entry *same;
498 struct prefix p;
d62a17ae 499 route_map_result_t ret = RMAP_MATCH;
500
501 if (rmap_name)
502 ret = zebra_import_table_route_map_check(
503 AFI_IP, re->type, &rn->p, re->nexthop, re->vrf_id,
504 re->tag, rmap_name);
505
506 if (ret == RMAP_MATCH) {
507 if (rn->p.family == AF_INET) {
508 p.family = AF_INET;
509 p.prefixlen = rn->p.prefixlen;
510 p.u.prefix4 = rn->p.u.prefix4;
511
512 RNODE_FOREACH_RE(rn, same)
513 {
514 if (CHECK_FLAG(same->status,
515 ROUTE_ENTRY_REMOVED))
516 continue;
517
518 if (same->type == re->type
519 && same->instance == re->instance
520 && same->table == re->table
521 && same->type != ZEBRA_ROUTE_CONNECT)
522 break;
523 }
524
525 if (same)
526 zebra_del_import_table_entry(rn, same);
527
528
529 if (re->nexthop_num == 1) {
d62a17ae 530 rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id,
531 ZEBRA_ROUTE_TABLE, re->table, 0, &p,
fd36be7e
DL
532 NULL, re->nexthop,
533 zebrad.rtm_table_default,
d62a17ae 534 re->metric, re->mtu,
535 zebra_import_table_distance[AFI_IP]
536 [re->table]);
537 } else if (re->nexthop_num > 1) {
538 newre = XCALLOC(MTYPE_RE,
539 sizeof(struct route_entry));
540 newre->type = ZEBRA_ROUTE_TABLE;
541 newre->distance =
542 zebra_import_table_distance[AFI_IP]
543 [re->table];
544 newre->flags = re->flags;
545 newre->metric = re->metric;
546 newre->mtu = re->mtu;
547 newre->table = zebrad.rtm_table_default;
548 newre->nexthop_num = 0;
549 newre->uptime = time(NULL);
550 newre->instance = re->table;
551 route_entry_copy_nexthops(newre, re->nexthop);
552
553 rib_add_multipath(AFI_IP, SAFI_UNICAST, &p,
554 NULL, newre);
555 }
556 }
557 } else {
558 zebra_del_import_table_entry(rn, re);
559 }
560 /* DD: Add IPv6 code */
561 return 0;
7a4bb9c5
DS
562}
563
d62a17ae 564int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
7a4bb9c5 565{
d62a17ae 566 struct prefix p;
7a4bb9c5 567
d62a17ae 568 if (rn->p.family == AF_INET) {
569 p.family = AF_INET;
570 p.prefixlen = rn->p.prefixlen;
571 p.u.prefix4 = rn->p.u.prefix4;
7a4bb9c5 572
d62a17ae 573 rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
fd36be7e 574 re->table, re->flags, &p, NULL, NULL,
f19435a8 575 zebrad.rtm_table_default, re->metric);
d62a17ae 576 }
577 /* DD: Add IPv6 code */
7a4bb9c5 578
d62a17ae 579 return 0;
7a4bb9c5
DS
580}
581
582/* Assuming no one calls this with the main routing table */
d62a17ae 583int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance,
584 const char *rmap_name, int add)
7a4bb9c5 585{
d62a17ae 586 struct route_table *table;
587 struct route_entry *re;
588 struct route_node *rn;
589
590 if (!is_zebra_valid_kernel_table(table_id)
591 || ((table_id == RT_TABLE_MAIN)
592 || (table_id == zebrad.rtm_table_default)))
593 return (-1);
594
595 if (afi >= AFI_MAX)
596 return (-1);
597
598 table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
599 if (table == NULL) {
600 return 0;
601 } else if (IS_ZEBRA_DEBUG_RIB) {
602 zlog_debug("%s routes from table %d",
603 add ? "Importing" : "Unimporting", table_id);
7a4bb9c5
DS
604 }
605
d62a17ae 606 if (add) {
607 if (rmap_name)
608 zebra_add_import_table_route_map(afi, rmap_name,
609 table_id);
610 else {
611 rmap_name =
612 zebra_get_import_table_route_map(afi, table_id);
613 if (rmap_name)
614 zebra_del_import_table_route_map(afi, table_id);
615 }
7a4bb9c5 616
d62a17ae 617 zebra_import_table_used[afi][table_id] = 1;
618 zebra_import_table_distance[afi][table_id] = distance;
619 } else {
620 zebra_import_table_used[afi][table_id] = 0;
621 zebra_import_table_distance[afi][table_id] =
622 ZEBRA_TABLE_DISTANCE_DEFAULT;
623
624 rmap_name = zebra_get_import_table_route_map(afi, table_id);
625 if (rmap_name)
626 zebra_del_import_table_route_map(afi, table_id);
7a4bb9c5 627 }
7a4bb9c5 628
d62a17ae 629 for (rn = route_top(table); rn; rn = route_next(rn)) {
630 /* For each entry in the non-default routing table,
631 * add the entry in the main table
632 */
633 if (!rn->info)
634 continue;
635
636 RNODE_FOREACH_RE(rn, re)
7a4bb9c5 637 {
d62a17ae 638 if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
639 continue;
640 break;
7a4bb9c5 641 }
8902474b 642
d62a17ae 643 if (!re)
644 continue;
8902474b 645
d62a17ae 646 if (((afi == AFI_IP) && (rn->p.family == AF_INET))
647 || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) {
648 if (add)
649 zebra_add_import_table_entry(rn, re, rmap_name);
650 else
651 zebra_del_import_table_entry(rn, re);
652 }
653 }
654 return 0;
655}
656
657int zebra_import_table_config(struct vty *vty)
658{
659 int i;
660 afi_t afi;
661 int write = 0;
662 char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"};
663 const char *rmap_name;
664
665 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
666 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
667 if (is_zebra_import_table_enabled(afi, i)) {
668 if (zebra_import_table_distance[afi][i]
669 != ZEBRA_TABLE_DISTANCE_DEFAULT) {
670 vty_out(vty,
671 "%s import-table %d distance %d",
672 afi_str[afi], i,
673 zebra_import_table_distance[afi]
674 [i]);
675 } else {
676 vty_out(vty, "%s import-table %d",
677 afi_str[afi], i);
678 }
679
680 rmap_name = zebra_get_import_table_route_map(
681 afi, i);
682 if (rmap_name)
683 vty_out(vty, " route-map %s",
684 rmap_name);
685
686 vty_out(vty, "\n");
687 write = 1;
688 }
689 }
7a4bb9c5 690 }
7a4bb9c5 691
d62a17ae 692 return write;
7a4bb9c5 693}
8902474b 694
d62a17ae 695void zebra_import_table_rm_update()
8902474b 696{
d62a17ae 697 afi_t afi;
698 int i;
699 struct route_table *table;
700 struct route_entry *re;
701 struct route_node *rn;
702 const char *rmap_name;
703
704 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
705 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) {
706 if (is_zebra_import_table_enabled(afi, i)) {
707 rmap_name = zebra_get_import_table_route_map(
708 afi, i);
709 if (!rmap_name)
710 return;
711
712 table = zebra_vrf_other_route_table(
713 afi, i, VRF_DEFAULT);
714 for (rn = route_top(table); rn;
715 rn = route_next(rn)) {
716 /* For each entry in the non-default
717 * routing table,
718 * add the entry in the main table
719 */
720 if (!rn->info)
721 continue;
722
723 RNODE_FOREACH_RE(rn, re)
724 {
725 if (CHECK_FLAG(
726 re->status,
727 ROUTE_ENTRY_REMOVED))
728 continue;
729 break;
730 }
731
732 if (!re)
733 continue;
734
735 if (((afi == AFI_IP)
736 && (rn->p.family == AF_INET))
737 || ((afi == AFI_IP6)
738 && (rn->p.family == AF_INET6)))
739 zebra_add_import_table_entry(
740 rn, re, rmap_name);
741 }
742 }
743 }
8902474b 744 }
8902474b 745
d62a17ae 746 return;
8902474b 747}
16f1b9ee
OD
748
749/* Interface parameters update */
d62a17ae 750void zebra_interface_parameters_update(struct interface *ifp)
16f1b9ee 751{
d62a17ae 752 struct listnode *node, *nnode;
753 struct zserv *client;
16f1b9ee 754
d62a17ae 755 if (IS_ZEBRA_DEBUG_EVENT)
756 zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s",
757 ifp->name);
16f1b9ee 758
d62a17ae 759 for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
760 if (client->ifinfo)
761 zsend_interface_link_params(client, ifp);
16f1b9ee 762}