]> git.proxmox.com Git - mirror_frr.git/blame - zebra/redistribute.c
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
[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 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "vector.h"
25#include "vty.h"
26#include "command.h"
27#include "prefix.h"
28#include "table.h"
29#include "stream.h"
30#include "zclient.h"
31#include "linklist.h"
32#include "log.h"
33
34#include "zebra/rib.h"
35#include "zebra/zserv.h"
36#include "zebra/redistribute.h"
37#include "zebra/debug.h"
18a6dce6 38#include "zebra/router-id.h"
718e3744 39
244c1cdc
DS
40#define ZEBRA_PTM_SUPPORT
41
42
b21b19c5 43/* master zebra server structure */
44extern struct zebra_t zebrad;
45
7a4bb9c5
DS
46/* array holding redistribute info about table redistribution */
47/* bit AFI is set if that AFI is redistributing routes from this table */
48static u_char zebra_import_table_used[ZEBRA_KERNEL_TABLE_MAX];
49static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
50
51int
52is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
53{
54 if (is_zebra_valid_kernel_table(table_id))
55 {
56 if (CHECK_FLAG(zebra_import_table_used[table_id], (u_char)afi))
57 return 1;
58 else
59 return 0;
60 }
61
62 return 0;
63}
64
27da3988 65static int
718e3744 66is_default (struct prefix *p)
67{
68 if (p->family == AF_INET)
69 if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)
70 return 1;
71#ifdef HAVE_IPV6
72#if 0 /* IPv6 default separation is now pending until protocol daemon
73 can handle that. */
74 if (p->family == AF_INET6)
75 if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)
76 return 1;
77#endif /* 0 */
78#endif /* HAVE_IPV6 */
79 return 0;
80}
81
27da3988 82static void
718e3744 83zebra_redistribute_default (struct zserv *client)
84{
85 struct prefix_ipv4 p;
86 struct route_table *table;
87 struct route_node *rn;
88 struct rib *newrib;
89#ifdef HAVE_IPV6
90 struct prefix_ipv6 p6;
91#endif /* HAVE_IPV6 */
92
93
94 /* Lookup default route. */
95 memset (&p, 0, sizeof (struct prefix_ipv4));
96 p.family = AF_INET;
97
98 /* Lookup table. */
99 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
100 if (table)
101 {
102 rn = route_node_lookup (table, (struct prefix *)&p);
103 if (rn)
104 {
9fd92e3c 105 RNODE_FOREACH_RIB (rn, newrib)
718e3744 106 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
107 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 108 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
718e3744 109 route_unlock_node (rn);
110 }
111 }
112
113#ifdef HAVE_IPV6
114 /* Lookup default route. */
115 memset (&p6, 0, sizeof (struct prefix_ipv6));
116 p6.family = AF_INET6;
117
118 /* Lookup table. */
119 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
120 if (table)
121 {
122 rn = route_node_lookup (table, (struct prefix *)&p6);
123 if (rn)
124 {
9fd92e3c 125 RNODE_FOREACH_RIB (rn, newrib)
718e3744 126 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
127 && newrib->distance != DISTANCE_INFINITY)
b9df2d25 128 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
718e3744 129 route_unlock_node (rn);
130 }
131 }
132#endif /* HAVE_IPV6 */
133}
134
135/* Redistribute routes. */
27da3988 136static void
7c8ff89e 137zebra_redistribute (struct zserv *client, int type, u_short instance)
718e3744 138{
139 struct rib *newrib;
140 struct route_table *table;
141 struct route_node *rn;
142
143 table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
144 if (table)
145 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 146 RNODE_FOREACH_RIB (rn, newrib)
718e3744 147 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
7c8ff89e
DS
148 && newrib->type == type
149 && newrib->instance == instance
718e3744 150 && newrib->distance != DISTANCE_INFINITY
151 && zebra_check_addr (&rn->p))
04b02fda
DS
152 {
153 client->redist_v4_add_cnt++;
154 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
155 }
718e3744 156
157#ifdef HAVE_IPV6
158 table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
159 if (table)
160 for (rn = route_top (table); rn; rn = route_next (rn))
9fd92e3c 161 RNODE_FOREACH_RIB (rn, newrib)
718e3744 162 if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
7c8ff89e
DS
163 && newrib->type == type
164 && newrib->instance == instance
718e3744 165 && newrib->distance != DISTANCE_INFINITY
166 && zebra_check_addr (&rn->p))
04b02fda
DS
167 {
168 client->redist_v6_add_cnt++;
169 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
170 }
718e3744 171#endif /* HAVE_IPV6 */
172}
173
718e3744 174void
175redistribute_add (struct prefix *p, struct rib *rib)
176{
1eb8ef25 177 struct listnode *node, *nnode;
718e3744 178 struct zserv *client;
179
1eb8ef25 180 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
181 {
182 if (is_default (p))
183 {
8bb0831e
DS
184 if ((p->family == AF_INET) &&
185 (client->redist_default ||
186 redist_check_instance(&client->redist[AFI_IP][rib->type],
187 rib->instance)))
188 {
189 client->redist_v4_add_cnt++;
190 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
191 }
718e3744 192#ifdef HAVE_IPV6
8bb0831e
DS
193 if ((p->family == AF_INET6) &&
194 (client->redist_default ||
195 redist_check_instance(&client->redist[AFI_IP6][rib->type],
196 rib->instance)))
197 {
198 client->redist_v6_add_cnt++;
199 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
200 }
718e3744 201#endif /* HAVE_IPV6 */
1eb8ef25 202 }
8bb0831e 203 else
1eb8ef25 204 {
8bb0831e
DS
205 if ((p->family == AF_INET) &&
206 redist_check_instance(&client->redist[AFI_IP][rib->type],
207 rib->instance))
04b02fda
DS
208 {
209 client->redist_v4_add_cnt++;
8bb0831e
DS
210 zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
211 }
718e3744 212#ifdef HAVE_IPV6
8bb0831e
DS
213 if ((p->family == AF_INET6) &&
214 redist_check_instance(&client->redist[AFI_IP6][rib->type],
215 rib->instance))
216 {
217 client->redist_v6_add_cnt++;
218 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
219 }
718e3744 220#endif /* HAVE_IPV6 */
1eb8ef25 221 }
222 }
718e3744 223}
224
225void
226redistribute_delete (struct prefix *p, struct rib *rib)
227{
1eb8ef25 228 struct listnode *node, *nnode;
718e3744 229 struct zserv *client;
230
231 /* Add DISTANCE_INFINITY check. */
232 if (rib->distance == DISTANCE_INFINITY)
233 return;
234
1eb8ef25 235 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
236 {
237 if (is_default (p))
238 {
8bb0831e
DS
239 if ((p->family == AF_INET) &&
240 (client->redist_default ||
241 redist_check_instance(&client->redist[AFI_IP][rib->type],
242 rib->instance)))
243 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
1eb8ef25 244 rib);
718e3744 245#ifdef HAVE_IPV6
8bb0831e
DS
246 if ((p->family == AF_INET6) &&
247 (client->redist_default ||
248 redist_check_instance(&client->redist[AFI_IP6][rib->type],
249 rib->instance)))
250 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
1eb8ef25 251 rib);
252#endif /* HAVE_IPV6 */
1eb8ef25 253 }
8bb0831e
DS
254 else
255 {
256 if ((p->family == AF_INET) &&
257 redist_check_instance(&client->redist[AFI_IP][rib->type],
258 rib->instance))
259 zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
260 rib);
718e3744 261#ifdef HAVE_IPV6
8bb0831e
DS
262 if ((p->family == AF_INET6) &&
263 redist_check_instance(&client->redist[AFI_IP6][rib->type],
264 rib->instance))
265 zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
266 rib);
1eb8ef25 267#endif /* HAVE_IPV6 */
268 }
269 }
718e3744 270}
271
272void
273zebra_redistribute_add (int command, struct zserv *client, int length)
274{
8bb0831e 275 afi_t afi;
718e3744 276 int type;
7c8ff89e 277 u_short instance;
718e3744 278
8bb0831e 279 afi = stream_getc (client->ibuf);
718e3744 280 type = stream_getc (client->ibuf);
7c8ff89e 281 instance = stream_getw (client->ibuf);
718e3744 282
ebf08631
DL
283 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
284 return;
285
8bb0831e 286 if (!redist_check_instance(&client->redist[afi][type], instance))
718e3744 287 {
8bb0831e 288 redist_add_instance(&client->redist[afi][type], instance);
7c8ff89e 289 zebra_redistribute (client, type, instance);
718e3744 290 }
ebf08631 291}
718e3744 292
293void
294zebra_redistribute_delete (int command, struct zserv *client, int length)
295{
8bb0831e 296 afi_t afi;
718e3744 297 int type;
7c8ff89e 298 u_short instance;
718e3744 299
8bb0831e 300 afi = stream_getc (client->ibuf);
718e3744 301 type = stream_getc (client->ibuf);
7c8ff89e 302 instance = stream_getw (client->ibuf);
718e3744 303
ebf08631
DL
304 if (type == 0 || type >= ZEBRA_ROUTE_MAX)
305 return;
306
8bb0831e 307 if (redist_check_instance(&client->redist[afi][type], instance))
7c8ff89e 308 {
8bb0831e 309 redist_del_instance(&client->redist[afi][type], instance);
7c8ff89e
DS
310 //Pending: why no reaction here?
311 }
ebf08631 312}
718e3744 313
314void
315zebra_redistribute_default_add (int command, struct zserv *client, int length)
316{
317 client->redist_default = 1;
318 zebra_redistribute_default (client);
319}
320
321void
322zebra_redistribute_default_delete (int command, struct zserv *client,
323 int length)
324{
325 client->redist_default = 0;;
326}
327
328/* Interface up information. */
329void
330zebra_interface_up_update (struct interface *ifp)
331{
1eb8ef25 332 struct listnode *node, *nnode;
718e3744 333 struct zserv *client;
334
335 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 336 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
718e3744 337
244c1cdc
DS
338 if (ifp->ptm_status || !ifp->ptm_enable) {
339 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
04b02fda
DS
340 {
341 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
342 }
244c1cdc 343 }
718e3744 344}
345
346/* Interface down information. */
347void
348zebra_interface_down_update (struct interface *ifp)
349{
1eb8ef25 350 struct listnode *node, *nnode;
718e3744 351 struct zserv *client;
352
353 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 354 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
718e3744 355
1eb8ef25 356 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
04b02fda
DS
357 {
358 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
359 }
718e3744 360}
361
362/* Interface information update. */
363void
364zebra_interface_add_update (struct interface *ifp)
365{
1eb8ef25 366 struct listnode *node, *nnode;
718e3744 367 struct zserv *client;
368
369 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 370 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);
718e3744 371
1eb8ef25 372 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
373 if (client->ifinfo)
04b02fda
DS
374 {
375 client->ifadd_cnt++;
376 zsend_interface_add (client, ifp);
377 }
718e3744 378}
379
380void
381zebra_interface_delete_update (struct interface *ifp)
382{
1eb8ef25 383 struct listnode *node, *nnode;
718e3744 384 struct zserv *client;
385
386 if (IS_ZEBRA_DEBUG_EVENT)
b6178002 387 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
718e3744 388
1eb8ef25 389 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
390 if (client->ifinfo)
04b02fda
DS
391 {
392 client->ifdel_cnt++;
393 zsend_interface_delete (client, ifp);
394 }
718e3744 395}
396
397/* Interface address addition. */
398void
399zebra_interface_address_add_update (struct interface *ifp,
400 struct connected *ifc)
401{
1eb8ef25 402 struct listnode *node, *nnode;
718e3744 403 struct zserv *client;
404 struct prefix *p;
718e3744 405
406 if (IS_ZEBRA_DEBUG_EVENT)
407 {
81cce018
SH
408 char buf[INET6_ADDRSTRLEN];
409
718e3744 410 p = ifc->address;
b6178002 411 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",
81cce018 412 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
b6178002 413 p->prefixlen, ifc->ifp->name);
718e3744 414 }
415
c7df92de
CF
416 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
417 zlog_warn("WARNING: advertising address to clients that is not yet usable.");
418
18a6dce6 419 router_id_add_address(ifc);
420
1eb8ef25 421 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
422 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
04b02fda
DS
423 {
424 client->connected_rt_add_cnt++;
425 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
426 }
718e3744 427}
428
429/* Interface address deletion. */
430void
431zebra_interface_address_delete_update (struct interface *ifp,
432 struct connected *ifc)
433{
1eb8ef25 434 struct listnode *node, *nnode;
718e3744 435 struct zserv *client;
436 struct prefix *p;
718e3744 437
438 if (IS_ZEBRA_DEBUG_EVENT)
439 {
81cce018
SH
440 char buf[INET6_ADDRSTRLEN];
441
718e3744 442 p = ifc->address;
b6178002 443 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",
81cce018 444 inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
718e3744 445 p->prefixlen, ifc->ifp->name);
446 }
447
18a6dce6 448 router_id_del_address(ifc);
449
1eb8ef25 450 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
451 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
04b02fda
DS
452 {
453 client->connected_rt_del_cnt++;
454 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
455 }
718e3744 456}
d5a5c8f0 457
7a4bb9c5
DS
458int
459zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
460{
461 struct rib *newrib;
462 struct prefix_ipv4 p4;
463 struct nexthop *nhop;
464 struct in_addr *gate;
465
466 if (rn->p.family == AF_INET)
467 {
468 p4.family = AF_INET;
469 p4.prefixlen = rn->p.prefixlen;
470 p4.prefix = rn->p.u.prefix4;
471
472 if (rib->nexthop_num == 1)
473 {
474 nhop = rib->nexthop;
475 if ((nhop->type == NEXTHOP_TYPE_IFINDEX) ||
476 (nhop->type == NEXTHOP_TYPE_IFNAME))
477 gate = NULL;
478 else
479 gate = &nhop->gate.ipv4;
480
481 rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
482 gate, &nhop->src.ipv4,
483 nhop->ifindex, zebrad.rtm_table_default,
484 rib->metric,
485 zebra_import_table_distance[AFI_IP][rib->table],
486 SAFI_UNICAST);
487 }
488 else if (rib->nexthop_num > 1)
489 {
490 newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
491 newrib->type = ZEBRA_ROUTE_TABLE;
492 newrib->distance = zebra_import_table_distance[AFI_IP][rib->table];
493 newrib->flags = rib->flags;
494 newrib->metric = rib->metric;
495 newrib->table = zebrad.rtm_table_default;
496 newrib->nexthop_num = 0;
497 newrib->uptime = time(NULL);
498 newrib->instance = rib->table;
499
500 /* Assuming these routes are never recursive */
501 for (nhop = rib->nexthop; nhop; nhop = nhop->next)
502 copy_nexthops(newrib, nhop);
503
504 rib_add_ipv4_multipath(&p4, newrib, SAFI_UNICAST);
505 }
506 }
507 /* DD: Add IPv6 code */
508 return 0;
509}
510
511int
512zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
513{
514 struct prefix_ipv4 p4;
515
516 if (rn->p.family == AF_INET)
517 {
518 p4.family = AF_INET;
519 p4.prefixlen = rn->p.prefixlen;
520 p4.prefix = rn->p.u.prefix4;
521
522 rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
523 0, zebrad.rtm_table_default, SAFI_UNICAST);
524 }
525 /* DD: Add IPv6 code */
526
527 return 0;
528}
529
530/* Assuming no one calls this with the main routing table */
531int
532zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
533{
534 struct route_table *table;
535 struct rib *rib;
536 struct route_node *rn;
537
538 if (!is_zebra_valid_kernel_table(table_id) ||
539 ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default)))
540 return (-1);
541
542 if (afi >= AFI_MAX)
543 return (-1);
544
545 table = vrf_other_route_table(afi, table_id, 0);
546 if (table == NULL)
547 {
548 return 0;
549 }
550 else if (IS_ZEBRA_DEBUG_RIB)
551 {
552 zlog_debug ("%s routes from table %d",
553 add ? "Importing" : "Unimporting", table_id);
554 }
555
556 if (add)
557 {
558 SET_FLAG(zebra_import_table_used[table_id], afi);
559 zebra_import_table_distance[afi][table_id] = distance;
560 }
561 else
562 {
563 UNSET_FLAG(zebra_import_table_used[table_id], (u_char)afi);
564 zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT;
565 }
566
567 for (rn = route_top(table); rn; rn = route_next(rn))
568 {
569 /* For each entry in the non-default routing table,
570 * add the entry in the main table
571 */
572 if (!rn->info)
573 continue;
574
575 RNODE_FOREACH_RIB (rn, rib)
576 {
577 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
578 continue;
579 break;
580 }
581
582 if (!rib)
583 continue;
584
4e3afb14
DS
585 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) ||
586 ((afi == AFI_IP6) && (rn->p.family == AF_INET6)))
7a4bb9c5
DS
587 {
588 if (add)
589 zebra_add_import_table_entry (rn, rib);
590 else
591 zebra_del_import_table_entry (rn, rib);
592 }
593 }
594 return 0;
595}
596
597int
598zebra_import_table_config (struct vty *vty)
599{
600 int i;
601 afi_t afi;
602 int write = 0;
603 char afi_str[AFI_MAX][6] = {"", "ip", "ipv6"};
604
605 for (afi = AFI_IP; afi < AFI_MAX; afi++)
606 {
607 for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++)
608 {
609 if (is_zebra_import_table_enabled(afi, i))
610 {
611 if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT)
612 {
613 vty_out(vty, "%s import-table %d distance %d%s", afi_str[afi],
614 i, zebra_import_table_distance[afi][i], VTY_NEWLINE);
615 }
616 else
617 {
618 vty_out(vty, "%s import-table %d%s", afi_str[afi], i,
619 VTY_NEWLINE);
620 }
621 write = 1;
622 }
623 }
624 }
625
626 return write;
627}