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
;
43 /* Update default router id. */
45 bgp_if_update (struct interface
*ifp
)
53 for (cn
= listhead (ifp
->connected
); cn
; nextnode (cn
))
60 if (co
->address
->family
== AF_INET
)
62 addr
= co
->address
->u
.prefix4
;
65 if (IPV4_NET127 (ntohl (addr
.s_addr
)))
68 LIST_LOOP (bm
->bgp
, bgp
, nn
)
70 /* Respect configured router id */
71 if (! (bgp
->config
& BGP_CONFIG_ROUTER_ID
))
72 if (ntohl (bgp
->router_id
.s_addr
) < ntohl (addr
.s_addr
))
74 bgp
->router_id
= addr
;
75 LIST_LOOP (bgp
->peer
, peer
, nm
)
77 peer
->local_id
= addr
;
90 struct interface
*ifp
;
92 for (node
= listhead (iflist
); node
; node
= nextnode (node
))
100 /* Inteface addition message from zebra. */
102 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
104 struct interface
*ifp
;
106 ifp
= zebra_interface_add_read (zclient
->ibuf
);
113 bgp_interface_delete (int command
, struct zclient
*zclient
,
117 struct interface
*ifp
;
120 ifp
= zebra_interface_state_read (s
);
126 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
129 struct interface
*ifp
;
134 ifp
= zebra_interface_state_read (s
);
139 for (node
= listhead (ifp
->connected
); node
; nextnode (node
))
142 bgp_connected_add (c
);
149 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
152 struct interface
*ifp
;
157 ifp
= zebra_interface_state_read (s
);
161 for (node
= listhead (ifp
->connected
); node
; nextnode (node
))
164 bgp_connected_delete (c
);
167 /* Fast external-failover (Currently IPv4 only) */
169 struct listnode
*nn
, *nm
;
172 struct interface
*peer_if
;
174 LIST_LOOP (bm
->bgp
, bgp
, nn
)
176 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
179 LIST_LOOP (bgp
->peer
, peer
, nm
)
184 if (peer
->su
.sa
.sa_family
== AF_INET
)
185 peer_if
= if_lookup_by_ipv4 (&peer
->su
.sin
.sin_addr
);
190 BGP_EVENT_ADD (peer
, BGP_Stop
);
199 bgp_interface_address_add (int command
, struct zclient
*zclient
,
202 struct connected
*ifc
;
204 ifc
= zebra_interface_address_add_read (zclient
->ibuf
);
209 bgp_if_update (ifc
->ifp
);
211 if (if_is_operative (ifc
->ifp
))
212 bgp_connected_add (ifc
);
218 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
221 struct connected
*ifc
;
223 ifc
= zebra_interface_address_delete_read (zclient
->ibuf
);
228 bgp_if_update (ifc
->ifp
);
230 if (if_is_operative (ifc
->ifp
))
231 bgp_connected_delete (ifc
);
233 connected_free (ifc
);
238 /* Zebra route add and delete treatment. */
240 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
243 struct zapi_ipv4 api
;
244 unsigned long ifindex
;
245 struct in_addr nexthop
;
246 struct prefix_ipv4 p
;
252 /* Type, flags, message. */
253 api
.type
= stream_getc (s
);
254 api
.flags
= stream_getc (s
);
255 api
.message
= stream_getc (s
);
258 memset (&p
, 0, sizeof (struct prefix_ipv4
));
260 p
.prefixlen
= stream_getc (s
);
261 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
263 /* Nexthop, ifindex, distance, metric. */
264 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
266 api
.nexthop_num
= stream_getc (s
);
267 nexthop
.s_addr
= stream_get_ipv4 (s
);
269 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
271 api
.ifindex_num
= stream_getc (s
);
272 ifindex
= stream_getl (s
);
274 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
275 api
.distance
= stream_getc (s
);
276 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
277 api
.metric
= stream_getl (s
);
281 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
282 bgp_redistribute_add ((struct prefix
*)&p
, &nexthop
, api
.metric
, api
.type
);
284 bgp_redistribute_delete ((struct prefix
*)&p
, api
.type
);
290 /* Zebra route add and delete treatment. */
292 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
295 struct zapi_ipv6 api
;
296 unsigned long ifindex
;
297 struct in6_addr nexthop
;
298 struct prefix_ipv6 p
;
302 memset (&nexthop
, 0, sizeof (struct in6_addr
));
304 /* Type, flags, message. */
305 api
.type
= stream_getc (s
);
306 api
.flags
= stream_getc (s
);
307 api
.message
= stream_getc (s
);
310 memset (&p
, 0, sizeof (struct prefix_ipv6
));
312 p
.prefixlen
= stream_getc (s
);
313 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
315 /* Nexthop, ifindex, distance, metric. */
316 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
318 api
.nexthop_num
= stream_getc (s
);
319 stream_get (&nexthop
, s
, 16);
321 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
323 api
.ifindex_num
= stream_getc (s
);
324 ifindex
= stream_getl (s
);
326 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
327 api
.distance
= stream_getc (s
);
330 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
331 api
.metric
= stream_getl (s
);
335 /* Simply ignore link-local address. */
336 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
339 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
340 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, api
.metric
, api
.type
);
342 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
346 #endif /* HAVE_IPV6 */
349 if_lookup_by_ipv4 (struct in_addr
*addr
)
353 struct interface
*ifp
;
354 struct connected
*connected
;
355 struct prefix_ipv4 p
;
360 p
.prefixlen
= IPV4_MAX_BITLEN
;
362 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
364 ifp
= getdata (ifnode
);
366 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
368 connected
= getdata (cnode
);
369 cp
= connected
->address
;
371 if (cp
->family
== AF_INET
)
372 if (prefix_match (cp
, (struct prefix
*)&p
))
380 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
384 struct interface
*ifp
;
385 struct connected
*connected
;
388 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
390 ifp
= getdata (ifnode
);
392 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
394 connected
= getdata (cnode
);
395 cp
= connected
->address
;
397 if (cp
->family
== AF_INET
)
398 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
407 if_lookup_by_ipv6 (struct in6_addr
*addr
)
411 struct interface
*ifp
;
412 struct connected
*connected
;
413 struct prefix_ipv6 p
;
418 p
.prefixlen
= IPV6_MAX_BITLEN
;
420 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
422 ifp
= getdata (ifnode
);
424 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
426 connected
= getdata (cnode
);
427 cp
= connected
->address
;
429 if (cp
->family
== AF_INET6
)
430 if (prefix_match (cp
, (struct prefix
*)&p
))
438 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
442 struct interface
*ifp
;
443 struct connected
*connected
;
446 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
448 ifp
= getdata (ifnode
);
450 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
452 connected
= getdata (cnode
);
453 cp
= connected
->address
;
455 if (cp
->family
== AF_INET6
)
456 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
464 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
467 struct connected
*connected
;
470 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
472 connected
= getdata (cnode
);
473 cp
= connected
->address
;
475 if (cp
->family
== AF_INET6
)
476 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
478 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
486 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
489 struct connected
*connected
;
492 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
494 connected
= getdata (cnode
);
495 cp
= connected
->address
;
497 if (cp
->family
== AF_INET6
)
498 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
500 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
506 #endif /* HAVE_IPV6 */
509 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
510 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
513 struct interface
*ifp
= NULL
;
515 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
522 if (local
->sa
.sa_family
== AF_INET
)
524 nexthop
->v4
= local
->sin
.sin_addr
;
525 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
528 if (local
->sa
.sa_family
== AF_INET6
)
530 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
533 ifp
= if_lookup_by_index (if_nametoindex (peer
->ifname
));
536 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
538 #endif /* HAVE_IPV6 */
545 /* IPv4 connection. */
546 if (local
->sa
.sa_family
== AF_INET
)
550 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
552 /* There is no global nexthop. */
554 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
556 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
557 #endif /* HAVE_IPV6 */
561 /* IPv6 connection. */
562 if (local
->sa
.sa_family
== AF_INET6
)
564 struct interface
*direct
= NULL
;
566 /* IPv4 nexthop. I don't care about it. */
567 if (peer
->local_id
.s_addr
)
568 nexthop
->v4
= peer
->local_id
;
571 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
573 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
576 /* If directory connected set link-local address. */
577 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
579 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
582 /* Link-local address. */
584 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
586 /* If there is no global address. Set link-local address as
587 global. I know this break RFC specification... */
589 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
592 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
597 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
598 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
599 peer
->shared_network
= 1;
601 peer
->shared_network
= 0;
603 /* KAME stack specific treatment. */
605 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
606 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
608 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
610 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
611 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
613 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
616 #endif /* HAVE_IPV6 */
622 bgp_ifindex_by_nexthop (struct in6_addr
*addr
)
626 struct interface
*ifp
;
627 struct connected
*connected
;
628 struct prefix_ipv6 p
;
632 p
.prefixlen
= IPV6_MAX_BITLEN
;
634 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
636 ifp
= getdata (ifnode
);
638 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
642 connected
= getdata (cnode
);
643 cp
= connected
->address
;
645 if (cp
->family
== AF_INET6
)
647 if (prefix_match (cp
, (struct prefix
*)&p
))
654 #endif /* HAVE_IPV6 */
657 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
)
663 if (zclient
->sock
< 0)
666 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
672 if (peer_sort (peer
) == BGP_PEER_IBGP
|| peer_sort (peer
) == BGP_PEER_CONFED
)
674 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
675 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
678 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
679 || CHECK_FLAG (peer
->flags
, PEER_FLAG_ENFORCE_MULTIHOP
))
680 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
682 if (p
->family
== AF_INET
)
684 struct zapi_ipv4 api
;
685 struct in_addr
*nexthop
;
688 nexthop
= &info
->attr
->nexthop
;
690 api
.type
= ZEBRA_ROUTE_BGP
;
692 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
694 api
.nexthop
= &nexthop
;
696 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
697 api
.metric
= info
->attr
->med
;
699 distance
= bgp_distance_apply (p
, info
, bgp
);
703 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
704 api
.distance
= distance
;
706 zapi_ipv4_add (zclient
, (struct prefix_ipv4
*) p
, &api
);
709 /* We have to think about a IPv6 link-local address curse. */
710 if (p
->family
== AF_INET6
)
712 unsigned int ifindex
;
713 struct in6_addr
*nexthop
;
714 struct zapi_ipv6 api
;
719 /* Only global address nexthop exists. */
720 if (info
->attr
->mp_nexthop_len
== 16)
721 nexthop
= &info
->attr
->mp_nexthop_global
;
723 /* If both global and link-local address present. */
724 if (info
->attr
->mp_nexthop_len
== 32)
726 /* Workaround for Cisco's nexthop bug. */
727 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->mp_nexthop_global
)
728 && peer
->su_remote
->sa
.sa_family
== AF_INET6
)
729 nexthop
= &peer
->su_remote
->sin6
.sin6_addr
;
731 nexthop
= &info
->attr
->mp_nexthop_local
;
733 if (info
->peer
->nexthop
.ifp
)
734 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
740 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
742 if (info
->peer
->ifname
)
743 ifindex
= if_nametoindex (info
->peer
->ifname
);
744 else if (info
->peer
->nexthop
.ifp
)
745 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
748 /* Make Zebra API structure. */
750 api
.type
= ZEBRA_ROUTE_BGP
;
752 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
754 api
.nexthop
= &nexthop
;
755 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
757 api
.ifindex
= &ifindex
;
758 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
759 api
.metric
= info
->attr
->med
;
761 zapi_ipv6_add (zclient
, (struct prefix_ipv6
*) p
, &api
);
763 #endif /* HAVE_IPV6 */
767 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
)
772 if (zclient
->sock
< 0)
775 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
781 if (peer_sort (peer
) == BGP_PEER_IBGP
)
783 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
784 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
787 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
788 || CHECK_FLAG (peer
->flags
, PEER_FLAG_ENFORCE_MULTIHOP
))
789 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
791 if (p
->family
== AF_INET
)
793 struct zapi_ipv4 api
;
794 struct in_addr
*nexthop
;
797 nexthop
= &info
->attr
->nexthop
;
799 api
.type
= ZEBRA_ROUTE_BGP
;
801 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
803 api
.nexthop
= &nexthop
;
805 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
806 api
.metric
= info
->attr
->med
;
808 zapi_ipv4_delete (zclient
, (struct prefix_ipv4
*) p
, &api
);
811 /* We have to think about a IPv6 link-local address curse. */
812 if (p
->family
== AF_INET6
)
814 struct zapi_ipv6 api
;
815 unsigned int ifindex
;
816 struct in6_addr
*nexthop
;
821 /* Only global address nexthop exists. */
822 if (info
->attr
->mp_nexthop_len
== 16)
823 nexthop
= &info
->attr
->mp_nexthop_global
;
825 /* If both global and link-local address present. */
826 if (info
->attr
->mp_nexthop_len
== 32)
828 nexthop
= &info
->attr
->mp_nexthop_local
;
829 if (info
->peer
->nexthop
.ifp
)
830 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
836 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
837 if (info
->peer
->ifname
)
838 ifindex
= if_nametoindex (info
->peer
->ifname
);
841 api
.type
= ZEBRA_ROUTE_BGP
;
843 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
845 api
.nexthop
= &nexthop
;
846 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
848 api
.ifindex
= &ifindex
;
849 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
850 api
.metric
= info
->attr
->med
;
852 zapi_ipv6_delete (zclient
, (struct prefix_ipv6
*) p
, &api
);
854 #endif /* HAVE_IPV6 */
857 /* Other routes redistribution into BGP. */
859 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
861 /* Set flag to BGP instance. */
862 bgp
->redist
[afi
][type
] = 1;
864 /* Return if already redistribute flag is set. */
865 if (zclient
->redist
[type
])
868 zclient
->redist
[type
] = 1;
870 /* Return if zebra connection is not established. */
871 if (zclient
->sock
< 0)
874 /* Send distribute add message to zebra. */
875 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
->sock
, type
);
880 /* Redistribute with route-map specification. */
882 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
, char *name
)
884 if (bgp
->rmap
[afi
][type
].name
885 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
888 if (bgp
->rmap
[afi
][type
].name
)
889 free (bgp
->rmap
[afi
][type
].name
);
890 bgp
->rmap
[afi
][type
].name
= strdup (name
);
891 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
896 /* Redistribute with metric specification. */
898 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
901 if (bgp
->redist_metric_flag
[afi
][type
]
902 && bgp
->redist_metric
[afi
][type
] == metric
)
905 bgp
->redist_metric_flag
[afi
][type
] = 1;
906 bgp
->redist_metric
[afi
][type
] = metric
;
911 /* Unset redistribution. */
913 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
915 /* Unset flag from BGP instance. */
916 bgp
->redist
[afi
][type
] = 0;
918 /* Unset route-map. */
919 if (bgp
->rmap
[afi
][type
].name
)
920 free (bgp
->rmap
[afi
][type
].name
);
921 bgp
->rmap
[afi
][type
].name
= NULL
;
922 bgp
->rmap
[afi
][type
].map
= NULL
;
925 bgp
->redist_metric_flag
[afi
][type
] = 0;
926 bgp
->redist_metric
[afi
][type
] = 0;
928 /* Return if zebra connection is disabled. */
929 if (! zclient
->redist
[type
])
931 zclient
->redist
[type
] = 0;
933 if (bgp
->redist
[AFI_IP
][type
] == 0
934 && bgp
->redist
[AFI_IP6
][type
] == 0
935 && zclient
->sock
>= 0)
936 /* Send distribute delete message to zebra. */
937 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
->sock
, type
);
939 /* Withdraw redistributed routes from current BGP's routing table. */
940 bgp_redistribute_withdraw (bgp
, afi
, type
);
945 /* Unset redistribution route-map configuration. */
947 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
949 if (! bgp
->rmap
[afi
][type
].name
)
952 /* Unset route-map. */
953 free (bgp
->rmap
[afi
][type
].name
);
954 bgp
->rmap
[afi
][type
].name
= NULL
;
955 bgp
->rmap
[afi
][type
].map
= NULL
;
960 /* Unset redistribution metric configuration. */
962 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
964 if (! bgp
->redist_metric_flag
[afi
][type
])
968 bgp
->redist_metric_flag
[afi
][type
] = 0;
969 bgp
->redist_metric
[afi
][type
] = 0;
977 zclient_reset (zclient
);
981 bgp_zebra_init (int enable
)
983 /* Set default values. */
984 zclient
= zclient_new ();
985 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
986 zclient
->interface_add
= bgp_interface_add
;
987 zclient
->interface_delete
= bgp_interface_delete
;
988 zclient
->interface_address_add
= bgp_interface_address_add
;
989 zclient
->interface_address_delete
= bgp_interface_address_delete
;
990 zclient
->ipv4_route_add
= zebra_read_ipv4
;
991 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
992 zclient
->interface_up
= bgp_interface_up
;
993 zclient
->interface_down
= bgp_interface_down
;
995 zclient
->ipv6_route_add
= zebra_read_ipv6
;
996 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
997 #endif /* HAVE_IPV6 */
999 /* Interface related init. */