]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_zebra.c
Quagga default: BGP enable "maximum-paths 64"
[mirror_frr.git] / bgpd / bgp_zebra.c
CommitLineData
718e3744 1/* zebra client
2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "log.h"
28#include "sockunion.h"
29#include "zclient.h"
30#include "routemap.h"
31#include "thread.h"
3f9c7369 32#include "queue.h"
6e919709 33#include "memory.h"
856ca177 34#include "lib/json.h"
718e3744 35
36#include "bgpd/bgpd.h"
37#include "bgpd/bgp_route.h"
38#include "bgpd/bgp_attr.h"
39#include "bgpd/bgp_nexthop.h"
40#include "bgpd/bgp_zebra.h"
41#include "bgpd/bgp_fsm.h"
a39275d7 42#include "bgpd/bgp_debug.h"
8196f13d 43#include "bgpd/bgp_mpath.h"
fb018d25 44#include "bgpd/bgp_nexthop.h"
ffd0c037 45#include "bgpd/bgp_nht.h"
c43ed2e4 46#include "bgpd/bgp_bfd.h"
6b0655a2 47
718e3744 48/* All information about zebra. */
228da428 49struct zclient *zclient = NULL;
18a6dce6 50struct in_addr router_id_zebra;
718e3744 51
8196f13d
JB
52/* Growable buffer for nexthops sent to zebra */
53struct stream *bgp_nexthop_buf = NULL;
431aa9f9 54struct stream *bgp_ifindices_buf = NULL;
8196f13d 55
73ac8160
DS
56/* These array buffers are used in making a copy of the attributes for
57 route-map apply. Arrays are being used here to minimize mallocs and
58 frees for the temporary copy of the attributes.
59 Given the zapi api expects the nexthop buffer to contain pointer to
60 pointers for nexthops, we couldnt have used a single nexthop variable
61 on the stack, hence we had two options:
62 1. maintain a linked-list and free it after zapi_*_route call
63 2. use an array to avoid number of mallocs.
64 Number of supported next-hops are finite, use of arrays should be ok. */
65struct attr attr_cp[BGP_MAXIMUM_MAXPATHS];
66struct attr_extra attr_extra_cp[BGP_MAXIMUM_MAXPATHS];
67int attr_index = 0;
68
69/* Once per address-family initialization of the attribute array */
70#define BGP_INFO_ATTR_BUF_INIT()\
71do {\
72 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
73 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
74 attr_index = 0;\
75} while (0)
76
77#define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
78do { \
79 *info_dst = *info_src; \
80 assert(attr_index != BGP_MAXIMUM_MAXPATHS);\
81 attr_cp[attr_index].extra = &attr_extra_cp[attr_index]; \
82 bgp_attr_dup (&attr_cp[attr_index], info_src->attr); \
83 bgp_attr_deep_dup (&attr_cp[attr_index], info_src->attr); \
84 info_dst->attr = &attr_cp[attr_index]; \
85 attr_index++;\
86} while (0)
87
88#define BGP_INFO_ATTR_BUF_FREE(info) \
89do { \
90 bgp_attr_deep_free(info->attr); \
91} while (0)
92
18a6dce6 93/* Router-id update message from zebra. */
94f2b392 94static int
7076bb2f
FL
95bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
96 vrf_id_t vrf_id)
718e3744 97{
18a6dce6 98 struct prefix router_id;
1eb8ef25 99 struct listnode *node, *nnode;
18a6dce6 100 struct bgp *bgp;
718e3744 101
18a6dce6 102 zebra_router_id_update_read(zclient->ibuf,&router_id);
a39275d7 103
16286195 104 if (BGP_DEBUG (zebra, ZEBRA))
a39275d7
AS
105 {
106 char buf[128];
107 prefix2str(&router_id, buf, sizeof(buf));
108 zlog_debug("Zebra rcvd: router id update %s", buf);
109 }
110
18a6dce6 111 router_id_zebra = router_id.u.prefix4;
718e3744 112
1eb8ef25 113 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
718e3744 114 {
18a6dce6 115 if (!bgp->router_id_static.s_addr)
1eb8ef25 116 bgp_router_id_set (bgp, &router_id.u.prefix4);
718e3744 117 }
18a6dce6 118
718e3744 119 return 0;
120}
121
fb018d25
DS
122/* Nexthop update message from zebra. */
123static int
124bgp_read_nexthop_update (int command, struct zclient *zclient,
7076bb2f 125 zebra_size_t length, vrf_id_t vrf_id)
fb018d25 126{
7076bb2f 127 bgp_parse_nexthop_update(command, vrf_id);
078430f6
DS
128 return 0;
129}
130
131static int
132bgp_read_import_check_update(int command, struct zclient *zclient,
7076bb2f 133 zebra_size_t length, vrf_id_t vrf_id)
078430f6 134{
7076bb2f 135 bgp_parse_nexthop_update(command, vrf_id);
fb018d25
DS
136 return 0;
137}
138
a80beece 139static void
a197c47c 140bgp_start_interface_nbrs (struct interface *ifp)
a80beece
DS
141{
142 struct listnode *node, *nnode, *mnode;
143 struct bgp *bgp;
144 struct peer *peer;
145
146 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
147 {
148 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
149 {
a197c47c
DS
150 if (peer->conf_if &&
151 (strcmp (peer->conf_if, ifp->name) == 0) &&
152 peer->status != Established)
a80beece
DS
153 {
154 if (peer_active(peer))
155 BGP_EVENT_ADD (peer, BGP_Stop);
156 BGP_EVENT_ADD (peer, BGP_Start);
157 }
158 }
159 }
160}
161
162static void
a197c47c
DS
163bgp_nbr_connected_add (struct nbr_connected *ifc)
164{
165 struct listnode *node;
166 struct connected *connected;
167 struct interface *ifp;
168 struct prefix *p;
169
170 /* Kick-off the FSM for any relevant peers only if there is a
171 * valid local address on the interface.
172 */
173 ifp = ifc->ifp;
174 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
175 {
176 p = connected->address;
177 if (p->family == AF_INET6 &&
178 IN6_IS_ADDR_LINKLOCAL (&p->u.prefix6))
179 break;
180 }
181 if (!connected)
182 return;
183
184 bgp_start_interface_nbrs (ifp);
185}
186
187static void
188bgp_nbr_connected_delete (struct nbr_connected *ifc, int del)
a80beece
DS
189{
190 struct listnode *node, *nnode, *mnode;
191 struct bgp *bgp;
192 struct peer *peer;
a197c47c 193 struct interface *ifp;
a80beece
DS
194
195 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
196 {
197 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
198 {
199 if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0))
200 {
201 BGP_EVENT_ADD (peer, BGP_Stop);
202 }
203 }
204 }
a197c47c
DS
205 /* Free neighbor also, if we're asked to. */
206 if (del)
207 {
208 ifp = ifc->ifp;
209 listnode_delete (ifp->nbr_connected, ifc);
210 nbr_connected_free (ifc);
211 }
a80beece
DS
212}
213
718e3744 214/* Inteface addition message from zebra. */
94f2b392 215static int
7076bb2f
FL
216bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
217 vrf_id_t vrf_id)
718e3744 218{
219 struct interface *ifp;
220
7076bb2f 221 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
718e3744 222
16286195 223 if (BGP_DEBUG (zebra, ZEBRA) && ifp)
a39275d7
AS
224 zlog_debug("Zebra rcvd: interface add %s", ifp->name);
225
718e3744 226 return 0;
227}
228
94f2b392 229static int
718e3744 230bgp_interface_delete (int command, struct zclient *zclient,
7076bb2f 231 zebra_size_t length, vrf_id_t vrf_id)
718e3744 232{
233 struct stream *s;
234 struct interface *ifp;
235
236 s = zclient->ibuf;
7076bb2f 237 ifp = zebra_interface_state_read (s, vrf_id);
d2fc8896 238 ifp->ifindex = IFINDEX_INTERNAL;
718e3744 239
16286195 240 if (BGP_DEBUG (zebra, ZEBRA))
a39275d7
AS
241 zlog_debug("Zebra rcvd: interface delete %s", ifp->name);
242
718e3744 243 return 0;
244}
245
94f2b392 246static int
7076bb2f
FL
247bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length,
248 vrf_id_t vrf_id)
718e3744 249{
250 struct stream *s;
251 struct interface *ifp;
252 struct connected *c;
a80beece 253 struct nbr_connected *nc;
1eb8ef25 254 struct listnode *node, *nnode;
718e3744 255
256 s = zclient->ibuf;
7076bb2f 257 ifp = zebra_interface_state_read (s, vrf_id);
718e3744 258
259 if (! ifp)
260 return 0;
261
16286195 262 if (BGP_DEBUG (zebra, ZEBRA))
a39275d7
AS
263 zlog_debug("Zebra rcvd: interface %s up", ifp->name);
264
1eb8ef25 265 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
266 bgp_connected_add (c);
718e3744 267
a80beece
DS
268 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
269 bgp_nbr_connected_add (nc);
270
718e3744 271 return 0;
272}
273
94f2b392 274static int
7076bb2f
FL
275bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
276 vrf_id_t vrf_id)
718e3744 277{
278 struct stream *s;
279 struct interface *ifp;
280 struct connected *c;
a80beece 281 struct nbr_connected *nc;
1eb8ef25 282 struct listnode *node, *nnode;
718e3744 283
284 s = zclient->ibuf;
7076bb2f 285 ifp = zebra_interface_state_read (s, vrf_id);
718e3744 286 if (! ifp)
287 return 0;
288
16286195 289 if (BGP_DEBUG (zebra, ZEBRA))
a39275d7
AS
290 zlog_debug("Zebra rcvd: interface %s down", ifp->name);
291
1eb8ef25 292 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c))
293 bgp_connected_delete (c);
718e3744 294
a80beece 295 for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc))
a197c47c 296 bgp_nbr_connected_delete (nc, 1);
a80beece 297
8da8689d 298 /* Fast external-failover */
718e3744 299 {
1eb8ef25 300 struct listnode *mnode;
718e3744 301 struct bgp *bgp;
302 struct peer *peer;
718e3744 303
1eb8ef25 304 for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
718e3744 305 {
306 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
307 continue;
308
1eb8ef25 309 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 310 {
8da8689d 311 if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
718e3744 312 continue;
313
8da8689d 314 if (ifp == peer->nexthop.ifp)
718e3744 315 BGP_EVENT_ADD (peer, BGP_Stop);
316 }
317 }
318 }
319
320 return 0;
321}
322
94f2b392 323static int
718e3744 324bgp_interface_address_add (int command, struct zclient *zclient,
7076bb2f 325 zebra_size_t length, vrf_id_t vrf_id)
718e3744 326{
327 struct connected *ifc;
328
7076bb2f 329 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
718e3744 330
331 if (ifc == NULL)
332 return 0;
333
16286195 334 if (bgp_debug_zebra(ifc->address))
a39275d7
AS
335 {
336 char buf[128];
337 prefix2str(ifc->address, buf, sizeof(buf));
338 zlog_debug("Zebra rcvd: interface %s address add %s",
339 ifc->ifp->name, buf);
340 }
341
2e3b2e47 342 if (if_is_operative (ifc->ifp))
a197c47c
DS
343 {
344 bgp_connected_add (ifc);
345 /* If we have learnt of any neighbors on this interface,
346 * check to kick off any BGP interface-based neighbors,
347 * but only if this is a link-local address.
348 */
349 if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) &&
350 !list_isempty(ifc->ifp->nbr_connected))
351 bgp_start_interface_nbrs (ifc->ifp);
352 }
718e3744 353
354 return 0;
355}
356
94f2b392 357static int
718e3744 358bgp_interface_address_delete (int command, struct zclient *zclient,
7076bb2f 359 zebra_size_t length, vrf_id_t vrf_id)
718e3744 360{
361 struct connected *ifc;
362
7076bb2f 363 ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id);
718e3744 364
365 if (ifc == NULL)
366 return 0;
367
16286195 368 if (bgp_debug_zebra(ifc->address))
a39275d7
AS
369 {
370 char buf[128];
371 prefix2str(ifc->address, buf, sizeof(buf));
372 zlog_debug("Zebra rcvd: interface %s address delete %s",
373 ifc->ifp->name, buf);
374 }
375
2e3b2e47 376 if (if_is_operative (ifc->ifp))
718e3744 377 bgp_connected_delete (ifc);
378
379 connected_free (ifc);
380
381 return 0;
382}
383
a80beece
DS
384static int
385bgp_interface_nbr_address_add (int command, struct zclient *zclient,
7076bb2f 386 zebra_size_t length, vrf_id_t vrf_id)
a80beece
DS
387{
388 struct nbr_connected *ifc = NULL;
389
7076bb2f 390 ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
a80beece
DS
391
392 if (ifc == NULL)
393 return 0;
394
16286195 395 if (bgp_debug_zebra(ifc->address))
a80beece
DS
396 {
397 char buf[128];
398 prefix2str(ifc->address, buf, sizeof(buf));
399 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
400 ifc->ifp->name, buf);
401 }
402
403 if (if_is_operative (ifc->ifp))
404 bgp_nbr_connected_add (ifc);
405
406 return 0;
407}
408
409static int
410bgp_interface_nbr_address_delete (int command, struct zclient *zclient,
7076bb2f 411 zebra_size_t length, vrf_id_t vrf_id)
a80beece
DS
412{
413 struct nbr_connected *ifc = NULL;
414
7076bb2f 415 ifc = zebra_interface_nbr_address_read (command, zclient->ibuf, vrf_id);
a80beece
DS
416
417 if (ifc == NULL)
418 return 0;
419
16286195 420 if (bgp_debug_zebra(ifc->address))
a80beece
DS
421 {
422 char buf[128];
423 prefix2str(ifc->address, buf, sizeof(buf));
424 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
425 ifc->ifp->name, buf);
426 }
427
428 if (if_is_operative (ifc->ifp))
a197c47c 429 bgp_nbr_connected_delete (ifc, 0);
a80beece
DS
430
431 nbr_connected_free (ifc);
432
433 return 0;
434}
435
718e3744 436/* Zebra route add and delete treatment. */
94f2b392 437static int
7076bb2f
FL
438zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
439 vrf_id_t vrf_id)
718e3744 440{
441 struct stream *s;
442 struct zapi_ipv4 api;
718e3744 443 struct in_addr nexthop;
444 struct prefix_ipv4 p;
bc413143 445 unsigned int ifindex;
d289687f 446 int i;
718e3744 447
448 s = zclient->ibuf;
718e3744 449 nexthop.s_addr = 0;
450
451 /* Type, flags, message. */
452 api.type = stream_getc (s);
7c8ff89e 453 api.instance = stream_getw (s);
718e3744 454 api.flags = stream_getc (s);
455 api.message = stream_getc (s);
456
457 /* IPv4 prefix. */
458 memset (&p, 0, sizeof (struct prefix_ipv4));
459 p.family = AF_INET;
460 p.prefixlen = stream_getc (s);
461 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
462
463 /* Nexthop, ifindex, distance, metric. */
464 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
465 {
466 api.nexthop_num = stream_getc (s);
467 nexthop.s_addr = stream_get_ipv4 (s);
468 }
0d9551dc 469
718e3744 470 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
471 {
472 api.ifindex_num = stream_getc (s);
bc413143 473 ifindex = stream_getl (s); /* ifindex, unused */
718e3744 474 }
ffd0c037
DS
475 else
476 {
477 ifindex = 0;
478 }
0d9551dc 479
718e3744 480 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
481 api.distance = stream_getc (s);
0d9551dc 482
718e3744 483 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
484 api.metric = stream_getl (s);
485 else
486 api.metric = 0;
487
0d9551dc
DS
488 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
489 api.tag = stream_getw (s);
490 else
491 api.tag = 0;
492
5048fe14 493 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
a39275d7 494 {
ffd0c037 495 if (bgp_debug_zebra((struct prefix *)&p))
a39275d7
AS
496 {
497 char buf[2][INET_ADDRSTRLEN];
7c8ff89e
DS
498 zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
499 zebra_route_string(api.type), api.instance,
a39275d7
AS
500 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
501 p.prefixlen,
502 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
0d9551dc
DS
503 api.metric,
504 api.tag);
a39275d7 505 }
d289687f 506
507 /*
508 * The ADD message is actually an UPDATE and there is no explicit DEL
509 * for a prior redistributed route, if any. So, perform an implicit
510 * DEL processing for the same redistributed route from any other
511 * source type.
512 */
513 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
514 {
515 if (i != api.type)
516 bgp_redistribute_delete((struct prefix *)&p, i, api.instance);
517 }
518
519 /* Now perform the add/update. */
bc413143 520 bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
7c8ff89e 521 api.metric, api.type, api.instance, api.tag);
a39275d7 522 }
5048fe14 523 else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL)
a39275d7 524 {
ffd0c037 525 if (bgp_debug_zebra((struct prefix *)&p))
a39275d7
AS
526 {
527 char buf[2][INET_ADDRSTRLEN];
7c8ff89e 528 zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
0d9551dc 529 "nexthop %s metric %u tag %d",
7c8ff89e 530 zebra_route_string(api.type), api.instance,
a39275d7
AS
531 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
532 p.prefixlen,
533 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
0d9551dc
DS
534 api.metric,
535 api.tag);
a39275d7 536 }
7c8ff89e 537 bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance);
a39275d7 538 }
718e3744 539
540 return 0;
541}
542
543#ifdef HAVE_IPV6
544/* Zebra route add and delete treatment. */
94f2b392 545static int
7076bb2f
FL
546zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length,
547 vrf_id_t vrf_id)
718e3744 548{
549 struct stream *s;
550 struct zapi_ipv6 api;
718e3744 551 struct in6_addr nexthop;
552 struct prefix_ipv6 p;
bc413143 553 unsigned int ifindex;
d289687f 554 int i;
718e3744 555
556 s = zclient->ibuf;
718e3744 557 memset (&nexthop, 0, sizeof (struct in6_addr));
558
559 /* Type, flags, message. */
560 api.type = stream_getc (s);
7c8ff89e 561 api.instance = stream_getw (s);
718e3744 562 api.flags = stream_getc (s);
563 api.message = stream_getc (s);
564
565 /* IPv6 prefix. */
566 memset (&p, 0, sizeof (struct prefix_ipv6));
567 p.family = AF_INET6;
568 p.prefixlen = stream_getc (s);
569 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
570
571 /* Nexthop, ifindex, distance, metric. */
572 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
573 {
574 api.nexthop_num = stream_getc (s);
575 stream_get (&nexthop, s, 16);
576 }
0d9551dc 577
718e3744 578 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
579 {
580 api.ifindex_num = stream_getc (s);
bc413143 581 ifindex = stream_getl (s); /* ifindex, unused */
718e3744 582 }
ffd0c037
DS
583 else
584 {
585 ifindex = 0;
586 }
0d9551dc 587
718e3744 588 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
589 api.distance = stream_getc (s);
590 else
591 api.distance = 0;
0d9551dc 592
718e3744 593 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
594 api.metric = stream_getl (s);
595 else
596 api.metric = 0;
597
0d9551dc
DS
598 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
599 api.tag = stream_getw (s);
600 else
601 api.tag = 0;
602
718e3744 603 /* Simply ignore link-local address. */
604 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
605 return 0;
606
5048fe14 607 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
a39275d7 608 {
ffd0c037 609 if (bgp_debug_zebra((struct prefix *)&p))
a39275d7 610 {
f04a80a5 611 char buf[2][INET6_ADDRSTRLEN];
7c8ff89e
DS
612 zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
613 zebra_route_string(api.type), api.instance,
f04a80a5
SH
614 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
615 p.prefixlen,
616 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
0d9551dc
DS
617 api.metric,
618 api.tag);
a39275d7 619 }
d289687f 620
621 /*
622 * The ADD message is actually an UPDATE and there is no explicit DEL
623 * for a prior redistributed route, if any. So, perform an implicit
624 * DEL processing for the same redistributed route from any other
625 * source type.
626 */
627 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
628 {
629 if (i != api.type)
630 bgp_redistribute_delete((struct prefix *)&p, i, api.instance);
631 }
632
bc413143 633 bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
7c8ff89e 634 api.metric, api.type, api.instance, api.tag);
a39275d7 635 }
5048fe14 636 else if (command == ZEBRA_REDISTRIBUTE_IPV6_DEL)
a39275d7 637 {
ffd0c037 638 if (bgp_debug_zebra((struct prefix *)&p))
a39275d7 639 {
f04a80a5 640 char buf[2][INET6_ADDRSTRLEN];
7c8ff89e 641 zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
0d9551dc 642 "nexthop %s metric %u tag %d",
7c8ff89e 643 zebra_route_string(api.type), api.instance,
f04a80a5
SH
644 inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
645 p.prefixlen,
646 inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
0d9551dc
DS
647 api.metric,
648 api.tag);
a39275d7 649 }
7c8ff89e 650 bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance);
a39275d7 651 }
718e3744 652
653 return 0;
654}
655#endif /* HAVE_IPV6 */
6b0655a2 656
718e3744 657struct interface *
658if_lookup_by_ipv4 (struct in_addr *addr)
659{
52dc7ee6 660 struct listnode *ifnode;
661 struct listnode *cnode;
718e3744 662 struct interface *ifp;
663 struct connected *connected;
664 struct prefix_ipv4 p;
665 struct prefix *cp;
666
667 p.family = AF_INET;
668 p.prefix = *addr;
669 p.prefixlen = IPV4_MAX_BITLEN;
670
1eb8ef25 671 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
718e3744 672 {
1eb8ef25 673 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 674 {
718e3744 675 cp = connected->address;
676
677 if (cp->family == AF_INET)
678 if (prefix_match (cp, (struct prefix *)&p))
679 return ifp;
680 }
681 }
682 return NULL;
683}
684
685struct interface *
686if_lookup_by_ipv4_exact (struct in_addr *addr)
687{
52dc7ee6 688 struct listnode *ifnode;
689 struct listnode *cnode;
718e3744 690 struct interface *ifp;
691 struct connected *connected;
692 struct prefix *cp;
693
1eb8ef25 694 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
718e3744 695 {
1eb8ef25 696 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 697 {
718e3744 698 cp = connected->address;
699
700 if (cp->family == AF_INET)
701 if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))
702 return ifp;
703 }
704 }
705 return NULL;
706}
707
708#ifdef HAVE_IPV6
709struct interface *
ffd0c037 710if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex)
718e3744 711{
52dc7ee6 712 struct listnode *ifnode;
713 struct listnode *cnode;
718e3744 714 struct interface *ifp;
715 struct connected *connected;
716 struct prefix_ipv6 p;
717 struct prefix *cp;
718
719 p.family = AF_INET6;
720 p.prefix = *addr;
721 p.prefixlen = IPV6_MAX_BITLEN;
722
1eb8ef25 723 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
718e3744 724 {
1eb8ef25 725 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 726 {
718e3744 727 cp = connected->address;
728
729 if (cp->family == AF_INET6)
730 if (prefix_match (cp, (struct prefix *)&p))
f2345335 731 {
ffd0c037 732 if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6.s6_addr32[0]))
f2345335
DS
733 {
734 if (ifindex == ifp->ifindex)
735 return ifp;
736 }
737 else
738 return ifp;
739 }
718e3744 740 }
741 }
742 return NULL;
743}
744
745struct interface *
ffd0c037 746if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex)
718e3744 747{
52dc7ee6 748 struct listnode *ifnode;
749 struct listnode *cnode;
718e3744 750 struct interface *ifp;
751 struct connected *connected;
752 struct prefix *cp;
753
1eb8ef25 754 for (ALL_LIST_ELEMENTS_RO (iflist, ifnode, ifp))
718e3744 755 {
1eb8ef25 756 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 757 {
718e3744 758 cp = connected->address;
759
760 if (cp->family == AF_INET6)
761 if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))
f2345335
DS
762 {
763 if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6))
764 {
765 if (ifindex == ifp->ifindex)
766 return ifp;
767 }
768 else
769 return ifp;
770 }
718e3744 771 }
772 }
773 return NULL;
774}
775
94f2b392 776static int
718e3744 777if_get_ipv6_global (struct interface *ifp, struct in6_addr *addr)
778{
52dc7ee6 779 struct listnode *cnode;
718e3744 780 struct connected *connected;
781 struct prefix *cp;
782
1eb8ef25 783 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 784 {
718e3744 785 cp = connected->address;
786
787 if (cp->family == AF_INET6)
788 if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
789 {
790 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
791 return 1;
792 }
793 }
794 return 0;
795}
796
94f2b392 797static int
718e3744 798if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
799{
52dc7ee6 800 struct listnode *cnode;
718e3744 801 struct connected *connected;
802 struct prefix *cp;
803
1eb8ef25 804 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
718e3744 805 {
718e3744 806 cp = connected->address;
807
808 if (cp->family == AF_INET6)
809 if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
810 {
811 memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
812 return 1;
813 }
814 }
815 return 0;
816}
817#endif /* HAVE_IPV6 */
818
6ee06fa9
PM
819static int
820if_get_ipv4_address (struct interface *ifp, struct in_addr *addr)
821{
822 struct listnode *cnode;
823 struct connected *connected;
824 struct prefix *cp;
825
826 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
827 {
828 cp = connected->address;
829 if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4)))
830 {
831 *addr = cp->u.prefix4;
832 return 1;
833 }
834 }
835 return 0;
836}
837
718e3744 838int
839bgp_nexthop_set (union sockunion *local, union sockunion *remote,
840 struct bgp_nexthop *nexthop, struct peer *peer)
841{
842 int ret = 0;
843 struct interface *ifp = NULL;
844
845 memset (nexthop, 0, sizeof (struct bgp_nexthop));
846
847 if (!local)
848 return -1;
849 if (!remote)
850 return -1;
851
852 if (local->sa.sa_family == AF_INET)
853 {
854 nexthop->v4 = local->sin.sin_addr;
2fb2f5cf
DS
855 if (peer->update_if)
856 ifp = if_lookup_by_name (peer->update_if);
857 else
858 ifp = if_lookup_by_ipv4_exact (&local->sin.sin_addr);
718e3744 859 }
860#ifdef HAVE_IPV6
861 if (local->sa.sa_family == AF_INET6)
862 {
863 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
864 {
a80beece
DS
865 if (peer->conf_if || peer->ifname)
866 ifp = if_lookup_by_index (if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname));
718e3744 867 }
2fb2f5cf
DS
868 else if (peer->update_if)
869 ifp = if_lookup_by_name (peer->update_if);
718e3744 870 else
f2345335
DS
871 ifp = if_lookup_by_ipv6_exact (&local->sin6.sin6_addr,
872 local->sin6.sin6_scope_id);
718e3744 873 }
874#endif /* HAVE_IPV6 */
875
876 if (!ifp)
877 return -1;
878
879 nexthop->ifp = ifp;
880
e33a4880 881 /* IPv4 connection, fetch and store IPv6 local address(es) if any. */
718e3744 882 if (local->sa.sa_family == AF_INET)
883 {
884#ifdef HAVE_IPV6
885 /* IPv6 nexthop*/
886 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
887
888 /* There is no global nexthop. */
889 if (!ret)
890 if_get_ipv6_local (ifp, &nexthop->v6_global);
891 else
892 if_get_ipv6_local (ifp, &nexthop->v6_local);
893#endif /* HAVE_IPV6 */
894 }
895
896#ifdef HAVE_IPV6
e33a4880 897 /* IPv6 connection, fetch and store IPv4 local address if any. */
718e3744 898 if (local->sa.sa_family == AF_INET6)
899 {
900 struct interface *direct = NULL;
901
6ee06fa9
PM
902 /* IPv4 nexthop. */
903 ret = if_get_ipv4_address(ifp, &nexthop->v4);
904 if (!ret && peer->local_id.s_addr)
718e3744 905 nexthop->v4 = peer->local_id;
906
907 /* Global address*/
908 if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))
909 {
910 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
911 IPV6_MAX_BYTELEN);
912
913 /* If directory connected set link-local address. */
f2345335
DS
914 direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr,
915 remote->sin6.sin6_scope_id);
718e3744 916 if (direct)
917 if_get_ipv6_local (ifp, &nexthop->v6_local);
918 }
919 else
920 /* Link-local address. */
921 {
922 ret = if_get_ipv6_global (ifp, &nexthop->v6_global);
923
924 /* If there is no global address. Set link-local address as
925 global. I know this break RFC specification... */
b2b926d5
DS
926 /* In this scenario, the expectation for interop is that the
927 * network admin would use a route-map to specify the global
928 * IPv6 nexthop.
929 */
718e3744 930 if (!ret)
931 memcpy (&nexthop->v6_global, &local->sin6.sin6_addr,
932 IPV6_MAX_BYTELEN);
b2b926d5
DS
933 /* Always set the link-local address */
934 memcpy (&nexthop->v6_local, &local->sin6.sin6_addr,
935 IPV6_MAX_BYTELEN);
718e3744 936 }
937 }
938
939 if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||
f2345335 940 if_lookup_by_ipv6 (&remote->sin6.sin6_addr, remote->sin6.sin6_scope_id))
718e3744 941 peer->shared_network = 1;
942 else
943 peer->shared_network = 0;
944
945 /* KAME stack specific treatment. */
946#ifdef KAME
947 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)
948 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))
949 {
950 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);
951 }
952 if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)
953 && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))
954 {
955 SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);
956 }
957#endif /* KAME */
958#endif /* HAVE_IPV6 */
e33a4880 959
960 /* If we have identified the local interface, there is no error for now. */
961 return 0;
718e3744 962}
963
73ac8160
DS
964static struct in6_addr *
965bgp_info_to_ipv6_nexthop (struct bgp_info *info)
966{
967 struct in6_addr *nexthop = NULL;
968
969 /* Only global address nexthop exists. */
801a9bcc 970 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
73ac8160
DS
971 nexthop = &info->attr->extra->mp_nexthop_global;
972
973 /* If both global and link-local address present. */
801a9bcc 974 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
73ac8160
DS
975 {
976 /* Workaround for Cisco's nexthop bug. */
977 if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
978 && info->peer->su_remote->sa.sa_family == AF_INET6)
979 nexthop = &info->peer->su_remote->sin6.sin6_addr;
980 else
981 nexthop = &info->attr->extra->mp_nexthop_local;
982 }
983
984 return nexthop;
985}
986
987static int
988bgp_table_map_apply (struct route_map *map, struct prefix *p,
989 struct bgp_info *info)
990{
991 if (route_map_apply(map, p, RMAP_BGP, info) != RMAP_DENYMATCH)
992 return 1;
993
16286195 994 if (bgp_debug_zebra(p))
73ac8160
DS
995 {
996 if (p->family == AF_INET)
997 {
998 char buf[2][INET_ADDRSTRLEN];
999 zlog_debug("Zebra rmap deny: IPv4 route %s/%d nexthop %s",
1000 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1001 p->prefixlen,
1002 inet_ntop(AF_INET, &info->attr->nexthop, buf[1],
1003 sizeof(buf[1])));
1004 }
1005 if (p->family == AF_INET6)
1006 {
1007 char buf[2][INET6_ADDRSTRLEN];
1008 zlog_debug("Zebra rmap deny: IPv6 route %s/%d nexthop %s",
1009 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1010 p->prefixlen,
1011 inet_ntop(AF_INET6, bgp_info_to_ipv6_nexthop(info), buf[1],
1012 sizeof(buf[1])));
1013 }
1014 }
1015 return 0;
1016}
1017
718e3744 1018void
73ac8160
DS
1019bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
1020 afi_t afi, safi_t safi)
718e3744 1021{
1022 int flags;
1023 u_char distance;
1024 struct peer *peer;
8196f13d
JB
1025 struct bgp_info *mpinfo;
1026 size_t oldsize, newsize;
73ac8160
DS
1027 u_int32_t nhcount, metric;
1028 struct bgp_info local_info;
1029 struct bgp_info *info_cp = &local_info;
0d9551dc 1030 u_short tag;
718e3744 1031
1032 if (zclient->sock < 0)
1033 return;
1034
7076bb2f
FL
1035 if ((p->family == AF_INET &&
1036 !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], VRF_DEFAULT))
1037 || (p->family == AF_INET6 &&
1038 !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], VRF_DEFAULT)))
718e3744 1039 return;
1040
4a16ae86
DS
1041 if (bgp->main_zebra_update_hold)
1042 return;
1043
718e3744 1044 flags = 0;
1045 peer = info->peer;
1046
0d9551dc
DS
1047 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1048 tag = info->attr->extra->tag;
1049 else
1050 tag = 0;
1051
f992e2a9
DS
1052 /* When we create an aggregate route we must also install a Null0 route in
1053 * the RIB */
1054 if (info->sub_type == BGP_ROUTE_AGGREGATE)
1055 SET_FLAG (flags, ZEBRA_FLAG_BLACKHOLE);
1056
1057 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED ||
1058 info->sub_type == BGP_ROUTE_AGGREGATE)
718e3744 1059 {
1060 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
1061 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1062 }
1063
6d85b15b 1064 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
907f92c8
DS
1065 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1066 || bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
1067
718e3744 1068 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1069
431aa9f9 1070 nhcount = 1 + bgp_info_mpath_count (info);
8196f13d 1071
8a92a8a0 1072 if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(info->attr))
718e3744 1073 {
1074 struct zapi_ipv4 api;
1075 struct in_addr *nexthop;
73ac8160
DS
1076 char buf[2][INET_ADDRSTRLEN];
1077 int valid_nh_count = 0;
718e3744 1078
431aa9f9
DS
1079 /* resize nexthop buffer size if necessary */
1080 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
1081 (sizeof (struct in_addr *) * nhcount))
1082 {
1083 newsize = (sizeof (struct in_addr *) * nhcount);
1084 newsize = stream_resize (bgp_nexthop_buf, newsize);
1085 if (newsize == oldsize)
1086 {
1087 zlog_err ("can't resize nexthop buffer");
1088 return;
1089 }
1090 }
1091 stream_reset (bgp_nexthop_buf);
73ac8160
DS
1092 nexthop = NULL;
1093
1094 /* Metric is currently based on the best-path only. */
1095 metric = info->attr->med;
1096
1097 if (bgp->table_map[afi][safi].name)
1098 {
1099 BGP_INFO_ATTR_BUF_INIT();
1100
1101 /* Copy info and attributes, so the route-map apply doesn't modify the
1102 BGP route info. */
1103 BGP_INFO_ATTR_BUF_COPY(info, info_cp);
1104 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1105 {
1106 metric = info_cp->attr->med;
1107 nexthop = &info_cp->attr->nexthop;
0d9551dc
DS
1108
1109 if (info_cp->attr->extra)
1110 tag = info_cp->attr->extra->tag;
73ac8160
DS
1111 }
1112 BGP_INFO_ATTR_BUF_FREE(info_cp);
1113 }
1114 else
1115 {
1116 nexthop = &info->attr->nexthop;
1117 }
1118
1119 if (nexthop)
1120 {
1121 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
1122 valid_nh_count++;
1123 }
431aa9f9 1124
8196f13d 1125 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
73ac8160
DS
1126 mpinfo = bgp_info_mpath_next (mpinfo))
1127 {
1128 nexthop = NULL;
1129
1130 if (bgp->table_map[afi][safi].name)
1131 {
1132 /* Copy info and attributes, so the route-map apply doesn't modify the
1133 BGP route info. */
1134 BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp);
1135 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1136 nexthop = &info_cp->attr->nexthop;
1137 BGP_INFO_ATTR_BUF_FREE(info_cp);
1138 }
1139 else
1140 {
1141 nexthop = &mpinfo->attr->nexthop;
1142 }
1143
1144 if (nexthop == NULL)
1145 continue;
1146
1147 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *));
1148 valid_nh_count++;
1149 }
718e3744 1150
7076bb2f 1151 api.vrf_id = VRF_DEFAULT;
73ac8160 1152 api.flags = flags;
718e3744 1153 api.type = ZEBRA_ROUTE_BGP;
7c8ff89e 1154 api.instance = 0;
718e3744 1155 api.message = 0;
5a616c08 1156 api.safi = safi;
718e3744 1157 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
f992e2a9
DS
1158
1159 /* Note that this currently only applies to Null0 routes for aggregates.
1160 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a special
1161 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1162 * do not want to also encode the 0.0.0.0 nexthop for the aggregate route.
1163 */
1164 if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE))
1165 api.nexthop_num = 0;
1166 else
1167 api.nexthop_num = valid_nh_count;
1168
8196f13d 1169 api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf);
718e3744 1170 api.ifindex_num = 0;
1171 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
73ac8160 1172 api.metric = metric;
718e3744 1173
0d9551dc
DS
1174 if (tag)
1175 {
1176 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
1177 api.tag = tag;
1178 }
1179
718e3744 1180 distance = bgp_distance_apply (p, info, bgp);
1181
1182 if (distance)
1183 {
1184 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
1185 api.distance = distance;
1186 }
a39275d7 1187
16286195 1188 if (bgp_debug_zebra(p))
73ac8160
DS
1189 {
1190 int i;
0d9551dc 1191 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d"
73ac8160
DS
1192 " count %d", (valid_nh_count ? "add":"delete"),
1193 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
0d9551dc 1194 p->prefixlen, api.metric, api.tag, api.nexthop_num);
73ac8160
DS
1195 for (i = 0; i < api.nexthop_num; i++)
1196 zlog_debug(" IPv4 [nexthop %d] %s", i+1,
1197 inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1])));
1198 }
a39275d7 1199
73ac8160
DS
1200 zapi_ipv4_route (valid_nh_count ? ZEBRA_IPV4_ROUTE_ADD: ZEBRA_IPV4_ROUTE_DELETE,
1201 zclient, (struct prefix_ipv4 *) p, &api);
718e3744 1202 }
1203#ifdef HAVE_IPV6
431aa9f9 1204
718e3744 1205 /* We have to think about a IPv6 link-local address curse. */
8a92a8a0
DS
1206 if (p->family == AF_INET6 ||
1207 (p->family == AF_INET && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)))
718e3744 1208 {
1209 unsigned int ifindex;
1210 struct in6_addr *nexthop;
1211 struct zapi_ipv6 api;
431aa9f9 1212 int valid_nh_count = 0;
73ac8160 1213 char buf[2][INET6_ADDRSTRLEN];
431aa9f9
DS
1214
1215 /* resize nexthop buffer size if necessary */
1216 if ((oldsize = stream_get_size (bgp_nexthop_buf)) <
1217 (sizeof (struct in6_addr *) * nhcount))
1218 {
1219 newsize = (sizeof (struct in6_addr *) * nhcount);
1220 newsize = stream_resize (bgp_nexthop_buf, newsize);
1221 if (newsize == oldsize)
1222 {
1223 zlog_err ("can't resize nexthop buffer");
1224 return;
1225 }
1226 }
1227 stream_reset (bgp_nexthop_buf);
1228
1229 /* resize ifindices buffer size if necessary */
1230 if ((oldsize = stream_get_size (bgp_ifindices_buf)) <
1231 (sizeof (unsigned int) * nhcount))
1232 {
1233 newsize = (sizeof (unsigned int) * nhcount);
1234 newsize = stream_resize (bgp_ifindices_buf, newsize);
1235 if (newsize == oldsize)
1236 {
1237 zlog_err ("can't resize nexthop buffer");
1238 return;
1239 }
1240 }
1241 stream_reset (bgp_ifindices_buf);
718e3744 1242
1243 ifindex = 0;
1244 nexthop = NULL;
431aa9f9 1245
fb982c25 1246 assert (info->attr->extra);
718e3744 1247
73ac8160
DS
1248 /* Metric is currently based on the best-path only. */
1249 metric = info->attr->med;
1250
1251 if (bgp->table_map[afi][safi].name)
1252 {
1253 BGP_INFO_ATTR_BUF_INIT();
718e3744 1254
73ac8160
DS
1255 /* Copy info and attributes, so the route-map apply doesn't modify the
1256 BGP route info. */
1257 BGP_INFO_ATTR_BUF_COPY(info, info_cp);
1258 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1259 {
1260 metric = info_cp->attr->med;
1261 nexthop = bgp_info_to_ipv6_nexthop(info_cp);
0d9551dc
DS
1262
1263 if (info_cp->attr->extra)
1264 tag = info_cp->attr->extra->tag;
73ac8160
DS
1265 }
1266 BGP_INFO_ATTR_BUF_FREE(info_cp);
1267 }
1268 else
1269 {
1270 nexthop = bgp_info_to_ipv6_nexthop(info);
1271 }
718e3744 1272
73ac8160
DS
1273 if (nexthop)
1274 {
801a9bcc 1275 if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
73ac8160
DS
1276 if (info->peer->nexthop.ifp)
1277 ifindex = info->peer->nexthop.ifp->ifindex;
1278
1279 if (!ifindex)
ffd0c037
DS
1280 {
1281 if (info->peer->conf_if || info->peer->ifname)
1282 ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname);
1283 else if (info->peer->nexthop.ifp)
1284 ifindex = info->peer->nexthop.ifp->ifindex;
1285 }
73ac8160
DS
1286 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
1287 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
1288 valid_nh_count++;
1289 }
431aa9f9
DS
1290
1291 for (mpinfo = bgp_info_mpath_first (info); mpinfo;
1292 mpinfo = bgp_info_mpath_next (mpinfo))
73ac8160
DS
1293 {
1294 ifindex = 0;
1295 nexthop = NULL;
000830bd 1296
73ac8160 1297 if (bgp->table_map[afi][safi].name)
431aa9f9 1298 {
73ac8160
DS
1299 /* Copy info and attributes, so the route-map apply doesn't modify the
1300 BGP route info. */
1301 BGP_INFO_ATTR_BUF_COPY(mpinfo, info_cp);
1302 if (bgp_table_map_apply(bgp->table_map[afi][safi].map, p, info_cp))
1303 nexthop = bgp_info_to_ipv6_nexthop(info_cp);
1304 BGP_INFO_ATTR_BUF_FREE(info_cp);
1305 }
1306 else
1307 {
1308 nexthop = bgp_info_to_ipv6_nexthop(mpinfo);
431aa9f9 1309 }
431aa9f9 1310
73ac8160
DS
1311 if (nexthop == NULL)
1312 continue;
1313
801a9bcc 1314 if (mpinfo->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
73ac8160
DS
1315 if (mpinfo->peer->nexthop.ifp)
1316 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
000830bd
DS
1317
1318 if (!ifindex)
ffd0c037
DS
1319 {
1320 if (mpinfo->peer->conf_if || mpinfo->peer->ifname)
1321 ifindex = if_nametoindex (mpinfo->peer->conf_if ? mpinfo->peer->conf_if : mpinfo->peer->ifname);
1322 else if (mpinfo->peer->nexthop.ifp)
1323 ifindex = mpinfo->peer->nexthop.ifp->ifindex;
1324 }
73ac8160
DS
1325 if (ifindex == 0)
1326 continue;
431aa9f9
DS
1327
1328 stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in6_addr *));
1329 stream_put (bgp_ifindices_buf, &ifindex, sizeof (unsigned int));
1330 valid_nh_count++;
73ac8160 1331 }
718e3744 1332
1333 /* Make Zebra API structure. */
7076bb2f 1334 api.vrf_id = VRF_DEFAULT;
718e3744 1335 api.flags = flags;
1336 api.type = ZEBRA_ROUTE_BGP;
7c8ff89e 1337 api.instance = 0;
718e3744 1338 api.message = 0;
c7ec179a 1339 api.safi = safi;
718e3744 1340 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
f992e2a9
DS
1341
1342 /* Note that this currently only applies to Null0 routes for aggregates.
1343 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a special
1344 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1345 * do not want to also encode the :: nexthop for the aggregate route.
1346 */
1347 if (CHECK_FLAG(flags, ZEBRA_FLAG_BLACKHOLE))
1348 api.nexthop_num = 0;
1349 else
1350 api.nexthop_num = valid_nh_count;
1351
431aa9f9 1352 api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
718e3744 1353 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
431aa9f9
DS
1354 api.ifindex_num = valid_nh_count;
1355 api.ifindex = (unsigned int *)STREAM_DATA (bgp_ifindices_buf);
718e3744 1356 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
73ac8160 1357 api.metric = metric;
718e3744 1358
0d9551dc
DS
1359 if (tag)
1360 {
1361 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
1362 api.tag = tag;
1363 }
1364
8a92a8a0 1365 if (p->family == AF_INET)
73ac8160 1366 {
8a92a8a0
DS
1367 if (bgp_debug_zebra(p))
1368 {
1369 int i;
1370 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d",
1371 valid_nh_count ? "add" : "delete",
1372 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
1373 p->prefixlen, api.metric, api.tag);
1374 for (i = 0; i < api.nexthop_num; i++)
1375 zlog_debug(" IPv6 [nexthop %d] %s", i+1,
1376 inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
1377 }
1378
1379 if (valid_nh_count)
1380 zapi_ipv4_route_ipv6_nexthop (ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD,
88177fe3
DS
1381 zclient, (struct prefix_ipv4 *) p,
1382 (struct zapi_ipv6 *)&api);
8a92a8a0
DS
1383 else
1384 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE,
88177fe3 1385 zclient, (struct prefix_ipv4 *) p, (struct zapi_ipv4 *)&api);
73ac8160 1386 }
8a92a8a0
DS
1387 else
1388 {
1389 if (bgp_debug_zebra(p))
1390 {
1391 int i;
1392 zlog_debug("Zebra send: IPv6 route %s %s/%d metric %u tag %d",
1393 valid_nh_count ? "add" : "delete",
1394 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
1395 p->prefixlen, api.metric, api.tag);
1396 for (i = 0; i < api.nexthop_num; i++)
1397 zlog_debug(" IPv6 [nexthop %d] %s", i+1,
1398 inet_ntop(AF_INET6, api.nexthop[i], buf[1], sizeof(buf[1])));
1399 }
a39275d7 1400
8a92a8a0
DS
1401 zapi_ipv6_route (valid_nh_count ?
1402 ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE,
1403 zclient, (struct prefix_ipv6 *) p, &api);
1404 }
718e3744 1405 }
1406#endif /* HAVE_IPV6 */
1407}
1408
73ac8160
DS
1409/* Announce all routes of a table to zebra */
1410void
1411bgp_zebra_announce_table (struct bgp *bgp, afi_t afi, safi_t safi)
1412{
1413 struct bgp_node *rn;
1414 struct bgp_table *table;
1415 struct bgp_info *ri;
1416
1417 table = bgp->rib[afi][safi];
4a16ae86 1418 if (!table) return;
73ac8160
DS
1419
1420 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
1421 for (ri = rn->info; ri; ri = ri->next)
1422 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
1423 && ri->type == ZEBRA_ROUTE_BGP
1424 && ri->sub_type == BGP_ROUTE_NORMAL)
1425 bgp_zebra_announce (&rn->p, ri, bgp, afi, safi);
1426}
1427
718e3744 1428void
5a616c08 1429bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
718e3744 1430{
1431 int flags;
1432 struct peer *peer;
1433
1434 if (zclient->sock < 0)
1435 return;
1436
7076bb2f
FL
1437 if ((p->family == AF_INET &&
1438 !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_BGP], VRF_DEFAULT))
1439 || (p->family == AF_INET6 &&
1440 !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_BGP], VRF_DEFAULT)))
718e3744 1441 return;
1442
1443 peer = info->peer;
4a16ae86 1444
718e3744 1445 flags = 0;
1446
6d85b15b 1447 if (peer->sort == BGP_PEER_IBGP)
718e3744 1448 {
1449 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1450 SET_FLAG (flags, ZEBRA_FLAG_IBGP);
1451 }
1452
6d85b15b 1453 if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
907f92c8
DS
1454 || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
1455 || bgp_flag_check(peer->bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
718e3744 1456 SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);
1457
1458 if (p->family == AF_INET)
1459 {
1460 struct zapi_ipv4 api;
718e3744 1461
7076bb2f 1462 api.vrf_id = VRF_DEFAULT;
718e3744 1463 api.flags = flags;
718e3744 1464
1465 api.type = ZEBRA_ROUTE_BGP;
7c8ff89e 1466 api.instance = 0;
718e3744 1467 api.message = 0;
5a616c08 1468 api.safi = safi;
718e3744 1469 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
76145957
DS
1470 api.nexthop_num = 0;
1471 api.nexthop = NULL;
718e3744 1472 api.ifindex_num = 0;
1473 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1474 api.metric = info->attr->med;
1475
0d9551dc
DS
1476 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1477 {
1478 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1479 api.tag = info->attr->extra->tag;
1480 }
1481
16286195 1482 if (bgp_debug_zebra(p))
a39275d7
AS
1483 {
1484 char buf[2][INET_ADDRSTRLEN];
fbf288a5 1485 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
a39275d7 1486 inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
fbf288a5 1487 p->prefixlen, api.metric, api.tag);
a39275d7
AS
1488 }
1489
0a589359 1490 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient,
1491 (struct prefix_ipv4 *) p, &api);
718e3744 1492 }
1493#ifdef HAVE_IPV6
1494 /* We have to think about a IPv6 link-local address curse. */
1495 if (p->family == AF_INET6)
1496 {
1497 struct zapi_ipv6 api;
fb982c25
PJ
1498
1499 assert (info->attr->extra);
1500
7076bb2f 1501 api.vrf_id = VRF_DEFAULT;
718e3744 1502 api.flags = flags;
1503 api.type = ZEBRA_ROUTE_BGP;
7c8ff89e 1504 api.instance = 0;
718e3744 1505 api.message = 0;
c7ec179a 1506 api.safi = safi;
718e3744 1507 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
fbf288a5
DS
1508 api.nexthop_num = 0;
1509 api.nexthop = NULL;
1510 api.ifindex_num = 0;
718e3744 1511 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1512 api.metric = info->attr->med;
1513
0d9551dc
DS
1514 if ((info->attr->extra) && (info->attr->extra->tag != 0))
1515 {
1516 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
1517 api.tag = info->attr->extra->tag;
1518 }
1519
16286195 1520 if (bgp_debug_zebra(p))
a39275d7
AS
1521 {
1522 char buf[2][INET6_ADDRSTRLEN];
fbf288a5 1523 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
a39275d7 1524 inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
fbf288a5 1525 p->prefixlen, api.metric, api.tag);
a39275d7
AS
1526 }
1527
0a589359 1528 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,
1529 (struct prefix_ipv6 *) p, &api);
718e3744 1530 }
1531#endif /* HAVE_IPV6 */
1532}
7c8ff89e
DS
1533struct bgp_redist *
1534bgp_redist_lookup (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1535{
1536 struct list *red_list;
1537 struct listnode *node;
1538 struct bgp_redist *red;
1539
1540 red_list = bgp->redist[afi][type];
1541 if (!red_list)
1542 return(NULL);
1543
1544 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
1545 if (red->instance == instance)
1546 return red;
1547
1548 return NULL;
1549}
1550
1551struct bgp_redist *
1552bgp_redist_add (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1553{
1554 struct list *red_list;
1555 struct bgp_redist *red;
1556
1557 red = bgp_redist_lookup(bgp, afi, type, instance);
1558 if (red)
1559 return red;
1560
1561 if (!bgp->redist[afi][type])
1562 bgp->redist[afi][type] = list_new();
1563
1564 red_list = bgp->redist[afi][type];
6e919709 1565 red = (struct bgp_redist *)XCALLOC(MTYPE_BGP_REDIST, sizeof(struct bgp_redist));
7c8ff89e
DS
1566 red->instance = instance;
1567
1568 listnode_add(red_list, red);
1569
1570 return red;
1571}
1572
1573static void
1574bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
1575{
1576 struct bgp_redist *red;
1577
1578 red = bgp_redist_lookup(bgp, afi, type, instance);
1579
1580 if (red)
1581 {
1582 listnode_delete(bgp->redist[afi][type], red);
1583 if (!bgp->redist[afi][type]->count)
1584 {
1585 list_free(bgp->redist[afi][type]);
1586 bgp->redist[afi][type] = NULL;
1587 }
1588 }
1589}
6b0655a2 1590
718e3744 1591/* Other routes redistribution into BGP. */
1592int
8bb0831e 1593bgp_redistribute_set (afi_t afi, int type, u_short instance)
718e3744 1594{
718e3744 1595
1596 /* Return if already redistribute flag is set. */
7076bb2f
FL
1597 if (instance)
1598 {
1599 if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
1600 return CMD_WARNING;
718e3744 1601
7076bb2f
FL
1602 redist_add_instance(&zclient->mi_redist[afi][type], instance);
1603 }
1604 else
1605 {
1606 if (vrf_bitmap_check (zclient->redist[afi][type], VRF_DEFAULT))
1607 return CMD_WARNING;
1608
1609 vrf_bitmap_set (zclient->redist[afi][type], VRF_DEFAULT);
1610 }
718e3744 1611
1612 /* Return if zebra connection is not established. */
1613 if (zclient->sock < 0)
1614 return CMD_WARNING;
a39275d7 1615
16286195 1616 if (BGP_DEBUG (zebra, ZEBRA))
8bb0831e
DS
1617 zlog_debug("Zebra send: redistribute add afi %d %s %d", afi,
1618 zebra_route_string(type), instance);
518f0eb1 1619
718e3744 1620 /* Send distribute add message to zebra. */
7076bb2f
FL
1621 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
1622 instance, VRF_DEFAULT);
718e3744 1623
1624 return CMD_SUCCESS;
1625}
1626
518f0eb1 1627int
7c8ff89e 1628bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type, u_short instance)
518f0eb1
DS
1629{
1630 /* Return if zebra connection is not established. */
1631 if (zclient->sock < 0)
1632 return -1;
1633
16286195 1634 if (BGP_DEBUG (zebra, ZEBRA))
8bb0831e
DS
1635 zlog_debug("Zebra send: redistribute delete/add afi %d %s %d", afi,
1636 zebra_route_string(type), instance);
518f0eb1
DS
1637
1638 /* Send distribute add message to zebra. */
7076bb2f
FL
1639 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type,
1640 instance, VRF_DEFAULT);
1641 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
1642 instance, VRF_DEFAULT);
518f0eb1
DS
1643
1644 return 0;
1645}
1646
718e3744 1647/* Redistribute with route-map specification. */
1648int
7c8ff89e 1649bgp_redistribute_rmap_set (struct bgp_redist *red, const char *name)
718e3744 1650{
7c8ff89e
DS
1651 if (red->rmap.name
1652 && (strcmp (red->rmap.name, name) == 0))
718e3744 1653 return 0;
1654
7c8ff89e 1655 if (red->rmap.name)
6e919709
DS
1656 XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
1657 red->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
7c8ff89e 1658 red->rmap.map = route_map_lookup_by_name (name);
718e3744 1659
1660 return 1;
1661}
1662
1663/* Redistribute with metric specification. */
1664int
caf958b4
DS
1665bgp_redistribute_metric_set (struct bgp *bgp, struct bgp_redist *red, afi_t afi,
1666 int type, u_int32_t metric)
718e3744 1667{
caf958b4
DS
1668 struct bgp_node *rn;
1669 struct bgp_info *ri;
1670
7c8ff89e
DS
1671 if (red->redist_metric_flag
1672 && red->redist_metric == metric)
718e3744 1673 return 0;
1674
7c8ff89e
DS
1675 red->redist_metric_flag = 1;
1676 red->redist_metric = metric;
718e3744 1677
caf958b4
DS
1678 for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn)) {
1679 for (ri = rn->info; ri; ri = ri->next) {
38244024
DS
1680 if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE && ri->type == type &&
1681 ri->instance == red->instance) {
caf958b4
DS
1682 ri->attr->med = red->redist_metric;
1683 bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
1684 bgp_process(bgp, rn, afi, SAFI_UNICAST);
1685 }
1686 }
1687 }
1688
718e3744 1689 return 1;
1690}
1691
1692/* Unset redistribution. */
1693int
7c8ff89e 1694bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
718e3744 1695{
7c8ff89e
DS
1696 struct bgp_redist *red;
1697
1698 red = bgp_redist_lookup(bgp, afi, type, instance);
1699 if (!red)
1700 return CMD_SUCCESS;
718e3744 1701
1702 /* Unset route-map. */
7c8ff89e 1703 if (red->rmap.name)
6e919709 1704 XFREE(MTYPE_ROUTE_MAP_NAME, red->rmap.name);
7c8ff89e
DS
1705 red->rmap.name = NULL;
1706 red->rmap.map = NULL;
718e3744 1707
1708 /* Unset metric. */
7c8ff89e
DS
1709 red->redist_metric_flag = 0;
1710 red->redist_metric = 0;
1711
1712 bgp_redist_del(bgp, afi, type, instance);
718e3744 1713
1714 /* Return if zebra connection is disabled. */
7076bb2f
FL
1715 if (instance)
1716 {
1717 if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
1718 return CMD_WARNING;
1719 redist_del_instance(&zclient->mi_redist[afi][type], instance);
1720 }
1721 else
1722 {
1723 if (! vrf_bitmap_check (zclient->redist[afi][type], VRF_DEFAULT))
1724 return CMD_WARNING;
1725 vrf_bitmap_unset (zclient->redist[afi][type], VRF_DEFAULT);
1726 }
718e3744 1727
8bb0831e 1728 if (zclient->sock >= 0)
a39275d7
AS
1729 {
1730 /* Send distribute delete message to zebra. */
16286195 1731 if (BGP_DEBUG (zebra, ZEBRA))
8bb0831e
DS
1732 zlog_debug("Zebra send: redistribute delete afi %d %s %d",
1733 afi, zebra_route_string(type), instance);
7076bb2f
FL
1734 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance,
1735 VRF_DEFAULT);
a39275d7 1736 }
718e3744 1737
1738 /* Withdraw redistributed routes from current BGP's routing table. */
7c8ff89e 1739 bgp_redistribute_withdraw (bgp, afi, type, instance);
718e3744 1740
1741 return CMD_SUCCESS;
1742}
1743
718e3744 1744void
94f2b392 1745bgp_zclient_reset (void)
718e3744 1746{
1747 zclient_reset (zclient);
1748}
1749
7076bb2f
FL
1750static void
1751bgp_zebra_connected (struct zclient *zclient)
1752{
1753 zclient_send_requests (zclient, VRF_DEFAULT);
1754
1755 bgp_nht_register_all();
1756}
1757
718e3744 1758void
4140ca4d 1759bgp_zebra_init (struct thread_master *master)
718e3744 1760{
1761 /* Set default values. */
4140ca4d 1762 zclient = zclient_new (master);
7c8ff89e 1763 zclient_init (zclient, ZEBRA_ROUTE_BGP, 0);
7076bb2f 1764 zclient->zebra_connected = bgp_zebra_connected;
18a6dce6 1765 zclient->router_id_update = bgp_router_id_update;
718e3744 1766 zclient->interface_add = bgp_interface_add;
1767 zclient->interface_delete = bgp_interface_delete;
1768 zclient->interface_address_add = bgp_interface_address_add;
1769 zclient->interface_address_delete = bgp_interface_address_delete;
a80beece
DS
1770 zclient->interface_nbr_address_add = bgp_interface_nbr_address_add;
1771 zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete;
718e3744 1772 zclient->ipv4_route_add = zebra_read_ipv4;
1773 zclient->ipv4_route_delete = zebra_read_ipv4;
5048fe14 1774 zclient->redistribute_route_ipv4_add = zebra_read_ipv4;
1775 zclient->redistribute_route_ipv4_del = zebra_read_ipv4;
718e3744 1776 zclient->interface_up = bgp_interface_up;
1777 zclient->interface_down = bgp_interface_down;
1778#ifdef HAVE_IPV6
1779 zclient->ipv6_route_add = zebra_read_ipv6;
1780 zclient->ipv6_route_delete = zebra_read_ipv6;
5048fe14 1781 zclient->redistribute_route_ipv6_add = zebra_read_ipv6;
1782 zclient->redistribute_route_ipv6_del = zebra_read_ipv6;
718e3744 1783#endif /* HAVE_IPV6 */
fb018d25 1784 zclient->nexthop_update = bgp_read_nexthop_update;
078430f6 1785 zclient->import_check_update = bgp_read_import_check_update;
718e3744 1786
8196f13d 1787 bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
431aa9f9 1788 bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
718e3744 1789}