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