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