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