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"
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"
43 /* All information about zebra. */
44 struct zclient
*zclient
= NULL
;
45 struct in_addr router_id_zebra
;
47 /* Growable buffer for nexthops sent to zebra */
48 struct stream
*bgp_nexthop_buf
= NULL
;
49 struct stream
*bgp_ifindices_buf
= NULL
;
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
];
64 /* Once per address-family initialization of the attribute array */
65 #define BGP_INFO_ATTR_BUF_INIT()\
67 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
68 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
72 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
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]; \
83 #define BGP_INFO_ATTR_BUF_FREE(info) \
85 bgp_attr_deep_free(info->attr); \
88 /* Router-id update message from zebra. */
90 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
92 struct prefix router_id
;
93 struct listnode
*node
, *nnode
;
96 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
98 if (BGP_DEBUG(zebra
, ZEBRA
))
101 prefix2str(&router_id
, buf
, sizeof(buf
));
102 zlog_debug("Zebra rcvd: router id update %s", buf
);
105 router_id_zebra
= router_id
.u
.prefix4
;
107 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
109 if (!bgp
->router_id_static
.s_addr
)
110 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
116 /* Nexthop update message from zebra. */
118 bgp_read_nexthop_update (int command
, struct zclient
*zclient
,
121 bgp_parse_nexthop_update();
126 bgp_nbr_connected_add (struct nbr_connected
*ifc
)
128 struct listnode
*node
, *nnode
, *mnode
;
132 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
134 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
136 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
138 if (peer_active(peer
))
139 BGP_EVENT_ADD (peer
, BGP_Stop
);
140 BGP_EVENT_ADD (peer
, BGP_Start
);
147 bgp_nbr_connected_delete (struct nbr_connected
*ifc
)
149 struct listnode
*node
, *nnode
, *mnode
;
153 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
155 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
157 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
159 BGP_EVENT_ADD (peer
, BGP_Stop
);
165 /* Inteface addition message from zebra. */
167 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
169 struct interface
*ifp
;
171 ifp
= zebra_interface_add_read (zclient
->ibuf
);
173 if (BGP_DEBUG(zebra
, ZEBRA
) && ifp
)
174 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
180 bgp_interface_delete (int command
, struct zclient
*zclient
,
184 struct interface
*ifp
;
187 ifp
= zebra_interface_state_read (s
);
188 ifp
->ifindex
= IFINDEX_INTERNAL
;
190 if (BGP_DEBUG(zebra
, ZEBRA
))
191 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
197 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
200 struct interface
*ifp
;
202 struct nbr_connected
*nc
;
203 struct listnode
*node
, *nnode
;
206 ifp
= zebra_interface_state_read (s
);
211 if (BGP_DEBUG(zebra
, ZEBRA
))
212 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
214 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
215 bgp_connected_add (c
);
217 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
218 bgp_nbr_connected_add (nc
);
224 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
227 struct interface
*ifp
;
229 struct nbr_connected
*nc
;
230 struct listnode
*node
, *nnode
;
233 ifp
= zebra_interface_state_read (s
);
237 if (BGP_DEBUG(zebra
, ZEBRA
))
238 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
240 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
241 bgp_connected_delete (c
);
243 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
244 bgp_nbr_connected_delete (nc
);
246 /* Fast external-failover */
248 struct listnode
*mnode
;
252 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
254 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
257 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
259 if ((peer
->ttl
!= 1) && (peer
->gtsm_hops
!= 1))
262 if (ifp
== peer
->nexthop
.ifp
)
263 BGP_EVENT_ADD (peer
, BGP_Stop
);
272 bgp_interface_bfd_dest_down (int command
, struct zclient
*zclient
,
275 struct interface
*ifp
;
278 ifp
= zebra_interface_bfd_read (zclient
->ibuf
, &p
);
283 if (BGP_DEBUG(zebra
, ZEBRA
))
286 prefix2str(&p
, buf
, sizeof(buf
));
287 zlog_debug("Zebra: interface %s bfd destination %s down", ifp
->name
, buf
);
290 /* Bring the peer down if BFD is enabled in BGP */
292 struct listnode
*mnode
, *node
, *nnode
;
296 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
298 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
300 if (!CHECK_FLAG (peer
->flags
, PEER_FLAG_BFD
))
303 if (ifp
== peer
->nexthop
.ifp
)
304 BGP_EVENT_ADD (peer
, BGP_Stop
);
313 bgp_interface_address_add (int command
, struct zclient
*zclient
,
316 struct connected
*ifc
;
318 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
323 if (BGP_DEBUG(zebra
, ZEBRA
))
326 prefix2str(ifc
->address
, buf
, sizeof(buf
));
327 zlog_debug("Zebra rcvd: interface %s address add %s",
328 ifc
->ifp
->name
, buf
);
331 if (if_is_operative (ifc
->ifp
))
332 bgp_connected_add (ifc
);
338 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
341 struct connected
*ifc
;
343 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
348 if (BGP_DEBUG(zebra
, ZEBRA
))
351 prefix2str(ifc
->address
, buf
, sizeof(buf
));
352 zlog_debug("Zebra rcvd: interface %s address delete %s",
353 ifc
->ifp
->name
, buf
);
356 if (if_is_operative (ifc
->ifp
))
357 bgp_connected_delete (ifc
);
359 connected_free (ifc
);
365 bgp_interface_nbr_address_add (int command
, struct zclient
*zclient
,
368 struct nbr_connected
*ifc
= NULL
;
370 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
375 if (BGP_DEBUG(zebra
, ZEBRA
))
378 prefix2str(ifc
->address
, buf
, sizeof(buf
));
379 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
380 ifc
->ifp
->name
, buf
);
383 if (if_is_operative (ifc
->ifp
))
384 bgp_nbr_connected_add (ifc
);
390 bgp_interface_nbr_address_delete (int command
, struct zclient
*zclient
,
393 struct nbr_connected
*ifc
= NULL
;
395 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
400 if (BGP_DEBUG(zebra
, ZEBRA
))
403 prefix2str(ifc
->address
, buf
, sizeof(buf
));
404 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
405 ifc
->ifp
->name
, buf
);
408 if (if_is_operative (ifc
->ifp
))
409 bgp_nbr_connected_delete (ifc
);
411 nbr_connected_free (ifc
);
416 /* Zebra route add and delete treatment. */
418 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
421 struct zapi_ipv4 api
;
422 struct in_addr nexthop
;
423 struct prefix_ipv4 p
;
424 unsigned int ifindex
;
429 /* Type, flags, message. */
430 api
.type
= stream_getc (s
);
431 api
.flags
= stream_getc (s
);
432 api
.message
= stream_getc (s
);
435 memset (&p
, 0, sizeof (struct prefix_ipv4
));
437 p
.prefixlen
= stream_getc (s
);
438 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
440 /* Nexthop, ifindex, distance, metric. */
441 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
443 api
.nexthop_num
= stream_getc (s
);
444 nexthop
.s_addr
= stream_get_ipv4 (s
);
447 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
449 api
.ifindex_num
= stream_getc (s
);
450 ifindex
= stream_getl (s
); /* ifindex, unused */
453 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
454 api
.distance
= stream_getc (s
);
456 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
457 api
.metric
= stream_getl (s
);
461 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
462 api
.tag
= stream_getw (s
);
466 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
468 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
475 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
479 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
, ifindex
,
480 api
.metric
, api
.type
, api
.tag
);
484 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
492 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
496 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
);
503 /* Zebra route add and delete treatment. */
505 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
508 struct zapi_ipv6 api
;
509 struct in6_addr nexthop
;
510 struct prefix_ipv6 p
;
511 unsigned int ifindex
;
514 memset (&nexthop
, 0, sizeof (struct in6_addr
));
516 /* Type, flags, message. */
517 api
.type
= stream_getc (s
);
518 api
.flags
= stream_getc (s
);
519 api
.message
= stream_getc (s
);
522 memset (&p
, 0, sizeof (struct prefix_ipv6
));
524 p
.prefixlen
= stream_getc (s
);
525 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
527 /* Nexthop, ifindex, distance, metric. */
528 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
530 api
.nexthop_num
= stream_getc (s
);
531 stream_get (&nexthop
, s
, 16);
534 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
536 api
.ifindex_num
= stream_getc (s
);
537 ifindex
= stream_getl (s
); /* ifindex, unused */
540 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
541 api
.distance
= stream_getc (s
);
545 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
546 api
.metric
= stream_getl (s
);
550 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
551 api
.tag
= stream_getw (s
);
555 /* Simply ignore link-local address. */
556 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
559 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
561 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
568 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
572 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
, ifindex
,
573 api
.metric
, api
.type
, api
.tag
);
577 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
585 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
589 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
594 #endif /* HAVE_IPV6 */
597 if_lookup_by_ipv4 (struct in_addr
*addr
)
599 struct listnode
*ifnode
;
600 struct listnode
*cnode
;
601 struct interface
*ifp
;
602 struct connected
*connected
;
603 struct prefix_ipv4 p
;
608 p
.prefixlen
= IPV4_MAX_BITLEN
;
610 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
612 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
614 cp
= connected
->address
;
616 if (cp
->family
== AF_INET
)
617 if (prefix_match (cp
, (struct prefix
*)&p
))
625 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
627 struct listnode
*ifnode
;
628 struct listnode
*cnode
;
629 struct interface
*ifp
;
630 struct connected
*connected
;
633 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
635 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
637 cp
= connected
->address
;
639 if (cp
->family
== AF_INET
)
640 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
649 if_lookup_by_ipv6 (struct in6_addr
*addr
)
651 struct listnode
*ifnode
;
652 struct listnode
*cnode
;
653 struct interface
*ifp
;
654 struct connected
*connected
;
655 struct prefix_ipv6 p
;
660 p
.prefixlen
= IPV6_MAX_BITLEN
;
662 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
664 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
666 cp
= connected
->address
;
668 if (cp
->family
== AF_INET6
)
669 if (prefix_match (cp
, (struct prefix
*)&p
))
677 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
679 struct listnode
*ifnode
;
680 struct listnode
*cnode
;
681 struct interface
*ifp
;
682 struct connected
*connected
;
685 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
687 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
689 cp
= connected
->address
;
691 if (cp
->family
== AF_INET6
)
692 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
700 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
702 struct listnode
*cnode
;
703 struct connected
*connected
;
706 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
708 cp
= connected
->address
;
710 if (cp
->family
== AF_INET6
)
711 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
713 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
721 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
723 struct listnode
*cnode
;
724 struct connected
*connected
;
727 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
729 cp
= connected
->address
;
731 if (cp
->family
== AF_INET6
)
732 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
734 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
740 #endif /* HAVE_IPV6 */
743 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
745 struct listnode
*cnode
;
746 struct connected
*connected
;
749 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
751 cp
= connected
->address
;
752 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
754 *addr
= cp
->u
.prefix4
;
762 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
763 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
766 struct interface
*ifp
= NULL
;
768 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
775 if (local
->sa
.sa_family
== AF_INET
)
777 nexthop
->v4
= local
->sin
.sin_addr
;
778 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
781 if (local
->sa
.sa_family
== AF_INET6
)
783 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
785 if (peer
->conf_if
|| peer
->ifname
)
786 ifp
= if_lookup_by_index (if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
));
789 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
791 #endif /* HAVE_IPV6 */
798 /* IPv4 connection. */
799 if (local
->sa
.sa_family
== AF_INET
)
803 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
805 /* There is no global nexthop. */
807 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
809 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
810 #endif /* HAVE_IPV6 */
814 /* IPv6 connection. */
815 if (local
->sa
.sa_family
== AF_INET6
)
817 struct interface
*direct
= NULL
;
820 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
821 if (!ret
&& peer
->local_id
.s_addr
)
822 nexthop
->v4
= peer
->local_id
;
825 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
827 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
830 /* If directory connected set link-local address. */
831 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
833 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
836 /* Link-local address. */
838 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
840 /* If there is no global address. Set link-local address as
841 global. I know this break RFC specification... */
843 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
846 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
851 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
852 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
853 peer
->shared_network
= 1;
855 peer
->shared_network
= 0;
857 /* KAME stack specific treatment. */
859 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
860 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
862 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
864 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
865 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
867 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
870 #endif /* HAVE_IPV6 */
874 static struct in6_addr
*
875 bgp_info_to_ipv6_nexthop (struct bgp_info
*info
)
877 struct in6_addr
*nexthop
= NULL
;
879 /* Only global address nexthop exists. */
880 if (info
->attr
->extra
->mp_nexthop_len
== 16)
881 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
883 /* If both global and link-local address present. */
884 if (info
->attr
->extra
->mp_nexthop_len
== 32)
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
;
891 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
898 bgp_table_map_apply (struct route_map
*map
, struct prefix
*p
,
899 struct bgp_info
*info
)
901 if (route_map_apply(map
, p
, RMAP_BGP
, info
) != RMAP_DENYMATCH
)
904 if (BGP_DEBUG(zebra
, ZEBRA
))
906 if (p
->family
== AF_INET
)
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])),
912 inet_ntop(AF_INET
, &info
->attr
->nexthop
, buf
[1],
915 if (p
->family
== AF_INET6
)
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])),
921 inet_ntop(AF_INET6
, bgp_info_to_ipv6_nexthop(info
), buf
[1],
929 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
,
930 afi_t afi
, safi_t safi
)
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
;
942 if (zclient
->sock
< 0)
945 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
948 if (bgp
->main_zebra_update_hold
)
954 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
955 tag
= info
->attr
->extra
->tag
;
959 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
961 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
962 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
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
);
969 nhcount
= 1 + bgp_info_mpath_count (info
);
971 if (p
->family
== AF_INET
)
973 struct zapi_ipv4 api
;
974 struct in_addr
*nexthop
;
975 char buf
[2][INET_ADDRSTRLEN
];
976 int valid_nh_count
= 0;
978 /* resize nexthop buffer size if necessary */
979 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
980 (sizeof (struct in_addr
*) * nhcount
))
982 newsize
= (sizeof (struct in_addr
*) * nhcount
);
983 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
984 if (newsize
== oldsize
)
986 zlog_err ("can't resize nexthop buffer");
990 stream_reset (bgp_nexthop_buf
);
993 /* Metric is currently based on the best-path only. */
994 metric
= info
->attr
->med
;
996 if (bgp
->table_map
[afi
][safi
].name
)
998 BGP_INFO_ATTR_BUF_INIT();
1000 /* Copy info and attributes, so the route-map apply doesn't modify the
1002 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1003 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1005 metric
= info_cp
->attr
->med
;
1006 nexthop
= &info_cp
->attr
->nexthop
;
1008 if (info_cp
->attr
->extra
)
1009 tag
= info_cp
->attr
->extra
->tag
;
1011 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1015 nexthop
= &info
->attr
->nexthop
;
1020 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1024 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1025 mpinfo
= bgp_info_mpath_next (mpinfo
))
1029 if (bgp
->table_map
[afi
][safi
].name
)
1031 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1040 nexthop
= &mpinfo
->attr
->nexthop
;
1043 if (nexthop
== NULL
)
1046 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1051 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1063 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1067 distance
= bgp_distance_apply (p
, info
, bgp
);
1071 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
1072 api
.distance
= distance
;
1075 if (BGP_DEBUG(zebra
, ZEBRA
))
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])));
1087 zapi_ipv4_route (valid_nh_count
? ZEBRA_IPV4_ROUTE_ADD
: ZEBRA_IPV4_ROUTE_DELETE
,
1088 zclient
, (struct prefix_ipv4
*) p
, &api
);
1092 /* We have to think about a IPv6 link-local address curse. */
1093 if (p
->family
== AF_INET6
)
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
];
1101 /* resize nexthop buffer size if necessary */
1102 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1103 (sizeof (struct in6_addr
*) * nhcount
))
1105 newsize
= (sizeof (struct in6_addr
*) * nhcount
);
1106 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1107 if (newsize
== oldsize
)
1109 zlog_err ("can't resize nexthop buffer");
1113 stream_reset (bgp_nexthop_buf
);
1115 /* resize ifindices buffer size if necessary */
1116 if ((oldsize
= stream_get_size (bgp_ifindices_buf
)) <
1117 (sizeof (unsigned int) * nhcount
))
1119 newsize
= (sizeof (unsigned int) * nhcount
);
1120 newsize
= stream_resize (bgp_ifindices_buf
, newsize
);
1121 if (newsize
== oldsize
)
1123 zlog_err ("can't resize nexthop buffer");
1127 stream_reset (bgp_ifindices_buf
);
1132 assert (info
->attr
->extra
);
1134 /* Metric is currently based on the best-path only. */
1135 metric
= info
->attr
->med
;
1137 if (bgp
->table_map
[afi
][safi
].name
)
1139 BGP_INFO_ATTR_BUF_INIT();
1141 /* Copy info and attributes, so the route-map apply doesn't modify the
1143 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1144 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1146 metric
= info_cp
->attr
->med
;
1147 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1149 if (info_cp
->attr
->extra
)
1150 tag
= info_cp
->attr
->extra
->tag
;
1152 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1156 nexthop
= bgp_info_to_ipv6_nexthop(info
);
1161 if (info
->attr
->extra
->mp_nexthop_len
== 32)
1162 if (info
->peer
->nexthop
.ifp
)
1163 ifindex
= info
->peer
->nexthop
.ifp
->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
;
1171 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1172 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1176 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1177 mpinfo
= bgp_info_mpath_next (mpinfo
))
1182 if (bgp
->table_map
[afi
][safi
].name
)
1184 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1193 nexthop
= bgp_info_to_ipv6_nexthop(mpinfo
);
1196 if (nexthop
== NULL
)
1199 if (mpinfo
->attr
->extra
->mp_nexthop_len
== 32)
1200 if (mpinfo
->peer
->nexthop
.ifp
)
1201 ifindex
= mpinfo
->peer
->nexthop
.ifp
->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
;
1212 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1213 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1217 /* Make Zebra API structure. */
1219 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1233 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1237 if (BGP_DEBUG(zebra
, ZEBRA
))
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])));
1249 zapi_ipv6_route (valid_nh_count
? ZEBRA_IPV6_ROUTE_ADD
: ZEBRA_IPV6_ROUTE_DELETE
,
1250 zclient
, (struct prefix_ipv6
*) p
, &api
);
1252 #endif /* HAVE_IPV6 */
1255 /* Announce all routes of a table to zebra */
1257 bgp_zebra_announce_table (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1259 struct bgp_node
*rn
;
1260 struct bgp_table
*table
;
1261 struct bgp_info
*ri
;
1263 table
= bgp
->rib
[afi
][safi
];
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
);
1275 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
1280 if (zclient
->sock
< 0)
1283 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
1288 if (peer
->bgp
&& peer
->bgp
->main_zebra_update_hold
)
1293 if (peer
->sort
== BGP_PEER_IBGP
)
1295 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1296 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
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
);
1303 if (p
->family
== AF_INET
)
1305 struct zapi_ipv4 api
;
1306 struct in_addr
*nexthop
;
1309 nexthop
= &info
->attr
->nexthop
;
1311 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1321 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1323 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1324 api
.tag
= info
->attr
->extra
->tag
;
1327 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
1333 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
1338 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
1339 (struct prefix_ipv4
*) p
, &api
);
1342 /* We have to think about a IPv6 link-local address curse. */
1343 if (p
->family
== AF_INET6
)
1345 struct zapi_ipv6 api
;
1346 unsigned int ifindex
;
1347 struct in6_addr
*nexthop
;
1349 assert (info
->attr
->extra
);
1354 /* Only global address nexthop exists. */
1355 if (info
->attr
->extra
->mp_nexthop_len
== 16)
1356 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
1358 /* If both global and link-local address present. */
1359 if (info
->attr
->extra
->mp_nexthop_len
== 32)
1361 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
1362 if (info
->peer
->nexthop
.ifp
)
1363 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1366 if (nexthop
== NULL
)
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
);
1374 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1386 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1388 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1389 api
.tag
= info
->attr
->extra
->tag
;
1392 if (BGP_DEBUG(zebra
, ZEBRA
))
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])),
1398 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
1403 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
1404 (struct prefix_ipv6
*) p
, &api
);
1406 #endif /* HAVE_IPV6 */
1409 /* Other routes redistribution into BGP. */
1411 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
1413 /* Set flag to BGP instance. */
1414 bgp
->redist
[afi
][type
] = 1;
1416 /* Return if already redistribute flag is set. */
1417 if (zclient
->redist
[type
])
1420 zclient
->redist
[type
] = 1;
1422 /* Return if zebra connection is not established. */
1423 if (zclient
->sock
< 0)
1426 if (BGP_DEBUG(zebra
, ZEBRA
))
1427 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type
));
1429 /* Send distribute add message to zebra. */
1430 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
1436 bgp_redistribute_resend (struct bgp
*bgp
, afi_t afi
, int type
)
1438 /* Return if zebra connection is not established. */
1439 if (zclient
->sock
< 0)
1442 if (BGP_DEBUG(zebra
, ZEBRA
))
1443 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type
));
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
);
1452 /* Redistribute with route-map specification. */
1454 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
1457 if (bgp
->rmap
[afi
][type
].name
1458 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
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
);
1469 /* Redistribute with metric specification. */
1471 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
1474 if (bgp
->redist_metric_flag
[afi
][type
]
1475 && bgp
->redist_metric
[afi
][type
] == metric
)
1478 bgp
->redist_metric_flag
[afi
][type
] = 1;
1479 bgp
->redist_metric
[afi
][type
] = metric
;
1484 /* Unset redistribution. */
1486 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1488 /* Unset flag from BGP instance. */
1489 bgp
->redist
[afi
][type
] = 0;
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
;
1498 bgp
->redist_metric_flag
[afi
][type
] = 0;
1499 bgp
->redist_metric
[afi
][type
] = 0;
1501 /* Return if zebra connection is disabled. */
1502 if (! zclient
->redist
[type
])
1504 zclient
->redist
[type
] = 0;
1506 if (bgp
->redist
[AFI_IP
][type
] == 0
1507 && bgp
->redist
[AFI_IP6
][type
] == 0
1508 && zclient
->sock
>= 0)
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
);
1517 /* Withdraw redistributed routes from current BGP's routing table. */
1518 bgp_redistribute_withdraw (bgp
, afi
, type
);
1524 bgp_zclient_reset (void)
1526 zclient_reset (zclient
);
1530 bgp_zebra_init (void)
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
;
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
;
1553 /* Interface related init. */
1556 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);
1557 bgp_ifindices_buf
= stream_new(BGP_IFINDICES_BUF_SIZE
);