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
;
52 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
53 router_id_zebra
= router_id
.u
.prefix4
;
55 LIST_LOOP (bm
->bgp
, bgp
, nn
)
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
);
89 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
92 struct interface
*ifp
;
94 struct listnode
*node
;
97 ifp
= zebra_interface_state_read (s
);
102 for (node
= listhead (ifp
->connected
); node
; nextnode (node
))
105 bgp_connected_add (c
);
112 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
115 struct interface
*ifp
;
117 struct listnode
*node
;
120 ifp
= zebra_interface_state_read (s
);
124 for (node
= listhead (ifp
->connected
); node
; nextnode (node
))
127 bgp_connected_delete (c
);
130 /* Fast external-failover (Currently IPv4 only) */
132 struct listnode
*nn
, *nm
;
135 struct interface
*peer_if
;
137 LIST_LOOP (bm
->bgp
, bgp
, nn
)
139 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
142 LIST_LOOP (bgp
->peer
, peer
, nm
)
147 if (peer
->su
.sa
.sa_family
== AF_INET
)
148 peer_if
= if_lookup_by_ipv4 (&peer
->su
.sin
.sin_addr
);
153 BGP_EVENT_ADD (peer
, BGP_Stop
);
162 bgp_interface_address_add (int command
, struct zclient
*zclient
,
165 struct connected
*ifc
;
167 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
172 if (if_is_operative (ifc
->ifp
))
173 bgp_connected_add (ifc
);
179 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
182 struct connected
*ifc
;
184 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
189 if (if_is_operative (ifc
->ifp
))
190 bgp_connected_delete (ifc
);
192 connected_free (ifc
);
197 /* Zebra route add and delete treatment. */
199 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
202 struct zapi_ipv4 api
;
203 unsigned long ifindex
;
204 struct in_addr nexthop
;
205 struct prefix_ipv4 p
;
211 /* Type, flags, message. */
212 api
.type
= stream_getc (s
);
213 api
.flags
= stream_getc (s
);
214 api
.message
= stream_getc (s
);
217 memset (&p
, 0, sizeof (struct prefix_ipv4
));
219 p
.prefixlen
= stream_getc (s
);
220 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
222 /* Nexthop, ifindex, distance, metric. */
223 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
225 api
.nexthop_num
= stream_getc (s
);
226 nexthop
.s_addr
= stream_get_ipv4 (s
);
228 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
230 api
.ifindex_num
= stream_getc (s
);
231 ifindex
= stream_getl (s
);
233 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
234 api
.distance
= stream_getc (s
);
235 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
236 api
.metric
= stream_getl (s
);
240 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
241 bgp_redistribute_add ((struct prefix
*)&p
, &nexthop
, api
.metric
, api
.type
);
243 bgp_redistribute_delete ((struct prefix
*)&p
, api
.type
);
249 /* Zebra route add and delete treatment. */
251 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
254 struct zapi_ipv6 api
;
255 unsigned long ifindex
;
256 struct in6_addr nexthop
;
257 struct prefix_ipv6 p
;
261 memset (&nexthop
, 0, sizeof (struct in6_addr
));
263 /* Type, flags, message. */
264 api
.type
= stream_getc (s
);
265 api
.flags
= stream_getc (s
);
266 api
.message
= stream_getc (s
);
269 memset (&p
, 0, sizeof (struct prefix_ipv6
));
271 p
.prefixlen
= stream_getc (s
);
272 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
274 /* Nexthop, ifindex, distance, metric. */
275 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
277 api
.nexthop_num
= stream_getc (s
);
278 stream_get (&nexthop
, s
, 16);
280 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
282 api
.ifindex_num
= stream_getc (s
);
283 ifindex
= stream_getl (s
);
285 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
286 api
.distance
= stream_getc (s
);
289 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
290 api
.metric
= stream_getl (s
);
294 /* Simply ignore link-local address. */
295 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
298 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
299 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, api
.metric
, api
.type
);
301 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
305 #endif /* HAVE_IPV6 */
308 if_lookup_by_ipv4 (struct in_addr
*addr
)
310 struct listnode
*ifnode
;
311 struct listnode
*cnode
;
312 struct interface
*ifp
;
313 struct connected
*connected
;
314 struct prefix_ipv4 p
;
319 p
.prefixlen
= IPV4_MAX_BITLEN
;
321 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
323 ifp
= getdata (ifnode
);
325 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
327 connected
= getdata (cnode
);
328 cp
= connected
->address
;
330 if (cp
->family
== AF_INET
)
331 if (prefix_match (cp
, (struct prefix
*)&p
))
339 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
341 struct listnode
*ifnode
;
342 struct listnode
*cnode
;
343 struct interface
*ifp
;
344 struct connected
*connected
;
347 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
349 ifp
= getdata (ifnode
);
351 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
353 connected
= getdata (cnode
);
354 cp
= connected
->address
;
356 if (cp
->family
== AF_INET
)
357 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
366 if_lookup_by_ipv6 (struct in6_addr
*addr
)
368 struct listnode
*ifnode
;
369 struct listnode
*cnode
;
370 struct interface
*ifp
;
371 struct connected
*connected
;
372 struct prefix_ipv6 p
;
377 p
.prefixlen
= IPV6_MAX_BITLEN
;
379 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
381 ifp
= getdata (ifnode
);
383 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
385 connected
= getdata (cnode
);
386 cp
= connected
->address
;
388 if (cp
->family
== AF_INET6
)
389 if (prefix_match (cp
, (struct prefix
*)&p
))
397 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
399 struct listnode
*ifnode
;
400 struct listnode
*cnode
;
401 struct interface
*ifp
;
402 struct connected
*connected
;
405 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
407 ifp
= getdata (ifnode
);
409 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
411 connected
= getdata (cnode
);
412 cp
= connected
->address
;
414 if (cp
->family
== AF_INET6
)
415 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
423 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
425 struct listnode
*cnode
;
426 struct connected
*connected
;
429 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
431 connected
= getdata (cnode
);
432 cp
= connected
->address
;
434 if (cp
->family
== AF_INET6
)
435 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
437 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
445 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
447 struct listnode
*cnode
;
448 struct connected
*connected
;
451 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
453 connected
= getdata (cnode
);
454 cp
= connected
->address
;
456 if (cp
->family
== AF_INET6
)
457 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
459 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
465 #endif /* HAVE_IPV6 */
468 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
469 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
472 struct interface
*ifp
= NULL
;
474 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
481 if (local
->sa
.sa_family
== AF_INET
)
483 nexthop
->v4
= local
->sin
.sin_addr
;
484 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
487 if (local
->sa
.sa_family
== AF_INET6
)
489 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
492 ifp
= if_lookup_by_index (if_nametoindex (peer
->ifname
));
495 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
497 #endif /* HAVE_IPV6 */
504 /* IPv4 connection. */
505 if (local
->sa
.sa_family
== AF_INET
)
509 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
511 /* There is no global nexthop. */
513 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
515 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
516 #endif /* HAVE_IPV6 */
520 /* IPv6 connection. */
521 if (local
->sa
.sa_family
== AF_INET6
)
523 struct interface
*direct
= NULL
;
525 /* IPv4 nexthop. I don't care about it. */
526 if (peer
->local_id
.s_addr
)
527 nexthop
->v4
= peer
->local_id
;
530 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
532 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
535 /* If directory connected set link-local address. */
536 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
538 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
541 /* Link-local address. */
543 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
545 /* If there is no global address. Set link-local address as
546 global. I know this break RFC specification... */
548 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
551 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
556 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
557 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
558 peer
->shared_network
= 1;
560 peer
->shared_network
= 0;
562 /* KAME stack specific treatment. */
564 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
565 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
567 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
569 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
570 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
572 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
575 #endif /* HAVE_IPV6 */
581 bgp_ifindex_by_nexthop (struct in6_addr
*addr
)
583 struct listnode
*ifnode
;
584 struct listnode
*cnode
;
585 struct interface
*ifp
;
586 struct connected
*connected
;
587 struct prefix_ipv6 p
;
591 p
.prefixlen
= IPV6_MAX_BITLEN
;
593 for (ifnode
= listhead (iflist
); ifnode
; nextnode (ifnode
))
595 ifp
= getdata (ifnode
);
597 for (cnode
= listhead (ifp
->connected
); cnode
; nextnode (cnode
))
601 connected
= getdata (cnode
);
602 cp
= connected
->address
;
604 if (cp
->family
== AF_INET6
)
606 if (prefix_match (cp
, (struct prefix
*)&p
))
613 #endif /* HAVE_IPV6 */
616 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
)
622 if (zclient
->sock
< 0)
625 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
631 if (peer_sort (peer
) == BGP_PEER_IBGP
|| peer_sort (peer
) == BGP_PEER_CONFED
)
633 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
634 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
637 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
638 || CHECK_FLAG (peer
->flags
, PEER_FLAG_ENFORCE_MULTIHOP
))
639 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
641 if (p
->family
== AF_INET
)
643 struct zapi_ipv4 api
;
644 struct in_addr
*nexthop
;
647 nexthop
= &info
->attr
->nexthop
;
649 api
.type
= ZEBRA_ROUTE_BGP
;
651 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
653 api
.nexthop
= &nexthop
;
655 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
656 api
.metric
= info
->attr
->med
;
658 distance
= bgp_distance_apply (p
, info
, bgp
);
662 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
663 api
.distance
= distance
;
665 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
,
666 (struct prefix_ipv4
*) p
, &api
);
669 /* We have to think about a IPv6 link-local address curse. */
670 if (p
->family
== AF_INET6
)
672 unsigned int ifindex
;
673 struct in6_addr
*nexthop
;
674 struct zapi_ipv6 api
;
679 /* Only global address nexthop exists. */
680 if (info
->attr
->mp_nexthop_len
== 16)
681 nexthop
= &info
->attr
->mp_nexthop_global
;
683 /* If both global and link-local address present. */
684 if (info
->attr
->mp_nexthop_len
== 32)
686 /* Workaround for Cisco's nexthop bug. */
687 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->mp_nexthop_global
)
688 && peer
->su_remote
->sa
.sa_family
== AF_INET6
)
689 nexthop
= &peer
->su_remote
->sin6
.sin6_addr
;
691 nexthop
= &info
->attr
->mp_nexthop_local
;
693 if (info
->peer
->nexthop
.ifp
)
694 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
700 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
702 if (info
->peer
->ifname
)
703 ifindex
= if_nametoindex (info
->peer
->ifname
);
704 else if (info
->peer
->nexthop
.ifp
)
705 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
708 /* Make Zebra API structure. */
710 api
.type
= ZEBRA_ROUTE_BGP
;
712 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
714 api
.nexthop
= &nexthop
;
715 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
717 api
.ifindex
= &ifindex
;
718 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
719 api
.metric
= info
->attr
->med
;
721 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD
, zclient
,
722 (struct prefix_ipv6
*) p
, &api
);
724 #endif /* HAVE_IPV6 */
728 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
)
733 if (zclient
->sock
< 0)
736 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
742 if (peer_sort (peer
) == BGP_PEER_IBGP
)
744 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
745 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
748 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
749 || CHECK_FLAG (peer
->flags
, PEER_FLAG_ENFORCE_MULTIHOP
))
750 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
752 if (p
->family
== AF_INET
)
754 struct zapi_ipv4 api
;
755 struct in_addr
*nexthop
;
758 nexthop
= &info
->attr
->nexthop
;
760 api
.type
= ZEBRA_ROUTE_BGP
;
762 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
764 api
.nexthop
= &nexthop
;
766 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
767 api
.metric
= info
->attr
->med
;
769 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
770 (struct prefix_ipv4
*) p
, &api
);
773 /* We have to think about a IPv6 link-local address curse. */
774 if (p
->family
== AF_INET6
)
776 struct zapi_ipv6 api
;
777 unsigned int ifindex
;
778 struct in6_addr
*nexthop
;
783 /* Only global address nexthop exists. */
784 if (info
->attr
->mp_nexthop_len
== 16)
785 nexthop
= &info
->attr
->mp_nexthop_global
;
787 /* If both global and link-local address present. */
788 if (info
->attr
->mp_nexthop_len
== 32)
790 nexthop
= &info
->attr
->mp_nexthop_local
;
791 if (info
->peer
->nexthop
.ifp
)
792 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
798 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
799 if (info
->peer
->ifname
)
800 ifindex
= if_nametoindex (info
->peer
->ifname
);
803 api
.type
= ZEBRA_ROUTE_BGP
;
805 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
807 api
.nexthop
= &nexthop
;
808 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
810 api
.ifindex
= &ifindex
;
811 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
812 api
.metric
= info
->attr
->med
;
814 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
815 (struct prefix_ipv6
*) p
, &api
);
817 #endif /* HAVE_IPV6 */
820 /* Other routes redistribution into BGP. */
822 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
824 /* Set flag to BGP instance. */
825 bgp
->redist
[afi
][type
] = 1;
827 /* Return if already redistribute flag is set. */
828 if (zclient
->redist
[type
])
831 zclient
->redist
[type
] = 1;
833 /* Return if zebra connection is not established. */
834 if (zclient
->sock
< 0)
837 /* Send distribute add message to zebra. */
838 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
->sock
, type
);
843 /* Redistribute with route-map specification. */
845 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
848 if (bgp
->rmap
[afi
][type
].name
849 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
852 if (bgp
->rmap
[afi
][type
].name
)
853 free (bgp
->rmap
[afi
][type
].name
);
854 bgp
->rmap
[afi
][type
].name
= strdup (name
);
855 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
860 /* Redistribute with metric specification. */
862 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
865 if (bgp
->redist_metric_flag
[afi
][type
]
866 && bgp
->redist_metric
[afi
][type
] == metric
)
869 bgp
->redist_metric_flag
[afi
][type
] = 1;
870 bgp
->redist_metric
[afi
][type
] = metric
;
875 /* Unset redistribution. */
877 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
879 /* Unset flag from BGP instance. */
880 bgp
->redist
[afi
][type
] = 0;
882 /* Unset route-map. */
883 if (bgp
->rmap
[afi
][type
].name
)
884 free (bgp
->rmap
[afi
][type
].name
);
885 bgp
->rmap
[afi
][type
].name
= NULL
;
886 bgp
->rmap
[afi
][type
].map
= NULL
;
889 bgp
->redist_metric_flag
[afi
][type
] = 0;
890 bgp
->redist_metric
[afi
][type
] = 0;
892 /* Return if zebra connection is disabled. */
893 if (! zclient
->redist
[type
])
895 zclient
->redist
[type
] = 0;
897 if (bgp
->redist
[AFI_IP
][type
] == 0
898 && bgp
->redist
[AFI_IP6
][type
] == 0
899 && zclient
->sock
>= 0)
900 /* Send distribute delete message to zebra. */
901 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
->sock
, type
);
903 /* Withdraw redistributed routes from current BGP's routing table. */
904 bgp_redistribute_withdraw (bgp
, afi
, type
);
909 /* Unset redistribution route-map configuration. */
911 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
913 if (! bgp
->rmap
[afi
][type
].name
)
916 /* Unset route-map. */
917 free (bgp
->rmap
[afi
][type
].name
);
918 bgp
->rmap
[afi
][type
].name
= NULL
;
919 bgp
->rmap
[afi
][type
].map
= NULL
;
924 /* Unset redistribution metric configuration. */
926 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
928 if (! bgp
->redist_metric_flag
[afi
][type
])
932 bgp
->redist_metric_flag
[afi
][type
] = 0;
933 bgp
->redist_metric
[afi
][type
] = 0;
941 zclient_reset (zclient
);
945 bgp_zebra_init (int enable
)
947 /* Set default values. */
948 zclient
= zclient_new ();
949 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
950 zclient
->router_id_update
= bgp_router_id_update
;
951 zclient
->interface_add
= bgp_interface_add
;
952 zclient
->interface_delete
= bgp_interface_delete
;
953 zclient
->interface_address_add
= bgp_interface_address_add
;
954 zclient
->interface_address_delete
= bgp_interface_address_delete
;
955 zclient
->ipv4_route_add
= zebra_read_ipv4
;
956 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
957 zclient
->interface_up
= bgp_interface_up
;
958 zclient
->interface_down
= bgp_interface_down
;
960 zclient
->ipv6_route_add
= zebra_read_ipv6
;
961 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
962 #endif /* HAVE_IPV6 */
964 /* Interface related init. */