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