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"
40 /* All information about zebra. */
41 static struct zclient
*zclient
= NULL
;
42 struct in_addr router_id_zebra
;
44 /* Router-id update message from zebra. */
46 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
48 struct prefix router_id
;
49 struct listnode
*node
, *nnode
;
52 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
53 router_id_zebra
= router_id
.u
.prefix4
;
55 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
57 if (!bgp
->router_id_static
.s_addr
)
58 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
64 /* Inteface addition message from zebra. */
66 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
68 struct interface
*ifp
;
70 ifp
= zebra_interface_add_read (zclient
->ibuf
);
76 bgp_interface_delete (int command
, struct zclient
*zclient
,
80 struct interface
*ifp
;
83 ifp
= zebra_interface_state_read (s
);
84 ifp
->ifindex
= IFINDEX_INTERNAL
;
90 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
93 struct interface
*ifp
;
95 struct listnode
*node
, *nnode
;
98 ifp
= zebra_interface_state_read (s
);
103 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
104 bgp_connected_add (c
);
110 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
113 struct interface
*ifp
;
115 struct listnode
*node
, *nnode
;
118 ifp
= zebra_interface_state_read (s
);
122 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
123 bgp_connected_delete (c
);
125 /* Fast external-failover (Currently IPv4 only) */
127 struct listnode
*mnode
;
130 struct interface
*peer_if
;
132 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
134 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
137 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
142 if (peer
->su
.sa
.sa_family
== AF_INET
)
143 peer_if
= if_lookup_by_ipv4 (&peer
->su
.sin
.sin_addr
);
148 BGP_EVENT_ADD (peer
, BGP_Stop
);
157 bgp_interface_address_add (int command
, struct zclient
*zclient
,
160 struct connected
*ifc
;
162 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
167 if (if_is_operative (ifc
->ifp
))
168 bgp_connected_add (ifc
);
174 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
177 struct connected
*ifc
;
179 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
184 if (if_is_operative (ifc
->ifp
))
185 bgp_connected_delete (ifc
);
187 connected_free (ifc
);
192 /* Zebra route add and delete treatment. */
194 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
197 struct zapi_ipv4 api
;
198 unsigned long ifindex
;
199 struct in_addr nexthop
;
200 struct prefix_ipv4 p
;
206 /* Type, flags, message. */
207 api
.type
= stream_getc (s
);
208 api
.flags
= stream_getc (s
);
209 api
.message
= stream_getc (s
);
212 memset (&p
, 0, sizeof (struct prefix_ipv4
));
214 p
.prefixlen
= stream_getc (s
);
215 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
217 /* Nexthop, ifindex, distance, metric. */
218 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
220 api
.nexthop_num
= stream_getc (s
);
221 nexthop
.s_addr
= stream_get_ipv4 (s
);
223 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
225 api
.ifindex_num
= stream_getc (s
);
226 ifindex
= stream_getl (s
);
228 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
229 api
.distance
= stream_getc (s
);
230 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
231 api
.metric
= stream_getl (s
);
235 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
236 bgp_redistribute_add ((struct prefix
*)&p
, &nexthop
, api
.metric
, api
.type
);
238 bgp_redistribute_delete ((struct prefix
*)&p
, api
.type
);
244 /* Zebra route add and delete treatment. */
246 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
249 struct zapi_ipv6 api
;
250 unsigned long ifindex
;
251 struct in6_addr nexthop
;
252 struct prefix_ipv6 p
;
256 memset (&nexthop
, 0, sizeof (struct in6_addr
));
258 /* Type, flags, message. */
259 api
.type
= stream_getc (s
);
260 api
.flags
= stream_getc (s
);
261 api
.message
= stream_getc (s
);
264 memset (&p
, 0, sizeof (struct prefix_ipv6
));
266 p
.prefixlen
= stream_getc (s
);
267 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
269 /* Nexthop, ifindex, distance, metric. */
270 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
272 api
.nexthop_num
= stream_getc (s
);
273 stream_get (&nexthop
, s
, 16);
275 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
277 api
.ifindex_num
= stream_getc (s
);
278 ifindex
= stream_getl (s
);
280 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
281 api
.distance
= stream_getc (s
);
284 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
285 api
.metric
= stream_getl (s
);
289 /* Simply ignore link-local address. */
290 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
293 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
294 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, api
.metric
, api
.type
);
296 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
300 #endif /* HAVE_IPV6 */
303 if_lookup_by_ipv4 (struct in_addr
*addr
)
305 struct listnode
*ifnode
;
306 struct listnode
*cnode
;
307 struct interface
*ifp
;
308 struct connected
*connected
;
309 struct prefix_ipv4 p
;
314 p
.prefixlen
= IPV4_MAX_BITLEN
;
316 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
318 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
320 cp
= connected
->address
;
322 if (cp
->family
== AF_INET
)
323 if (prefix_match (cp
, (struct prefix
*)&p
))
331 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
333 struct listnode
*ifnode
;
334 struct listnode
*cnode
;
335 struct interface
*ifp
;
336 struct connected
*connected
;
339 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
341 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
343 cp
= connected
->address
;
345 if (cp
->family
== AF_INET
)
346 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
355 if_lookup_by_ipv6 (struct in6_addr
*addr
)
357 struct listnode
*ifnode
;
358 struct listnode
*cnode
;
359 struct interface
*ifp
;
360 struct connected
*connected
;
361 struct prefix_ipv6 p
;
366 p
.prefixlen
= IPV6_MAX_BITLEN
;
368 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
370 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
372 cp
= connected
->address
;
374 if (cp
->family
== AF_INET6
)
375 if (prefix_match (cp
, (struct prefix
*)&p
))
383 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
385 struct listnode
*ifnode
;
386 struct listnode
*cnode
;
387 struct interface
*ifp
;
388 struct connected
*connected
;
391 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
393 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
395 cp
= connected
->address
;
397 if (cp
->family
== AF_INET6
)
398 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
406 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
408 struct listnode
*cnode
;
409 struct connected
*connected
;
412 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
414 cp
= connected
->address
;
416 if (cp
->family
== AF_INET6
)
417 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
419 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
427 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
429 struct listnode
*cnode
;
430 struct connected
*connected
;
433 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
435 cp
= connected
->address
;
437 if (cp
->family
== AF_INET6
)
438 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
440 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
446 #endif /* HAVE_IPV6 */
449 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
450 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
453 struct interface
*ifp
= NULL
;
455 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
462 if (local
->sa
.sa_family
== AF_INET
)
464 nexthop
->v4
= local
->sin
.sin_addr
;
465 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
468 if (local
->sa
.sa_family
== AF_INET6
)
470 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
473 ifp
= if_lookup_by_index (if_nametoindex (peer
->ifname
));
476 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
478 #endif /* HAVE_IPV6 */
485 /* IPv4 connection. */
486 if (local
->sa
.sa_family
== AF_INET
)
490 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
492 /* There is no global nexthop. */
494 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
496 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
497 #endif /* HAVE_IPV6 */
501 /* IPv6 connection. */
502 if (local
->sa
.sa_family
== AF_INET6
)
504 struct interface
*direct
= NULL
;
506 /* IPv4 nexthop. I don't care about it. */
507 if (peer
->local_id
.s_addr
)
508 nexthop
->v4
= peer
->local_id
;
511 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
513 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
516 /* If directory connected set link-local address. */
517 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
519 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
522 /* Link-local address. */
524 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
526 /* If there is no global address. Set link-local address as
527 global. I know this break RFC specification... */
529 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
532 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
537 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
538 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
539 peer
->shared_network
= 1;
541 peer
->shared_network
= 0;
543 /* KAME stack specific treatment. */
545 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
546 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
548 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
550 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
551 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
553 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
556 #endif /* HAVE_IPV6 */
562 bgp_ifindex_by_nexthop (struct in6_addr
*addr
)
564 struct listnode
*ifnode
;
565 struct listnode
*cnode
;
566 struct interface
*ifp
;
567 struct connected
*connected
;
568 struct prefix_ipv6 p
;
572 p
.prefixlen
= IPV6_MAX_BITLEN
;
574 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
576 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
580 cp
= connected
->address
;
582 if (cp
->family
== AF_INET6
)
584 if (prefix_match (cp
, (struct prefix
*)&p
))
591 #endif /* HAVE_IPV6 */
594 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
)
600 if (zclient
->sock
< 0)
603 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
609 if (peer_sort (peer
) == BGP_PEER_IBGP
|| peer_sort (peer
) == BGP_PEER_CONFED
)
611 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
612 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
615 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
616 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
617 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
619 if (p
->family
== AF_INET
)
621 struct zapi_ipv4 api
;
622 struct in_addr
*nexthop
;
625 nexthop
= &info
->attr
->nexthop
;
627 api
.type
= ZEBRA_ROUTE_BGP
;
629 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
631 api
.nexthop
= &nexthop
;
633 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
634 api
.metric
= info
->attr
->med
;
636 distance
= bgp_distance_apply (p
, info
, bgp
);
640 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
641 api
.distance
= distance
;
643 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
,
644 (struct prefix_ipv4
*) p
, &api
);
647 /* We have to think about a IPv6 link-local address curse. */
648 if (p
->family
== AF_INET6
)
650 unsigned int ifindex
;
651 struct in6_addr
*nexthop
;
652 struct zapi_ipv6 api
;
657 /* Only global address nexthop exists. */
658 if (info
->attr
->mp_nexthop_len
== 16)
659 nexthop
= &info
->attr
->mp_nexthop_global
;
661 /* If both global and link-local address present. */
662 if (info
->attr
->mp_nexthop_len
== 32)
664 /* Workaround for Cisco's nexthop bug. */
665 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->mp_nexthop_global
)
666 && peer
->su_remote
->sa
.sa_family
== AF_INET6
)
667 nexthop
= &peer
->su_remote
->sin6
.sin6_addr
;
669 nexthop
= &info
->attr
->mp_nexthop_local
;
671 if (info
->peer
->nexthop
.ifp
)
672 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
678 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
680 if (info
->peer
->ifname
)
681 ifindex
= if_nametoindex (info
->peer
->ifname
);
682 else if (info
->peer
->nexthop
.ifp
)
683 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
686 /* Make Zebra API structure. */
688 api
.type
= ZEBRA_ROUTE_BGP
;
690 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
692 api
.nexthop
= &nexthop
;
693 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
695 api
.ifindex
= &ifindex
;
696 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
697 api
.metric
= info
->attr
->med
;
699 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD
, zclient
,
700 (struct prefix_ipv6
*) p
, &api
);
702 #endif /* HAVE_IPV6 */
706 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
)
711 if (zclient
->sock
< 0)
714 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
720 if (peer_sort (peer
) == BGP_PEER_IBGP
)
722 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
723 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
726 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
727 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
728 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
730 if (p
->family
== AF_INET
)
732 struct zapi_ipv4 api
;
733 struct in_addr
*nexthop
;
736 nexthop
= &info
->attr
->nexthop
;
738 api
.type
= ZEBRA_ROUTE_BGP
;
740 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
742 api
.nexthop
= &nexthop
;
744 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
745 api
.metric
= info
->attr
->med
;
747 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
748 (struct prefix_ipv4
*) p
, &api
);
751 /* We have to think about a IPv6 link-local address curse. */
752 if (p
->family
== AF_INET6
)
754 struct zapi_ipv6 api
;
755 unsigned int ifindex
;
756 struct in6_addr
*nexthop
;
761 /* Only global address nexthop exists. */
762 if (info
->attr
->mp_nexthop_len
== 16)
763 nexthop
= &info
->attr
->mp_nexthop_global
;
765 /* If both global and link-local address present. */
766 if (info
->attr
->mp_nexthop_len
== 32)
768 nexthop
= &info
->attr
->mp_nexthop_local
;
769 if (info
->peer
->nexthop
.ifp
)
770 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
776 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
777 if (info
->peer
->ifname
)
778 ifindex
= if_nametoindex (info
->peer
->ifname
);
781 api
.type
= ZEBRA_ROUTE_BGP
;
783 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
785 api
.nexthop
= &nexthop
;
786 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
788 api
.ifindex
= &ifindex
;
789 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
790 api
.metric
= info
->attr
->med
;
792 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
793 (struct prefix_ipv6
*) p
, &api
);
795 #endif /* HAVE_IPV6 */
798 /* Other routes redistribution into BGP. */
800 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
802 /* Set flag to BGP instance. */
803 bgp
->redist
[afi
][type
] = 1;
805 /* Return if already redistribute flag is set. */
806 if (zclient
->redist
[type
])
809 zclient
->redist
[type
] = 1;
811 /* Return if zebra connection is not established. */
812 if (zclient
->sock
< 0)
815 /* Send distribute add message to zebra. */
816 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
821 /* Redistribute with route-map specification. */
823 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
826 if (bgp
->rmap
[afi
][type
].name
827 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
830 if (bgp
->rmap
[afi
][type
].name
)
831 free (bgp
->rmap
[afi
][type
].name
);
832 bgp
->rmap
[afi
][type
].name
= strdup (name
);
833 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
838 /* Redistribute with metric specification. */
840 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
843 if (bgp
->redist_metric_flag
[afi
][type
]
844 && bgp
->redist_metric
[afi
][type
] == metric
)
847 bgp
->redist_metric_flag
[afi
][type
] = 1;
848 bgp
->redist_metric
[afi
][type
] = metric
;
853 /* Unset redistribution. */
855 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
857 /* Unset flag from BGP instance. */
858 bgp
->redist
[afi
][type
] = 0;
860 /* Unset route-map. */
861 if (bgp
->rmap
[afi
][type
].name
)
862 free (bgp
->rmap
[afi
][type
].name
);
863 bgp
->rmap
[afi
][type
].name
= NULL
;
864 bgp
->rmap
[afi
][type
].map
= NULL
;
867 bgp
->redist_metric_flag
[afi
][type
] = 0;
868 bgp
->redist_metric
[afi
][type
] = 0;
870 /* Return if zebra connection is disabled. */
871 if (! zclient
->redist
[type
])
873 zclient
->redist
[type
] = 0;
875 if (bgp
->redist
[AFI_IP
][type
] == 0
876 && bgp
->redist
[AFI_IP6
][type
] == 0
877 && zclient
->sock
>= 0)
878 /* Send distribute delete message to zebra. */
879 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
881 /* Withdraw redistributed routes from current BGP's routing table. */
882 bgp_redistribute_withdraw (bgp
, afi
, type
);
887 /* Unset redistribution route-map configuration. */
889 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
891 if (! bgp
->rmap
[afi
][type
].name
)
894 /* Unset route-map. */
895 free (bgp
->rmap
[afi
][type
].name
);
896 bgp
->rmap
[afi
][type
].name
= NULL
;
897 bgp
->rmap
[afi
][type
].map
= NULL
;
902 /* Unset redistribution metric configuration. */
904 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
906 if (! bgp
->redist_metric_flag
[afi
][type
])
910 bgp
->redist_metric_flag
[afi
][type
] = 0;
911 bgp
->redist_metric
[afi
][type
] = 0;
917 bgp_zclient_reset (void)
919 zclient_reset (zclient
);
923 bgp_zebra_init (void)
925 /* Set default values. */
926 zclient
= zclient_new ();
927 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
928 zclient
->router_id_update
= bgp_router_id_update
;
929 zclient
->interface_add
= bgp_interface_add
;
930 zclient
->interface_delete
= bgp_interface_delete
;
931 zclient
->interface_address_add
= bgp_interface_address_add
;
932 zclient
->interface_address_delete
= bgp_interface_address_delete
;
933 zclient
->ipv4_route_add
= zebra_read_ipv4
;
934 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
935 zclient
->interface_up
= bgp_interface_up
;
936 zclient
->interface_down
= bgp_interface_down
;
938 zclient
->ipv6_route_add
= zebra_read_ipv6
;
939 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
940 #endif /* HAVE_IPV6 */
942 /* Interface related init. */