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"
44 /* All information about zebra. */
45 struct zclient
*zclient
= NULL
;
46 struct in_addr router_id_zebra
;
48 /* Growable buffer for nexthops sent to zebra */
49 struct stream
*bgp_nexthop_buf
= NULL
;
50 struct stream
*bgp_ifindices_buf
= NULL
;
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
];
65 /* Once per address-family initialization of the attribute array */
66 #define BGP_INFO_ATTR_BUF_INIT()\
68 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
69 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
73 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
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]; \
84 #define BGP_INFO_ATTR_BUF_FREE(info) \
86 bgp_attr_deep_free(info->attr); \
89 /* Router-id update message from zebra. */
91 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
93 struct prefix router_id
;
94 struct listnode
*node
, *nnode
;
97 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
99 if (BGP_DEBUG (zebra
, ZEBRA
))
102 prefix2str(&router_id
, buf
, sizeof(buf
));
103 zlog_debug("Zebra rcvd: router id update %s", buf
);
106 router_id_zebra
= router_id
.u
.prefix4
;
108 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
110 if (!bgp
->router_id_static
.s_addr
)
111 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
117 /* Nexthop update message from zebra. */
119 bgp_read_nexthop_update (int command
, struct zclient
*zclient
,
122 bgp_parse_nexthop_update();
127 bgp_nbr_connected_add (struct nbr_connected
*ifc
)
129 struct listnode
*node
, *nnode
, *mnode
;
133 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
135 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
137 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
139 if (peer_active(peer
))
140 BGP_EVENT_ADD (peer
, BGP_Stop
);
141 BGP_EVENT_ADD (peer
, BGP_Start
);
148 bgp_nbr_connected_delete (struct nbr_connected
*ifc
)
150 struct listnode
*node
, *nnode
, *mnode
;
154 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
156 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
158 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
160 BGP_EVENT_ADD (peer
, BGP_Stop
);
166 /* Inteface addition message from zebra. */
168 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
170 struct interface
*ifp
;
172 ifp
= zebra_interface_add_read (zclient
->ibuf
);
174 if (BGP_DEBUG (zebra
, ZEBRA
) && ifp
)
175 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
181 bgp_interface_delete (int command
, struct zclient
*zclient
,
185 struct interface
*ifp
;
188 ifp
= zebra_interface_state_read (s
);
189 ifp
->ifindex
= IFINDEX_INTERNAL
;
191 if (BGP_DEBUG (zebra
, ZEBRA
))
192 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
198 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
201 struct interface
*ifp
;
203 struct nbr_connected
*nc
;
204 struct listnode
*node
, *nnode
;
207 ifp
= zebra_interface_state_read (s
);
212 if (BGP_DEBUG (zebra
, ZEBRA
))
213 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
215 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
216 bgp_connected_add (c
);
218 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
219 bgp_nbr_connected_add (nc
);
225 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
228 struct interface
*ifp
;
230 struct nbr_connected
*nc
;
231 struct listnode
*node
, *nnode
;
234 ifp
= zebra_interface_state_read (s
);
238 if (BGP_DEBUG (zebra
, ZEBRA
))
239 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
241 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
242 bgp_connected_delete (c
);
244 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
245 bgp_nbr_connected_delete (nc
);
247 /* Fast external-failover */
249 struct listnode
*mnode
;
253 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
255 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
258 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
260 if ((peer
->ttl
!= 1) && (peer
->gtsm_hops
!= 1))
263 if (ifp
== peer
->nexthop
.ifp
)
264 BGP_EVENT_ADD (peer
, BGP_Stop
);
273 bgp_interface_bfd_dest_down (int command
, struct zclient
*zclient
,
276 struct interface
*ifp
;
279 ifp
= zebra_interface_bfd_read (zclient
->ibuf
, &p
);
284 if (BGP_DEBUG (zebra
, ZEBRA
))
287 prefix2str(&p
, buf
, sizeof(buf
));
288 zlog_debug("Zebra: interface %s bfd destination %s down", ifp
->name
, buf
);
291 /* Bring the peer down if BFD is enabled in BGP */
293 struct listnode
*mnode
, *node
, *nnode
;
297 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
299 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
301 if (!CHECK_FLAG (peer
->flags
, PEER_FLAG_BFD
))
304 if (ifp
== peer
->nexthop
.ifp
)
305 BGP_EVENT_ADD (peer
, BGP_Stop
);
314 bgp_interface_address_add (int command
, struct zclient
*zclient
,
317 struct connected
*ifc
;
319 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
324 if (bgp_debug_zebra(ifc
->address
))
327 prefix2str(ifc
->address
, buf
, sizeof(buf
));
328 zlog_debug("Zebra rcvd: interface %s address add %s",
329 ifc
->ifp
->name
, buf
);
332 if (if_is_operative (ifc
->ifp
))
333 bgp_connected_add (ifc
);
339 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
342 struct connected
*ifc
;
344 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
349 if (bgp_debug_zebra(ifc
->address
))
352 prefix2str(ifc
->address
, buf
, sizeof(buf
));
353 zlog_debug("Zebra rcvd: interface %s address delete %s",
354 ifc
->ifp
->name
, buf
);
357 if (if_is_operative (ifc
->ifp
))
358 bgp_connected_delete (ifc
);
360 connected_free (ifc
);
366 bgp_interface_nbr_address_add (int command
, struct zclient
*zclient
,
369 struct nbr_connected
*ifc
= NULL
;
371 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
376 if (bgp_debug_zebra(ifc
->address
))
379 prefix2str(ifc
->address
, buf
, sizeof(buf
));
380 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
381 ifc
->ifp
->name
, buf
);
384 if (if_is_operative (ifc
->ifp
))
385 bgp_nbr_connected_add (ifc
);
391 bgp_interface_nbr_address_delete (int command
, struct zclient
*zclient
,
394 struct nbr_connected
*ifc
= NULL
;
396 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
401 if (bgp_debug_zebra(ifc
->address
))
404 prefix2str(ifc
->address
, buf
, sizeof(buf
));
405 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
406 ifc
->ifp
->name
, buf
);
409 if (if_is_operative (ifc
->ifp
))
410 bgp_nbr_connected_delete (ifc
);
412 nbr_connected_free (ifc
);
417 /* Zebra route add and delete treatment. */
419 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
422 struct zapi_ipv4 api
;
423 struct in_addr nexthop
;
424 struct prefix_ipv4 p
;
425 unsigned int ifindex
;
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
);
437 memset (&p
, 0, sizeof (struct prefix_ipv4
));
439 p
.prefixlen
= stream_getc (s
);
440 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
442 /* Nexthop, ifindex, distance, metric. */
443 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
445 api
.nexthop_num
= stream_getc (s
);
446 nexthop
.s_addr
= stream_get_ipv4 (s
);
449 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
451 api
.ifindex_num
= stream_getc (s
);
452 ifindex
= stream_getl (s
); /* ifindex, unused */
455 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
456 api
.distance
= stream_getc (s
);
458 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
459 api
.metric
= stream_getl (s
);
463 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
464 api
.tag
= stream_getw (s
);
468 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
470 if (bgp_debug_zebra(&p
))
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])),
477 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
481 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
, ifindex
,
482 api
.metric
, api
.type
, api
.instance
, api
.tag
);
486 if (bgp_debug_zebra(&p
))
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])),
494 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
498 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
, api
.instance
);
505 /* Zebra route add and delete treatment. */
507 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
510 struct zapi_ipv6 api
;
511 struct in6_addr nexthop
;
512 struct prefix_ipv6 p
;
513 unsigned int ifindex
;
516 memset (&nexthop
, 0, sizeof (struct in6_addr
));
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
);
525 memset (&p
, 0, sizeof (struct prefix_ipv6
));
527 p
.prefixlen
= stream_getc (s
);
528 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
530 /* Nexthop, ifindex, distance, metric. */
531 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
533 api
.nexthop_num
= stream_getc (s
);
534 stream_get (&nexthop
, s
, 16);
537 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
539 api
.ifindex_num
= stream_getc (s
);
540 ifindex
= stream_getl (s
); /* ifindex, unused */
543 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
544 api
.distance
= stream_getc (s
);
548 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
549 api
.metric
= stream_getl (s
);
553 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
554 api
.tag
= stream_getw (s
);
558 /* Simply ignore link-local address. */
559 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
562 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
564 if (bgp_debug_zebra(&p
))
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])),
571 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
575 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
, ifindex
,
576 api
.metric
, api
.type
, api
.instance
, api
.tag
);
580 if (bgp_debug_zebra(&p
))
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])),
588 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
592 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
, api
.instance
);
597 #endif /* HAVE_IPV6 */
600 if_lookup_by_ipv4 (struct in_addr
*addr
)
602 struct listnode
*ifnode
;
603 struct listnode
*cnode
;
604 struct interface
*ifp
;
605 struct connected
*connected
;
606 struct prefix_ipv4 p
;
611 p
.prefixlen
= IPV4_MAX_BITLEN
;
613 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
615 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
617 cp
= connected
->address
;
619 if (cp
->family
== AF_INET
)
620 if (prefix_match (cp
, (struct prefix
*)&p
))
628 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
630 struct listnode
*ifnode
;
631 struct listnode
*cnode
;
632 struct interface
*ifp
;
633 struct connected
*connected
;
636 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
638 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
640 cp
= connected
->address
;
642 if (cp
->family
== AF_INET
)
643 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
652 if_lookup_by_ipv6 (struct in6_addr
*addr
, int ifindex
)
654 struct listnode
*ifnode
;
655 struct listnode
*cnode
;
656 struct interface
*ifp
;
657 struct connected
*connected
;
658 struct prefix_ipv6 p
;
663 p
.prefixlen
= IPV6_MAX_BITLEN
;
665 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
667 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
669 cp
= connected
->address
;
671 if (cp
->family
== AF_INET6
)
672 if (prefix_match (cp
, (struct prefix
*)&p
))
674 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
))
676 if (ifindex
== ifp
->ifindex
)
688 if_lookup_by_ipv6_exact (struct in6_addr
*addr
, int ifindex
)
690 struct listnode
*ifnode
;
691 struct listnode
*cnode
;
692 struct interface
*ifp
;
693 struct connected
*connected
;
696 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
698 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
700 cp
= connected
->address
;
702 if (cp
->family
== AF_INET6
)
703 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
705 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
))
707 if (ifindex
== ifp
->ifindex
)
719 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
721 struct listnode
*cnode
;
722 struct connected
*connected
;
725 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
727 cp
= connected
->address
;
729 if (cp
->family
== AF_INET6
)
730 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
732 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
740 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
742 struct listnode
*cnode
;
743 struct connected
*connected
;
746 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
748 cp
= connected
->address
;
750 if (cp
->family
== AF_INET6
)
751 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
753 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
759 #endif /* HAVE_IPV6 */
762 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
764 struct listnode
*cnode
;
765 struct connected
*connected
;
768 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
770 cp
= connected
->address
;
771 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
773 *addr
= cp
->u
.prefix4
;
781 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
782 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
785 struct interface
*ifp
= NULL
;
787 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
794 if (local
->sa
.sa_family
== AF_INET
)
796 nexthop
->v4
= local
->sin
.sin_addr
;
798 ifp
= if_lookup_by_name (peer
->update_if
);
800 ifp
= if_lookup_by_ipv4_exact (&local
->sin
.sin_addr
);
803 if (local
->sa
.sa_family
== AF_INET6
)
805 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
807 if (peer
->conf_if
|| peer
->ifname
)
808 ifp
= if_lookup_by_index (if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
));
810 else if (peer
->update_if
)
811 ifp
= if_lookup_by_name (peer
->update_if
);
813 ifp
= if_lookup_by_ipv6_exact (&local
->sin6
.sin6_addr
,
814 local
->sin6
.sin6_scope_id
);
816 #endif /* HAVE_IPV6 */
823 /* IPv4 connection. */
824 if (local
->sa
.sa_family
== AF_INET
)
828 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
830 /* There is no global nexthop. */
832 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
834 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
835 #endif /* HAVE_IPV6 */
839 /* IPv6 connection. */
840 if (local
->sa
.sa_family
== AF_INET6
)
842 struct interface
*direct
= NULL
;
845 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
846 if (!ret
&& peer
->local_id
.s_addr
)
847 nexthop
->v4
= peer
->local_id
;
850 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
852 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
855 /* If directory connected set link-local address. */
856 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
,
857 remote
->sin6
.sin6_scope_id
);
859 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
862 /* Link-local address. */
864 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
866 /* If there is no global address. Set link-local address as
867 global. I know this break RFC specification... */
869 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
872 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
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;
881 peer
->shared_network
= 0;
883 /* KAME stack specific treatment. */
885 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
886 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
888 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
890 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
891 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
893 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
896 #endif /* HAVE_IPV6 */
900 static struct in6_addr
*
901 bgp_info_to_ipv6_nexthop (struct bgp_info
*info
)
903 struct in6_addr
*nexthop
= NULL
;
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
;
909 /* If both global and link-local address present. */
910 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
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
;
917 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
924 bgp_table_map_apply (struct route_map
*map
, struct prefix
*p
,
925 struct bgp_info
*info
)
927 if (route_map_apply(map
, p
, RMAP_BGP
, info
) != RMAP_DENYMATCH
)
930 if (bgp_debug_zebra(p
))
932 if (p
->family
== AF_INET
)
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])),
938 inet_ntop(AF_INET
, &info
->attr
->nexthop
, buf
[1],
941 if (p
->family
== AF_INET6
)
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])),
947 inet_ntop(AF_INET6
, bgp_info_to_ipv6_nexthop(info
), buf
[1],
955 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
,
956 afi_t afi
, safi_t safi
)
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
;
968 if (zclient
->sock
< 0)
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
))
975 if (bgp
->main_zebra_update_hold
)
981 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
982 tag
= info
->attr
->extra
->tag
;
986 /* When we create an aggregate route we must also install a Null0 route in
988 if (info
->sub_type
== BGP_ROUTE_AGGREGATE
)
989 SET_FLAG (flags
, ZEBRA_FLAG_BLACKHOLE
);
991 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
||
992 info
->sub_type
== BGP_ROUTE_AGGREGATE
)
994 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
995 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
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
))
1002 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1004 nhcount
= 1 + bgp_info_mpath_count (info
);
1006 if (p
->family
== AF_INET
)
1008 struct zapi_ipv4 api
;
1009 struct in_addr
*nexthop
;
1010 char buf
[2][INET_ADDRSTRLEN
];
1011 int valid_nh_count
= 0;
1013 /* resize nexthop buffer size if necessary */
1014 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1015 (sizeof (struct in_addr
*) * nhcount
))
1017 newsize
= (sizeof (struct in_addr
*) * nhcount
);
1018 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1019 if (newsize
== oldsize
)
1021 zlog_err ("can't resize nexthop buffer");
1025 stream_reset (bgp_nexthop_buf
);
1028 /* Metric is currently based on the best-path only. */
1029 metric
= info
->attr
->med
;
1031 if (bgp
->table_map
[afi
][safi
].name
)
1033 BGP_INFO_ATTR_BUF_INIT();
1035 /* Copy info and attributes, so the route-map apply doesn't modify the
1037 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1038 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1040 metric
= info_cp
->attr
->med
;
1041 nexthop
= &info_cp
->attr
->nexthop
;
1043 if (info_cp
->attr
->extra
)
1044 tag
= info_cp
->attr
->extra
->tag
;
1046 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1050 nexthop
= &info
->attr
->nexthop
;
1055 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1059 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1060 mpinfo
= bgp_info_mpath_next (mpinfo
))
1064 if (bgp
->table_map
[afi
][safi
].name
)
1066 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1075 nexthop
= &mpinfo
->attr
->nexthop
;
1078 if (nexthop
== NULL
)
1081 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1086 api
.type
= ZEBRA_ROUTE_BGP
;
1090 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
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.
1097 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1098 api
.nexthop_num
= 0;
1100 api
.nexthop_num
= valid_nh_count
;
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
;
1109 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1113 distance
= bgp_distance_apply (p
, info
, bgp
);
1117 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
1118 api
.distance
= distance
;
1121 if (bgp_debug_zebra(p
))
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])));
1133 zapi_ipv4_route (valid_nh_count
? ZEBRA_IPV4_ROUTE_ADD
: ZEBRA_IPV4_ROUTE_DELETE
,
1134 zclient
, (struct prefix_ipv4
*) p
, &api
);
1138 /* We have to think about a IPv6 link-local address curse. */
1139 if (p
->family
== AF_INET6
)
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
];
1147 /* resize nexthop buffer size if necessary */
1148 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1149 (sizeof (struct in6_addr
*) * nhcount
))
1151 newsize
= (sizeof (struct in6_addr
*) * nhcount
);
1152 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1153 if (newsize
== oldsize
)
1155 zlog_err ("can't resize nexthop buffer");
1159 stream_reset (bgp_nexthop_buf
);
1161 /* resize ifindices buffer size if necessary */
1162 if ((oldsize
= stream_get_size (bgp_ifindices_buf
)) <
1163 (sizeof (unsigned int) * nhcount
))
1165 newsize
= (sizeof (unsigned int) * nhcount
);
1166 newsize
= stream_resize (bgp_ifindices_buf
, newsize
);
1167 if (newsize
== oldsize
)
1169 zlog_err ("can't resize nexthop buffer");
1173 stream_reset (bgp_ifindices_buf
);
1178 assert (info
->attr
->extra
);
1180 /* Metric is currently based on the best-path only. */
1181 metric
= info
->attr
->med
;
1183 if (bgp
->table_map
[afi
][safi
].name
)
1185 BGP_INFO_ATTR_BUF_INIT();
1187 /* Copy info and attributes, so the route-map apply doesn't modify the
1189 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1190 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1192 metric
= info_cp
->attr
->med
;
1193 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1195 if (info_cp
->attr
->extra
)
1196 tag
= info_cp
->attr
->extra
->tag
;
1198 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1202 nexthop
= bgp_info_to_ipv6_nexthop(info
);
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
;
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
;
1217 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1218 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1222 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1223 mpinfo
= bgp_info_mpath_next (mpinfo
))
1228 if (bgp
->table_map
[afi
][safi
].name
)
1230 /* Copy info and attributes, so the route-map apply doesn't modify the
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
);
1239 nexthop
= bgp_info_to_ipv6_nexthop(mpinfo
);
1242 if (nexthop
== NULL
)
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
;
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
;
1258 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1259 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1263 /* Make Zebra API structure. */
1265 api
.type
= ZEBRA_ROUTE_BGP
;
1269 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
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.
1276 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1277 api
.nexthop_num
= 0;
1279 api
.nexthop_num
= valid_nh_count
;
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
;
1290 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1294 if (bgp_debug_zebra(p
))
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])));
1306 zapi_ipv6_route (valid_nh_count
? ZEBRA_IPV6_ROUTE_ADD
: ZEBRA_IPV6_ROUTE_DELETE
,
1307 zclient
, (struct prefix_ipv6
*) p
, &api
);
1309 #endif /* HAVE_IPV6 */
1312 /* Announce all routes of a table to zebra */
1314 bgp_zebra_announce_table (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1316 struct bgp_node
*rn
;
1317 struct bgp_table
*table
;
1318 struct bgp_info
*ri
;
1320 table
= bgp
->rib
[afi
][safi
];
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
);
1332 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
1337 if (zclient
->sock
< 0)
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
))
1348 if (peer
->sort
== BGP_PEER_IBGP
)
1350 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1351 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
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
);
1359 if (p
->family
== AF_INET
)
1361 struct zapi_ipv4 api
;
1362 struct in_addr
*nexthop
;
1365 nexthop
= &info
->attr
->nexthop
;
1367 api
.type
= ZEBRA_ROUTE_BGP
;
1371 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1372 api
.nexthop_num
= 0;
1374 api
.ifindex_num
= 0;
1375 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1376 api
.metric
= info
->attr
->med
;
1378 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1380 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1381 api
.tag
= info
->attr
->extra
->tag
;
1384 if (bgp_debug_zebra(p
))
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])),
1390 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
1395 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
1396 (struct prefix_ipv4
*) p
, &api
);
1399 /* We have to think about a IPv6 link-local address curse. */
1400 if (p
->family
== AF_INET6
)
1402 struct zapi_ipv6 api
;
1403 unsigned int ifindex
;
1404 struct in6_addr
*nexthop
;
1406 assert (info
->attr
->extra
);
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
;
1415 /* If both global and link-local address present. */
1416 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1418 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
1419 if (info
->peer
->nexthop
.ifp
)
1420 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1423 if (nexthop
== NULL
)
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
);
1431 api
.type
= ZEBRA_ROUTE_BGP
;
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
;
1444 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1446 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1447 api
.tag
= info
->attr
->extra
->tag
;
1450 if (bgp_debug_zebra(p
))
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])),
1456 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
1461 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
1462 (struct prefix_ipv6
*) p
, &api
);
1464 #endif /* HAVE_IPV6 */
1467 bgp_redist_lookup (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1469 struct list
*red_list
;
1470 struct listnode
*node
;
1471 struct bgp_redist
*red
;
1473 red_list
= bgp
->redist
[afi
][type
];
1477 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
1478 if (red
->instance
== instance
)
1485 bgp_redist_add (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1487 struct list
*red_list
;
1488 struct bgp_redist
*red
;
1490 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1494 if (!bgp
->redist
[afi
][type
])
1495 bgp
->redist
[afi
][type
] = list_new();
1497 red_list
= bgp
->redist
[afi
][type
];
1498 red
= (struct bgp_redist
*)calloc (1, sizeof(struct bgp_redist
));
1499 red
->instance
= instance
;
1501 listnode_add(red_list
, red
);
1507 bgp_redist_del (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1509 struct bgp_redist
*red
;
1511 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1515 listnode_delete(bgp
->redist
[afi
][type
], red
);
1516 if (!bgp
->redist
[afi
][type
]->count
)
1518 list_free(bgp
->redist
[afi
][type
]);
1519 bgp
->redist
[afi
][type
] = NULL
;
1524 /* Other routes redistribution into BGP. */
1526 bgp_redistribute_set (afi_t afi
, int type
, u_short instance
)
1529 /* Return if already redistribute flag is set. */
1530 if (redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1533 redist_add_instance(&zclient
->redist
[afi
][type
], instance
);
1535 /* Return if zebra connection is not established. */
1536 if (zclient
->sock
< 0)
1539 if (BGP_DEBUG (zebra
, ZEBRA
))
1540 zlog_debug("Zebra send: redistribute add afi %d %s %d", afi
,
1541 zebra_route_string(type
), instance
);
1543 /* Send distribute add message to zebra. */
1544 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, instance
);
1550 bgp_redistribute_resend (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1552 /* Return if zebra connection is not established. */
1553 if (zclient
->sock
< 0)
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
);
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
);
1567 /* Redistribute with route-map specification. */
1569 bgp_redistribute_rmap_set (struct bgp_redist
*red
, const char *name
)
1572 && (strcmp (red
->rmap
.name
, name
) == 0))
1576 free (red
->rmap
.name
);
1577 red
->rmap
.name
= strdup (name
);
1578 red
->rmap
.map
= route_map_lookup_by_name (name
);
1583 /* Redistribute with metric specification. */
1585 bgp_redistribute_metric_set (struct bgp_redist
*red
, u_int32_t metric
)
1587 if (red
->redist_metric_flag
1588 && red
->redist_metric
== metric
)
1591 red
->redist_metric_flag
= 1;
1592 red
->redist_metric
= metric
;
1597 /* Unset redistribution. */
1599 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1601 struct bgp_redist
*red
;
1603 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1607 /* Unset route-map. */
1609 free (red
->rmap
.name
);
1610 red
->rmap
.name
= NULL
;
1611 red
->rmap
.map
= NULL
;
1614 red
->redist_metric_flag
= 0;
1615 red
->redist_metric
= 0;
1617 bgp_redist_del(bgp
, afi
, type
, instance
);
1619 /* Return if zebra connection is disabled. */
1620 if (!redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1622 redist_del_instance(&zclient
->redist
[afi
][type
], instance
);
1624 if (zclient
->sock
>= 0)
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
);
1633 /* Withdraw redistributed routes from current BGP's routing table. */
1634 bgp_redistribute_withdraw (bgp
, afi
, type
, instance
);
1640 bgp_zclient_reset (void)
1642 zclient_reset (zclient
);
1646 bgp_zebra_init (void)
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
;
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
;
1669 /* Interface related init. */
1672 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);
1673 bgp_ifindices_buf
= stream_new(BGP_IFINDICES_BUF_SIZE
);