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