2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
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
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.
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. */
28 #include "sockunion.h"
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 #include "bgpd/bgp_nht.h"
45 /* All information about zebra. */
46 struct zclient
*zclient
= NULL
;
47 struct in_addr router_id_zebra
;
49 /* Growable buffer for nexthops sent to zebra */
50 struct stream
*bgp_nexthop_buf
= NULL
;
51 struct stream
*bgp_ifindices_buf
= NULL
;
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. */
62 struct attr attr_cp
[BGP_MAXIMUM_MAXPATHS
];
63 struct attr_extra attr_extra_cp
[BGP_MAXIMUM_MAXPATHS
];
66 /* Once per address-family initialization of the attribute array */
67 #define BGP_INFO_ATTR_BUF_INIT()\
69 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
70 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
74 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
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]; \
85 #define BGP_INFO_ATTR_BUF_FREE(info) \
87 bgp_attr_deep_free(info->attr); \
90 /* Router-id update message from zebra. */
92 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
94 struct prefix router_id
;
95 struct listnode
*node
, *nnode
;
98 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
100 if (BGP_DEBUG (zebra
, ZEBRA
))
103 prefix2str(&router_id
, buf
, sizeof(buf
));
104 zlog_debug("Zebra rcvd: router id update %s", buf
);
107 router_id_zebra
= router_id
.u
.prefix4
;
109 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
111 if (!bgp
->router_id_static
.s_addr
)
112 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
118 /* Nexthop update message from zebra. */
120 bgp_read_nexthop_update (int command
, struct zclient
*zclient
,
123 bgp_parse_nexthop_update(command
);
128 bgp_read_import_check_update(int command
, struct zclient
*zclient
,
131 bgp_parse_nexthop_update(command
);
136 bgp_nbr_connected_add (struct nbr_connected
*ifc
)
138 struct listnode
*node
, *nnode
, *mnode
;
142 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
144 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
146 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
148 if (peer_active(peer
))
149 BGP_EVENT_ADD (peer
, BGP_Stop
);
150 BGP_EVENT_ADD (peer
, BGP_Start
);
157 bgp_nbr_connected_delete (struct nbr_connected
*ifc
)
159 struct listnode
*node
, *nnode
, *mnode
;
163 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
165 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
167 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
169 BGP_EVENT_ADD (peer
, BGP_Stop
);
175 /* Inteface addition message from zebra. */
177 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
179 struct interface
*ifp
;
181 ifp
= zebra_interface_add_read (zclient
->ibuf
);
183 if (BGP_DEBUG (zebra
, ZEBRA
) && ifp
)
184 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
190 bgp_interface_delete (int command
, struct zclient
*zclient
,
194 struct interface
*ifp
;
197 ifp
= zebra_interface_state_read (s
);
198 ifp
->ifindex
= IFINDEX_INTERNAL
;
200 if (BGP_DEBUG (zebra
, ZEBRA
))
201 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
207 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
210 struct interface
*ifp
;
212 struct nbr_connected
*nc
;
213 struct listnode
*node
, *nnode
;
216 ifp
= zebra_interface_state_read (s
);
221 if (BGP_DEBUG (zebra
, ZEBRA
))
222 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
224 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
225 bgp_connected_add (c
);
227 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
228 bgp_nbr_connected_add (nc
);
234 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
237 struct interface
*ifp
;
239 struct nbr_connected
*nc
;
240 struct listnode
*node
, *nnode
;
243 ifp
= zebra_interface_state_read (s
);
247 if (BGP_DEBUG (zebra
, ZEBRA
))
248 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
250 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
251 bgp_connected_delete (c
);
253 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
254 bgp_nbr_connected_delete (nc
);
256 /* Fast external-failover */
258 struct listnode
*mnode
;
262 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
264 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
267 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
269 if ((peer
->ttl
!= 1) && (peer
->gtsm_hops
!= 1))
272 if (ifp
== peer
->nexthop
.ifp
)
273 BGP_EVENT_ADD (peer
, BGP_Stop
);
282 bgp_interface_bfd_dest_down (int command
, struct zclient
*zclient
,
285 struct interface
*ifp
;
288 ifp
= zebra_interface_bfd_read (zclient
->ibuf
, &p
);
293 if (BGP_DEBUG (zebra
, ZEBRA
))
296 prefix2str(&p
, buf
, sizeof(buf
));
297 zlog_debug("Zebra: interface %s bfd destination %s down", ifp
->name
, buf
);
300 /* Bring the peer down if BFD is enabled in BGP */
302 struct listnode
*mnode
, *node
, *nnode
;
306 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
308 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
310 if (!CHECK_FLAG (peer
->flags
, PEER_FLAG_BFD
))
313 if (ifp
== peer
->nexthop
.ifp
)
314 BGP_EVENT_ADD (peer
, BGP_Stop
);
323 bgp_interface_address_add (int command
, struct zclient
*zclient
,
326 struct connected
*ifc
;
328 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
333 if (bgp_debug_zebra(ifc
->address
))
336 prefix2str(ifc
->address
, buf
, sizeof(buf
));
337 zlog_debug("Zebra rcvd: interface %s address add %s",
338 ifc
->ifp
->name
, buf
);
341 if (if_is_operative (ifc
->ifp
))
342 bgp_connected_add (ifc
);
348 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
351 struct connected
*ifc
;
353 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
358 if (bgp_debug_zebra(ifc
->address
))
361 prefix2str(ifc
->address
, buf
, sizeof(buf
));
362 zlog_debug("Zebra rcvd: interface %s address delete %s",
363 ifc
->ifp
->name
, buf
);
366 if (if_is_operative (ifc
->ifp
))
367 bgp_connected_delete (ifc
);
369 connected_free (ifc
);
375 bgp_interface_nbr_address_add (int command
, struct zclient
*zclient
,
378 struct nbr_connected
*ifc
= NULL
;
380 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
385 if (bgp_debug_zebra(ifc
->address
))
388 prefix2str(ifc
->address
, buf
, sizeof(buf
));
389 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
390 ifc
->ifp
->name
, buf
);
393 if (if_is_operative (ifc
->ifp
))
394 bgp_nbr_connected_add (ifc
);
400 bgp_interface_nbr_address_delete (int command
, struct zclient
*zclient
,
403 struct nbr_connected
*ifc
= NULL
;
405 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
410 if (bgp_debug_zebra(ifc
->address
))
413 prefix2str(ifc
->address
, buf
, sizeof(buf
));
414 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
415 ifc
->ifp
->name
, buf
);
418 if (if_is_operative (ifc
->ifp
))
419 bgp_nbr_connected_delete (ifc
);
421 nbr_connected_free (ifc
);
426 /* Zebra route add and delete treatment. */
428 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
431 struct zapi_ipv4 api
;
432 struct in_addr nexthop
;
433 struct prefix_ipv4 p
;
434 unsigned int ifindex
;
439 /* Type, flags, message. */
440 api
.type
= stream_getc (s
);
441 api
.instance
= stream_getw (s
);
442 api
.flags
= stream_getc (s
);
443 api
.message
= stream_getc (s
);
446 memset (&p
, 0, sizeof (struct prefix_ipv4
));
448 p
.prefixlen
= stream_getc (s
);
449 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
451 /* Nexthop, ifindex, distance, metric. */
452 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
454 api
.nexthop_num
= stream_getc (s
);
455 nexthop
.s_addr
= stream_get_ipv4 (s
);
458 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
460 api
.ifindex_num
= stream_getc (s
);
461 ifindex
= stream_getl (s
); /* ifindex, unused */
468 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
469 api
.distance
= stream_getc (s
);
471 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
472 api
.metric
= stream_getl (s
);
476 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
477 api
.tag
= stream_getw (s
);
481 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
483 if (bgp_debug_zebra((struct prefix
*)&p
))
485 char buf
[2][INET_ADDRSTRLEN
];
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
,
488 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
490 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
494 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
, ifindex
,
495 api
.metric
, api
.type
, api
.instance
, api
.tag
);
499 if (bgp_debug_zebra((struct prefix
*)&p
))
501 char buf
[2][INET_ADDRSTRLEN
];
502 zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
503 "nexthop %s metric %u tag %d",
504 zebra_route_string(api
.type
), api
.instance
,
505 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
507 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
511 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
, api
.instance
);
518 /* Zebra route add and delete treatment. */
520 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
523 struct zapi_ipv6 api
;
524 struct in6_addr nexthop
;
525 struct prefix_ipv6 p
;
526 unsigned int ifindex
;
529 memset (&nexthop
, 0, sizeof (struct in6_addr
));
531 /* Type, flags, message. */
532 api
.type
= stream_getc (s
);
533 api
.instance
= stream_getw (s
);
534 api
.flags
= stream_getc (s
);
535 api
.message
= stream_getc (s
);
538 memset (&p
, 0, sizeof (struct prefix_ipv6
));
540 p
.prefixlen
= stream_getc (s
);
541 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
543 /* Nexthop, ifindex, distance, metric. */
544 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
546 api
.nexthop_num
= stream_getc (s
);
547 stream_get (&nexthop
, s
, 16);
550 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
552 api
.ifindex_num
= stream_getc (s
);
553 ifindex
= stream_getl (s
); /* ifindex, unused */
560 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
561 api
.distance
= stream_getc (s
);
565 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
566 api
.metric
= stream_getl (s
);
570 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
571 api
.tag
= stream_getw (s
);
575 /* Simply ignore link-local address. */
576 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
579 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
581 if (bgp_debug_zebra((struct prefix
*)&p
))
583 char buf
[2][INET6_ADDRSTRLEN
];
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
,
586 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
588 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
592 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
, ifindex
,
593 api
.metric
, api
.type
, api
.instance
, api
.tag
);
597 if (bgp_debug_zebra((struct prefix
*)&p
))
599 char buf
[2][INET6_ADDRSTRLEN
];
600 zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
601 "nexthop %s metric %u tag %d",
602 zebra_route_string(api
.type
), api
.instance
,
603 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
605 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
609 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
, api
.instance
);
614 #endif /* HAVE_IPV6 */
617 if_lookup_by_ipv4 (struct in_addr
*addr
)
619 struct listnode
*ifnode
;
620 struct listnode
*cnode
;
621 struct interface
*ifp
;
622 struct connected
*connected
;
623 struct prefix_ipv4 p
;
628 p
.prefixlen
= IPV4_MAX_BITLEN
;
630 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
632 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
634 cp
= connected
->address
;
636 if (cp
->family
== AF_INET
)
637 if (prefix_match (cp
, (struct prefix
*)&p
))
645 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
647 struct listnode
*ifnode
;
648 struct listnode
*cnode
;
649 struct interface
*ifp
;
650 struct connected
*connected
;
653 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
655 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
657 cp
= connected
->address
;
659 if (cp
->family
== AF_INET
)
660 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
669 if_lookup_by_ipv6 (struct in6_addr
*addr
, unsigned int ifindex
)
671 struct listnode
*ifnode
;
672 struct listnode
*cnode
;
673 struct interface
*ifp
;
674 struct connected
*connected
;
675 struct prefix_ipv6 p
;
680 p
.prefixlen
= IPV6_MAX_BITLEN
;
682 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
684 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
686 cp
= connected
->address
;
688 if (cp
->family
== AF_INET6
)
689 if (prefix_match (cp
, (struct prefix
*)&p
))
691 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
.s6_addr32
[0]))
693 if (ifindex
== ifp
->ifindex
)
705 if_lookup_by_ipv6_exact (struct in6_addr
*addr
, unsigned int ifindex
)
707 struct listnode
*ifnode
;
708 struct listnode
*cnode
;
709 struct interface
*ifp
;
710 struct connected
*connected
;
713 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
715 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
717 cp
= connected
->address
;
719 if (cp
->family
== AF_INET6
)
720 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
722 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
))
724 if (ifindex
== ifp
->ifindex
)
736 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
738 struct listnode
*cnode
;
739 struct connected
*connected
;
742 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
744 cp
= connected
->address
;
746 if (cp
->family
== AF_INET6
)
747 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
749 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
757 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
759 struct listnode
*cnode
;
760 struct connected
*connected
;
763 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
765 cp
= connected
->address
;
767 if (cp
->family
== AF_INET6
)
768 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
770 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
776 #endif /* HAVE_IPV6 */
779 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
781 struct listnode
*cnode
;
782 struct connected
*connected
;
785 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
787 cp
= connected
->address
;
788 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
790 *addr
= cp
->u
.prefix4
;
798 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
799 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
802 struct interface
*ifp
= NULL
;
804 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
811 if (local
->sa
.sa_family
== AF_INET
)
813 nexthop
->v4
= local
->sin
.sin_addr
;
815 ifp
= if_lookup_by_name (peer
->update_if
);
817 ifp
= if_lookup_by_ipv4_exact (&local
->sin
.sin_addr
);
820 if (local
->sa
.sa_family
== AF_INET6
)
822 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
824 if (peer
->conf_if
|| peer
->ifname
)
825 ifp
= if_lookup_by_index (if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
));
827 else if (peer
->update_if
)
828 ifp
= if_lookup_by_name (peer
->update_if
);
830 ifp
= if_lookup_by_ipv6_exact (&local
->sin6
.sin6_addr
,
831 local
->sin6
.sin6_scope_id
);
833 #endif /* HAVE_IPV6 */
840 /* IPv4 connection. */
841 if (local
->sa
.sa_family
== AF_INET
)
845 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
847 /* There is no global nexthop. */
849 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
851 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
852 #endif /* HAVE_IPV6 */
856 /* IPv6 connection. */
857 if (local
->sa
.sa_family
== AF_INET6
)
859 struct interface
*direct
= NULL
;
862 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
863 if (!ret
&& peer
->local_id
.s_addr
)
864 nexthop
->v4
= peer
->local_id
;
867 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
869 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
872 /* If directory connected set link-local address. */
873 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
,
874 remote
->sin6
.sin6_scope_id
);
876 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
879 /* Link-local address. */
881 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
883 /* If there is no global address. Set link-local address as
884 global. I know this break RFC specification... */
886 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
889 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
894 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
895 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
, remote
->sin6
.sin6_scope_id
))
896 peer
->shared_network
= 1;
898 peer
->shared_network
= 0;
900 /* KAME stack specific treatment. */
902 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
903 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
905 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
907 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
908 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
910 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
913 #endif /* HAVE_IPV6 */
917 static struct in6_addr
*
918 bgp_info_to_ipv6_nexthop (struct bgp_info
*info
)
920 struct in6_addr
*nexthop
= NULL
;
922 /* Only global address nexthop exists. */
923 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
924 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
926 /* If both global and link-local address present. */
927 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
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
;
934 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
941 bgp_table_map_apply (struct route_map
*map
, struct prefix
*p
,
942 struct bgp_info
*info
)
944 if (route_map_apply(map
, p
, RMAP_BGP
, info
) != RMAP_DENYMATCH
)
947 if (bgp_debug_zebra(p
))
949 if (p
->family
== AF_INET
)
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])),
955 inet_ntop(AF_INET
, &info
->attr
->nexthop
, buf
[1],
958 if (p
->family
== AF_INET6
)
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])),
964 inet_ntop(AF_INET6
, bgp_info_to_ipv6_nexthop(info
), buf
[1],
972 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
,
973 afi_t afi
, safi_t safi
)
978 struct bgp_info
*mpinfo
;
979 size_t oldsize
, newsize
;
980 u_int32_t nhcount
, metric
;
981 struct bgp_info local_info
;
982 struct bgp_info
*info_cp
= &local_info
;
985 if (zclient
->sock
< 0)
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
))
992 if (bgp
->main_zebra_update_hold
)
998 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
999 tag
= info
->attr
->extra
->tag
;
1003 /* When we create an aggregate route we must also install a Null0 route in
1005 if (info
->sub_type
== BGP_ROUTE_AGGREGATE
)
1006 SET_FLAG (flags
, ZEBRA_FLAG_BLACKHOLE
);
1008 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
||
1009 info
->sub_type
== BGP_ROUTE_AGGREGATE
)
1011 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
1012 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1015 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
1016 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
1017 || bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
1019 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1021 nhcount
= 1 + bgp_info_mpath_count (info
);
1023 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(info
->attr
))
1025 struct zapi_ipv4 api
;
1026 struct in_addr
*nexthop
;
1027 char buf
[2][INET_ADDRSTRLEN
];
1028 int valid_nh_count
= 0;
1030 /* resize nexthop buffer size if necessary */
1031 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1032 (sizeof (struct in_addr
*) * nhcount
))
1034 newsize
= (sizeof (struct in_addr
*) * nhcount
);
1035 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1036 if (newsize
== oldsize
)
1038 zlog_err ("can't resize nexthop buffer");
1042 stream_reset (bgp_nexthop_buf
);
1045 /* Metric is currently based on the best-path only. */
1046 metric
= info
->attr
->med
;
1048 if (bgp
->table_map
[afi
][safi
].name
)
1050 BGP_INFO_ATTR_BUF_INIT();
1052 /* Copy info and attributes, so the route-map apply doesn't modify the
1054 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1055 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1057 metric
= info_cp
->attr
->med
;
1058 nexthop
= &info_cp
->attr
->nexthop
;
1060 if (info_cp
->attr
->extra
)
1061 tag
= info_cp
->attr
->extra
->tag
;
1063 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1067 nexthop
= &info
->attr
->nexthop
;
1072 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1076 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1077 mpinfo
= bgp_info_mpath_next (mpinfo
))
1081 if (bgp
->table_map
[afi
][safi
].name
)
1083 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1092 nexthop
= &mpinfo
->attr
->nexthop
;
1095 if (nexthop
== NULL
)
1098 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1103 api
.type
= ZEBRA_ROUTE_BGP
;
1107 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
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.
1114 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1115 api
.nexthop_num
= 0;
1117 api
.nexthop_num
= valid_nh_count
;
1119 api
.nexthop
= (struct in_addr
**)STREAM_DATA (bgp_nexthop_buf
);
1120 api
.ifindex_num
= 0;
1121 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1122 api
.metric
= metric
;
1126 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1130 distance
= bgp_distance_apply (p
, info
, bgp
);
1134 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
1135 api
.distance
= distance
;
1138 if (bgp_debug_zebra(p
))
1141 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d"
1142 " count %d", (valid_nh_count
? "add":"delete"),
1143 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1144 p
->prefixlen
, api
.metric
, api
.tag
, api
.nexthop_num
);
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])));
1150 zapi_ipv4_route (valid_nh_count
? ZEBRA_IPV4_ROUTE_ADD
: ZEBRA_IPV4_ROUTE_DELETE
,
1151 zclient
, (struct prefix_ipv4
*) p
, &api
);
1155 /* We have to think about a IPv6 link-local address curse. */
1156 if (p
->family
== AF_INET6
||
1157 (p
->family
== AF_INET
&& BGP_ATTR_NEXTHOP_AFI_IP6(info
->attr
)))
1159 unsigned int ifindex
;
1160 struct in6_addr
*nexthop
;
1161 struct zapi_ipv6 api
;
1162 int valid_nh_count
= 0;
1163 char buf
[2][INET6_ADDRSTRLEN
];
1165 /* resize nexthop buffer size if necessary */
1166 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1167 (sizeof (struct in6_addr
*) * nhcount
))
1169 newsize
= (sizeof (struct in6_addr
*) * nhcount
);
1170 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1171 if (newsize
== oldsize
)
1173 zlog_err ("can't resize nexthop buffer");
1177 stream_reset (bgp_nexthop_buf
);
1179 /* resize ifindices buffer size if necessary */
1180 if ((oldsize
= stream_get_size (bgp_ifindices_buf
)) <
1181 (sizeof (unsigned int) * nhcount
))
1183 newsize
= (sizeof (unsigned int) * nhcount
);
1184 newsize
= stream_resize (bgp_ifindices_buf
, newsize
);
1185 if (newsize
== oldsize
)
1187 zlog_err ("can't resize nexthop buffer");
1191 stream_reset (bgp_ifindices_buf
);
1196 assert (info
->attr
->extra
);
1198 /* Metric is currently based on the best-path only. */
1199 metric
= info
->attr
->med
;
1201 if (bgp
->table_map
[afi
][safi
].name
)
1203 BGP_INFO_ATTR_BUF_INIT();
1205 /* Copy info and attributes, so the route-map apply doesn't modify the
1207 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1208 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1210 metric
= info_cp
->attr
->med
;
1211 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1213 if (info_cp
->attr
->extra
)
1214 tag
= info_cp
->attr
->extra
->tag
;
1216 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1220 nexthop
= bgp_info_to_ipv6_nexthop(info
);
1225 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1226 if (info
->peer
->nexthop
.ifp
)
1227 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
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
;
1236 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1237 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1241 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1242 mpinfo
= bgp_info_mpath_next (mpinfo
))
1247 if (bgp
->table_map
[afi
][safi
].name
)
1249 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1258 nexthop
= bgp_info_to_ipv6_nexthop(mpinfo
);
1261 if (nexthop
== NULL
)
1264 if (mpinfo
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1265 if (mpinfo
->peer
->nexthop
.ifp
)
1266 ifindex
= mpinfo
->peer
->nexthop
.ifp
->ifindex
;
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
;
1278 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1279 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1283 /* Make Zebra API structure. */
1285 api
.type
= ZEBRA_ROUTE_BGP
;
1289 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
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.
1296 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1297 api
.nexthop_num
= 0;
1299 api
.nexthop_num
= valid_nh_count
;
1301 api
.nexthop
= (struct in6_addr
**)STREAM_DATA (bgp_nexthop_buf
);
1302 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
1303 api
.ifindex_num
= valid_nh_count
;
1304 api
.ifindex
= (unsigned int *)STREAM_DATA (bgp_ifindices_buf
);
1305 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1306 api
.metric
= metric
;
1310 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1314 if (p
->family
== AF_INET
)
1316 if (bgp_debug_zebra(p
))
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])));
1329 zapi_ipv4_route_ipv6_nexthop (ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD
,
1330 zclient
, (struct prefix_ipv4
*) p
, &api
);
1332 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
,
1333 zclient
, (struct prefix_ipv4
*) p
, &api
);
1337 if (bgp_debug_zebra(p
))
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])));
1349 zapi_ipv6_route (valid_nh_count
?
1350 ZEBRA_IPV6_ROUTE_ADD
: ZEBRA_IPV6_ROUTE_DELETE
,
1351 zclient
, (struct prefix_ipv6
*) p
, &api
);
1354 #endif /* HAVE_IPV6 */
1357 /* Announce all routes of a table to zebra */
1359 bgp_zebra_announce_table (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1361 struct bgp_node
*rn
;
1362 struct bgp_table
*table
;
1363 struct bgp_info
*ri
;
1365 table
= bgp
->rib
[afi
][safi
];
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
);
1377 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
1382 if (zclient
->sock
< 0)
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
))
1393 if (peer
->sort
== BGP_PEER_IBGP
)
1395 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1396 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
1399 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
1400 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
1401 || bgp_flag_check(peer
->bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
1402 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1404 if (p
->family
== AF_INET
)
1406 struct zapi_ipv4 api
;
1407 struct in_addr
*nexthop
;
1410 nexthop
= &info
->attr
->nexthop
;
1412 api
.type
= ZEBRA_ROUTE_BGP
;
1416 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1417 api
.nexthop_num
= 0;
1419 api
.ifindex_num
= 0;
1420 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1421 api
.metric
= info
->attr
->med
;
1423 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1425 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1426 api
.tag
= info
->attr
->extra
->tag
;
1429 if (bgp_debug_zebra(p
))
1431 char buf
[2][INET_ADDRSTRLEN
];
1432 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u tag %d",
1433 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1435 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
1440 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
1441 (struct prefix_ipv4
*) p
, &api
);
1444 /* We have to think about a IPv6 link-local address curse. */
1445 if (p
->family
== AF_INET6
)
1447 struct zapi_ipv6 api
;
1448 unsigned int ifindex
;
1449 struct in6_addr
*nexthop
;
1451 assert (info
->attr
->extra
);
1456 /* Only global address nexthop exists. */
1457 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
1458 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
1460 /* If both global and link-local address present. */
1461 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1463 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
1464 if (info
->peer
->nexthop
.ifp
)
1465 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1468 if (nexthop
== NULL
)
1471 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
1472 if (info
->peer
->conf_if
|| info
->peer
->ifname
)
1473 ifindex
= if_nametoindex (info
->peer
->conf_if
? info
->peer
->conf_if
: info
->peer
->ifname
);
1476 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1489 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1491 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1492 api
.tag
= info
->attr
->extra
->tag
;
1495 if (bgp_debug_zebra(p
))
1497 char buf
[2][INET6_ADDRSTRLEN
];
1498 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u tag %d",
1499 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
1501 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
1506 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
1507 (struct prefix_ipv6
*) p
, &api
);
1509 #endif /* HAVE_IPV6 */
1512 bgp_redist_lookup (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1514 struct list
*red_list
;
1515 struct listnode
*node
;
1516 struct bgp_redist
*red
;
1518 red_list
= bgp
->redist
[afi
][type
];
1522 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
1523 if (red
->instance
== instance
)
1530 bgp_redist_add (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1532 struct list
*red_list
;
1533 struct bgp_redist
*red
;
1535 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1539 if (!bgp
->redist
[afi
][type
])
1540 bgp
->redist
[afi
][type
] = list_new();
1542 red_list
= bgp
->redist
[afi
][type
];
1543 red
= (struct bgp_redist
*)calloc (1, sizeof(struct bgp_redist
));
1544 red
->instance
= instance
;
1546 listnode_add(red_list
, red
);
1552 bgp_redist_del (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1554 struct bgp_redist
*red
;
1556 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1560 listnode_delete(bgp
->redist
[afi
][type
], red
);
1561 if (!bgp
->redist
[afi
][type
]->count
)
1563 list_free(bgp
->redist
[afi
][type
]);
1564 bgp
->redist
[afi
][type
] = NULL
;
1569 /* Other routes redistribution into BGP. */
1571 bgp_redistribute_set (afi_t afi
, int type
, u_short instance
)
1574 /* Return if already redistribute flag is set. */
1575 if (redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1578 redist_add_instance(&zclient
->redist
[afi
][type
], instance
);
1580 /* Return if zebra connection is not established. */
1581 if (zclient
->sock
< 0)
1584 if (BGP_DEBUG (zebra
, ZEBRA
))
1585 zlog_debug("Zebra send: redistribute add afi %d %s %d", afi
,
1586 zebra_route_string(type
), instance
);
1588 /* Send distribute add message to zebra. */
1589 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, instance
);
1595 bgp_redistribute_resend (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1597 /* Return if zebra connection is not established. */
1598 if (zclient
->sock
< 0)
1601 if (BGP_DEBUG (zebra
, ZEBRA
))
1602 zlog_debug("Zebra send: redistribute delete/add afi %d %s %d", afi
,
1603 zebra_route_string(type
), instance
);
1605 /* Send distribute add message to zebra. */
1606 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, afi
, type
, instance
);
1607 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, instance
);
1612 /* Redistribute with route-map specification. */
1614 bgp_redistribute_rmap_set (struct bgp_redist
*red
, const char *name
)
1617 && (strcmp (red
->rmap
.name
, name
) == 0))
1621 free (red
->rmap
.name
);
1622 red
->rmap
.name
= strdup (name
);
1623 red
->rmap
.map
= route_map_lookup_by_name (name
);
1628 /* Redistribute with metric specification. */
1630 bgp_redistribute_metric_set (struct bgp_redist
*red
, u_int32_t metric
)
1632 if (red
->redist_metric_flag
1633 && red
->redist_metric
== metric
)
1636 red
->redist_metric_flag
= 1;
1637 red
->redist_metric
= metric
;
1642 /* Unset redistribution. */
1644 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1646 struct bgp_redist
*red
;
1648 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1652 /* Unset route-map. */
1654 free (red
->rmap
.name
);
1655 red
->rmap
.name
= NULL
;
1656 red
->rmap
.map
= NULL
;
1659 red
->redist_metric_flag
= 0;
1660 red
->redist_metric
= 0;
1662 bgp_redist_del(bgp
, afi
, type
, instance
);
1664 /* Return if zebra connection is disabled. */
1665 if (!redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1667 redist_del_instance(&zclient
->redist
[afi
][type
], instance
);
1669 if (zclient
->sock
>= 0)
1671 /* Send distribute delete message to zebra. */
1672 if (BGP_DEBUG (zebra
, ZEBRA
))
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
);
1678 /* Withdraw redistributed routes from current BGP's routing table. */
1679 bgp_redistribute_withdraw (bgp
, afi
, type
, instance
);
1685 bgp_zclient_reset (void)
1687 zclient_reset (zclient
);
1691 bgp_zebra_init (void)
1693 /* Set default values. */
1694 zclient
= zclient_new ();
1695 zclient_init (zclient
, ZEBRA_ROUTE_BGP
, 0);
1696 zclient
->router_id_update
= bgp_router_id_update
;
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
;
1701 zclient
->interface_nbr_address_add
= bgp_interface_nbr_address_add
;
1702 zclient
->interface_nbr_address_delete
= bgp_interface_nbr_address_delete
;
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
;
1707 zclient
->interface_bfd_dest_down
= bgp_interface_bfd_dest_down
;
1709 zclient
->ipv6_route_add
= zebra_read_ipv6
;
1710 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
1711 #endif /* HAVE_IPV6 */
1712 zclient
->nexthop_update
= bgp_read_nexthop_update
;
1713 zclient
->import_check_update
= bgp_read_import_check_update
;
1715 /* Interface related init. */
1718 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);
1719 bgp_ifindices_buf
= stream_new(BGP_IFINDICES_BUF_SIZE
);