2 Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
28 #include "sockunion.h"
33 #include "bgpd/bgpd.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_nexthop.h"
37 #include "bgpd/bgp_zebra.h"
38 #include "bgpd/bgp_fsm.h"
39 #include "bgpd/bgp_debug.h"
41 /* All information about zebra. */
42 static struct zclient
*zclient
= NULL
;
43 struct in_addr router_id_zebra
;
45 /* Router-id update message from zebra. */
47 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
49 struct prefix router_id
;
50 struct listnode
*node
, *nnode
;
53 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
55 if (BGP_DEBUG(zebra
, ZEBRA
))
58 prefix2str(&router_id
, buf
, sizeof(buf
));
59 zlog_debug("Zebra rcvd: router id update %s", buf
);
62 router_id_zebra
= router_id
.u
.prefix4
;
64 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
66 if (!bgp
->router_id_static
.s_addr
)
67 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
73 /* Inteface addition message from zebra. */
75 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
77 struct interface
*ifp
;
79 ifp
= zebra_interface_add_read (zclient
->ibuf
);
81 if (BGP_DEBUG(zebra
, ZEBRA
) && ifp
)
82 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
88 bgp_interface_delete (int command
, struct zclient
*zclient
,
92 struct interface
*ifp
;
95 ifp
= zebra_interface_state_read (s
);
96 ifp
->ifindex
= IFINDEX_INTERNAL
;
98 if (BGP_DEBUG(zebra
, ZEBRA
))
99 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
105 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
108 struct interface
*ifp
;
110 struct listnode
*node
, *nnode
;
113 ifp
= zebra_interface_state_read (s
);
118 if (BGP_DEBUG(zebra
, ZEBRA
))
119 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
121 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
122 bgp_connected_add (c
);
128 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
131 struct interface
*ifp
;
133 struct listnode
*node
, *nnode
;
136 ifp
= zebra_interface_state_read (s
);
140 if (BGP_DEBUG(zebra
, ZEBRA
))
141 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
143 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
144 bgp_connected_delete (c
);
146 /* Fast external-failover (Currently IPv4 only) */
148 struct listnode
*mnode
;
151 struct interface
*peer_if
;
153 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
155 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
158 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
163 if (peer
->su
.sa
.sa_family
== AF_INET
)
164 peer_if
= if_lookup_by_ipv4 (&peer
->su
.sin
.sin_addr
);
169 BGP_EVENT_ADD (peer
, BGP_Stop
);
178 bgp_interface_address_add (int command
, struct zclient
*zclient
,
181 struct connected
*ifc
;
183 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
188 if (BGP_DEBUG(zebra
, ZEBRA
))
191 prefix2str(ifc
->address
, buf
, sizeof(buf
));
192 zlog_debug("Zebra rcvd: interface %s address add %s",
193 ifc
->ifp
->name
, buf
);
196 if (if_is_operative (ifc
->ifp
))
197 bgp_connected_add (ifc
);
203 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
206 struct connected
*ifc
;
208 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
213 if (BGP_DEBUG(zebra
, ZEBRA
))
216 prefix2str(ifc
->address
, buf
, sizeof(buf
));
217 zlog_debug("Zebra rcvd: interface %s address delete %s",
218 ifc
->ifp
->name
, buf
);
221 if (if_is_operative (ifc
->ifp
))
222 bgp_connected_delete (ifc
);
224 connected_free (ifc
);
229 /* Zebra route add and delete treatment. */
231 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
234 struct zapi_ipv4 api
;
235 unsigned long ifindex
;
236 struct in_addr nexthop
;
237 struct prefix_ipv4 p
;
243 /* Type, flags, message. */
244 api
.type
= stream_getc (s
);
245 api
.flags
= stream_getc (s
);
246 api
.message
= stream_getc (s
);
249 memset (&p
, 0, sizeof (struct prefix_ipv4
));
251 p
.prefixlen
= stream_getc (s
);
252 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
254 /* Nexthop, ifindex, distance, metric. */
255 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
257 api
.nexthop_num
= stream_getc (s
);
258 nexthop
.s_addr
= stream_get_ipv4 (s
);
260 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
262 api
.ifindex_num
= stream_getc (s
);
263 ifindex
= stream_getl (s
);
265 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
266 api
.distance
= stream_getc (s
);
267 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
268 api
.metric
= stream_getl (s
);
272 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
274 if (BGP_DEBUG(zebra
, ZEBRA
))
276 char buf
[2][INET_ADDRSTRLEN
];
277 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
278 zebra_route_string(api
.type
),
279 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
281 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
284 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, api
.metric
, api
.type
);
288 if (BGP_DEBUG(zebra
, ZEBRA
))
290 char buf
[2][INET_ADDRSTRLEN
];
291 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
292 "nexthop %s metric %u",
293 zebra_route_string(api
.type
),
294 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
296 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
299 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
);
306 /* Zebra route add and delete treatment. */
308 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
311 struct zapi_ipv6 api
;
312 unsigned long ifindex
;
313 struct in6_addr nexthop
;
314 struct prefix_ipv6 p
;
318 memset (&nexthop
, 0, sizeof (struct in6_addr
));
320 /* Type, flags, message. */
321 api
.type
= stream_getc (s
);
322 api
.flags
= stream_getc (s
);
323 api
.message
= stream_getc (s
);
326 memset (&p
, 0, sizeof (struct prefix_ipv6
));
328 p
.prefixlen
= stream_getc (s
);
329 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
331 /* Nexthop, ifindex, distance, metric. */
332 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
334 api
.nexthop_num
= stream_getc (s
);
335 stream_get (&nexthop
, s
, 16);
337 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
339 api
.ifindex_num
= stream_getc (s
);
340 ifindex
= stream_getl (s
);
342 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
343 api
.distance
= stream_getc (s
);
346 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
347 api
.metric
= stream_getl (s
);
351 /* Simply ignore link-local address. */
352 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
355 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
357 if (BGP_DEBUG(zebra
, ZEBRA
))
359 char buf
[INET6_ADDRSTRLEN
];
360 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
361 zebra_route_string(api
.type
),
362 inet_ntop(AF_INET6
, &p
.prefix
, buf
, sizeof(buf
)),
363 p
.prefixlen
, api
.metric
);
365 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, api
.metric
, api
.type
);
369 if (BGP_DEBUG(zebra
, ZEBRA
))
371 char buf
[INET6_ADDRSTRLEN
];
372 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
373 zebra_route_string(api
.type
),
374 inet_ntop(AF_INET6
, &p
.prefix
, buf
, sizeof(buf
)),
375 p
.prefixlen
, api
.metric
);
377 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
382 #endif /* HAVE_IPV6 */
385 if_lookup_by_ipv4 (struct in_addr
*addr
)
387 struct listnode
*ifnode
;
388 struct listnode
*cnode
;
389 struct interface
*ifp
;
390 struct connected
*connected
;
391 struct prefix_ipv4 p
;
396 p
.prefixlen
= IPV4_MAX_BITLEN
;
398 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
400 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
402 cp
= connected
->address
;
404 if (cp
->family
== AF_INET
)
405 if (prefix_match (cp
, (struct prefix
*)&p
))
413 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
415 struct listnode
*ifnode
;
416 struct listnode
*cnode
;
417 struct interface
*ifp
;
418 struct connected
*connected
;
421 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
423 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
425 cp
= connected
->address
;
427 if (cp
->family
== AF_INET
)
428 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
437 if_lookup_by_ipv6 (struct in6_addr
*addr
)
439 struct listnode
*ifnode
;
440 struct listnode
*cnode
;
441 struct interface
*ifp
;
442 struct connected
*connected
;
443 struct prefix_ipv6 p
;
448 p
.prefixlen
= IPV6_MAX_BITLEN
;
450 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
452 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
454 cp
= connected
->address
;
456 if (cp
->family
== AF_INET6
)
457 if (prefix_match (cp
, (struct prefix
*)&p
))
465 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
467 struct listnode
*ifnode
;
468 struct listnode
*cnode
;
469 struct interface
*ifp
;
470 struct connected
*connected
;
473 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
475 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
477 cp
= connected
->address
;
479 if (cp
->family
== AF_INET6
)
480 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
488 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
490 struct listnode
*cnode
;
491 struct connected
*connected
;
494 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
496 cp
= connected
->address
;
498 if (cp
->family
== AF_INET6
)
499 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
501 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
509 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
511 struct listnode
*cnode
;
512 struct connected
*connected
;
515 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
517 cp
= connected
->address
;
519 if (cp
->family
== AF_INET6
)
520 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
522 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
528 #endif /* HAVE_IPV6 */
531 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
532 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
535 struct interface
*ifp
= NULL
;
537 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
544 if (local
->sa
.sa_family
== AF_INET
)
546 nexthop
->v4
= local
->sin
.sin_addr
;
547 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
550 if (local
->sa
.sa_family
== AF_INET6
)
552 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
555 ifp
= if_lookup_by_index (if_nametoindex (peer
->ifname
));
558 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
560 #endif /* HAVE_IPV6 */
567 /* IPv4 connection. */
568 if (local
->sa
.sa_family
== AF_INET
)
572 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
574 /* There is no global nexthop. */
576 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
578 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
579 #endif /* HAVE_IPV6 */
583 /* IPv6 connection. */
584 if (local
->sa
.sa_family
== AF_INET6
)
586 struct interface
*direct
= NULL
;
588 /* IPv4 nexthop. I don't care about it. */
589 if (peer
->local_id
.s_addr
)
590 nexthop
->v4
= peer
->local_id
;
593 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
595 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
598 /* If directory connected set link-local address. */
599 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
601 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
604 /* Link-local address. */
606 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
608 /* If there is no global address. Set link-local address as
609 global. I know this break RFC specification... */
611 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
614 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
619 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
620 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
621 peer
->shared_network
= 1;
623 peer
->shared_network
= 0;
625 /* KAME stack specific treatment. */
627 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
628 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
630 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
632 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
633 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
635 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
638 #endif /* HAVE_IPV6 */
644 bgp_ifindex_by_nexthop (struct in6_addr
*addr
)
646 struct listnode
*ifnode
;
647 struct listnode
*cnode
;
648 struct interface
*ifp
;
649 struct connected
*connected
;
650 struct prefix_ipv6 p
;
654 p
.prefixlen
= IPV6_MAX_BITLEN
;
656 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
658 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
662 cp
= connected
->address
;
664 if (cp
->family
== AF_INET6
)
666 if (prefix_match (cp
, (struct prefix
*)&p
))
673 #endif /* HAVE_IPV6 */
676 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
)
682 if (zclient
->sock
< 0)
685 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
691 if (peer_sort (peer
) == BGP_PEER_IBGP
|| peer_sort (peer
) == BGP_PEER_CONFED
)
693 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
694 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
697 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
698 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
699 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
701 if (p
->family
== AF_INET
)
703 struct zapi_ipv4 api
;
704 struct in_addr
*nexthop
;
707 nexthop
= &info
->attr
->nexthop
;
709 api
.type
= ZEBRA_ROUTE_BGP
;
711 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
713 api
.nexthop
= &nexthop
;
715 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
716 api
.metric
= info
->attr
->med
;
718 distance
= bgp_distance_apply (p
, info
, bgp
);
722 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
723 api
.distance
= distance
;
726 if (BGP_DEBUG(zebra
, ZEBRA
))
728 char buf
[2][INET_ADDRSTRLEN
];
729 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u",
730 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
732 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
736 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
,
737 (struct prefix_ipv4
*) p
, &api
);
740 /* We have to think about a IPv6 link-local address curse. */
741 if (p
->family
== AF_INET6
)
743 unsigned int ifindex
;
744 struct in6_addr
*nexthop
;
745 struct zapi_ipv6 api
;
750 assert (info
->attr
->extra
);
752 /* Only global address nexthop exists. */
753 if (info
->attr
->extra
->mp_nexthop_len
== 16)
754 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
756 /* If both global and link-local address present. */
757 if (info
->attr
->extra
->mp_nexthop_len
== 32)
759 /* Workaround for Cisco's nexthop bug. */
760 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->extra
->mp_nexthop_global
)
761 && peer
->su_remote
->sa
.sa_family
== AF_INET6
)
762 nexthop
= &peer
->su_remote
->sin6
.sin6_addr
;
764 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
766 if (info
->peer
->nexthop
.ifp
)
767 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
773 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
775 if (info
->peer
->ifname
)
776 ifindex
= if_nametoindex (info
->peer
->ifname
);
777 else if (info
->peer
->nexthop
.ifp
)
778 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
781 /* Make Zebra API structure. */
783 api
.type
= ZEBRA_ROUTE_BGP
;
785 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
787 api
.nexthop
= &nexthop
;
788 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
790 api
.ifindex
= &ifindex
;
791 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
792 api
.metric
= info
->attr
->med
;
794 if (BGP_DEBUG(zebra
, ZEBRA
))
796 char buf
[2][INET6_ADDRSTRLEN
];
797 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
798 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
800 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
804 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD
, zclient
,
805 (struct prefix_ipv6
*) p
, &api
);
807 #endif /* HAVE_IPV6 */
811 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
)
816 if (zclient
->sock
< 0)
819 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
825 if (peer_sort (peer
) == BGP_PEER_IBGP
)
827 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
828 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
831 if ((peer_sort (peer
) == BGP_PEER_EBGP
&& peer
->ttl
!= 1)
832 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
833 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
835 if (p
->family
== AF_INET
)
837 struct zapi_ipv4 api
;
838 struct in_addr
*nexthop
;
841 nexthop
= &info
->attr
->nexthop
;
843 api
.type
= ZEBRA_ROUTE_BGP
;
845 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
847 api
.nexthop
= &nexthop
;
849 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
850 api
.metric
= info
->attr
->med
;
852 if (BGP_DEBUG(zebra
, ZEBRA
))
854 char buf
[2][INET_ADDRSTRLEN
];
855 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
856 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
858 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
862 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
863 (struct prefix_ipv4
*) p
, &api
);
866 /* We have to think about a IPv6 link-local address curse. */
867 if (p
->family
== AF_INET6
)
869 struct zapi_ipv6 api
;
870 unsigned int ifindex
;
871 struct in6_addr
*nexthop
;
873 assert (info
->attr
->extra
);
878 /* Only global address nexthop exists. */
879 if (info
->attr
->extra
->mp_nexthop_len
== 16)
880 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
882 /* If both global and link-local address present. */
883 if (info
->attr
->extra
->mp_nexthop_len
== 32)
885 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
886 if (info
->peer
->nexthop
.ifp
)
887 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
893 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
894 if (info
->peer
->ifname
)
895 ifindex
= if_nametoindex (info
->peer
->ifname
);
898 api
.type
= ZEBRA_ROUTE_BGP
;
900 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
902 api
.nexthop
= &nexthop
;
903 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
905 api
.ifindex
= &ifindex
;
906 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
907 api
.metric
= info
->attr
->med
;
909 if (BGP_DEBUG(zebra
, ZEBRA
))
911 char buf
[2][INET6_ADDRSTRLEN
];
912 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
913 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
915 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
919 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
920 (struct prefix_ipv6
*) p
, &api
);
922 #endif /* HAVE_IPV6 */
925 /* Other routes redistribution into BGP. */
927 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
929 /* Set flag to BGP instance. */
930 bgp
->redist
[afi
][type
] = 1;
932 /* Return if already redistribute flag is set. */
933 if (zclient
->redist
[type
])
936 zclient
->redist
[type
] = 1;
938 /* Return if zebra connection is not established. */
939 if (zclient
->sock
< 0)
942 if (BGP_DEBUG(zebra
, ZEBRA
))
943 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type
));
945 /* Send distribute add message to zebra. */
946 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
951 /* Redistribute with route-map specification. */
953 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
956 if (bgp
->rmap
[afi
][type
].name
957 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
960 if (bgp
->rmap
[afi
][type
].name
)
961 free (bgp
->rmap
[afi
][type
].name
);
962 bgp
->rmap
[afi
][type
].name
= strdup (name
);
963 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
968 /* Redistribute with metric specification. */
970 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
973 if (bgp
->redist_metric_flag
[afi
][type
]
974 && bgp
->redist_metric
[afi
][type
] == metric
)
977 bgp
->redist_metric_flag
[afi
][type
] = 1;
978 bgp
->redist_metric
[afi
][type
] = metric
;
983 /* Unset redistribution. */
985 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
987 /* Unset flag from BGP instance. */
988 bgp
->redist
[afi
][type
] = 0;
990 /* Unset route-map. */
991 if (bgp
->rmap
[afi
][type
].name
)
992 free (bgp
->rmap
[afi
][type
].name
);
993 bgp
->rmap
[afi
][type
].name
= NULL
;
994 bgp
->rmap
[afi
][type
].map
= NULL
;
997 bgp
->redist_metric_flag
[afi
][type
] = 0;
998 bgp
->redist_metric
[afi
][type
] = 0;
1000 /* Return if zebra connection is disabled. */
1001 if (! zclient
->redist
[type
])
1003 zclient
->redist
[type
] = 0;
1005 if (bgp
->redist
[AFI_IP
][type
] == 0
1006 && bgp
->redist
[AFI_IP6
][type
] == 0
1007 && zclient
->sock
>= 0)
1009 /* Send distribute delete message to zebra. */
1010 if (BGP_DEBUG(zebra
, ZEBRA
))
1011 zlog_debug("Zebra send: redistribute delete %s",
1012 zebra_route_string(type
));
1013 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
1016 /* Withdraw redistributed routes from current BGP's routing table. */
1017 bgp_redistribute_withdraw (bgp
, afi
, type
);
1022 /* Unset redistribution route-map configuration. */
1024 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1026 if (! bgp
->rmap
[afi
][type
].name
)
1029 /* Unset route-map. */
1030 free (bgp
->rmap
[afi
][type
].name
);
1031 bgp
->rmap
[afi
][type
].name
= NULL
;
1032 bgp
->rmap
[afi
][type
].map
= NULL
;
1037 /* Unset redistribution metric configuration. */
1039 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1041 if (! bgp
->redist_metric_flag
[afi
][type
])
1045 bgp
->redist_metric_flag
[afi
][type
] = 0;
1046 bgp
->redist_metric
[afi
][type
] = 0;
1052 bgp_zclient_reset (void)
1054 zclient_reset (zclient
);
1058 bgp_zebra_init (void)
1060 /* Set default values. */
1061 zclient
= zclient_new ();
1062 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
1063 zclient
->router_id_update
= bgp_router_id_update
;
1064 zclient
->interface_add
= bgp_interface_add
;
1065 zclient
->interface_delete
= bgp_interface_delete
;
1066 zclient
->interface_address_add
= bgp_interface_address_add
;
1067 zclient
->interface_address_delete
= bgp_interface_address_delete
;
1068 zclient
->ipv4_route_add
= zebra_read_ipv4
;
1069 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
1070 zclient
->interface_up
= bgp_interface_up
;
1071 zclient
->interface_down
= bgp_interface_down
;
1073 zclient
->ipv6_route_add
= zebra_read_ipv6
;
1074 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
1075 #endif /* HAVE_IPV6 */
1077 /* Interface related init. */