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"
40 #include "bgpd/bgp_mpath.h"
42 /* All information about zebra. */
43 struct zclient
*zclient
= NULL
;
44 struct in_addr router_id_zebra
;
46 /* Growable buffer for nexthops sent to zebra */
47 struct stream
*bgp_nexthop_buf
= NULL
;
49 /* Router-id update message from zebra. */
51 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
53 struct prefix router_id
;
54 struct listnode
*node
, *nnode
;
57 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
59 if (BGP_DEBUG(zebra
, ZEBRA
))
62 prefix2str(&router_id
, buf
, sizeof(buf
));
63 zlog_debug("Zebra rcvd: router id update %s", buf
);
66 router_id_zebra
= router_id
.u
.prefix4
;
68 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
70 if (!bgp
->router_id_static
.s_addr
)
71 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
77 /* Inteface addition message from zebra. */
79 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
81 struct interface
*ifp
;
83 ifp
= zebra_interface_add_read (zclient
->ibuf
);
85 if (BGP_DEBUG(zebra
, ZEBRA
) && ifp
)
86 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
92 bgp_interface_delete (int command
, struct zclient
*zclient
,
96 struct interface
*ifp
;
99 ifp
= zebra_interface_state_read (s
);
100 ifp
->ifindex
= IFINDEX_INTERNAL
;
102 if (BGP_DEBUG(zebra
, ZEBRA
))
103 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
109 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
112 struct interface
*ifp
;
114 struct listnode
*node
, *nnode
;
117 ifp
= zebra_interface_state_read (s
);
122 if (BGP_DEBUG(zebra
, ZEBRA
))
123 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
125 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
126 bgp_connected_add (c
);
132 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
135 struct interface
*ifp
;
137 struct listnode
*node
, *nnode
;
140 ifp
= zebra_interface_state_read (s
);
144 if (BGP_DEBUG(zebra
, ZEBRA
))
145 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
147 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
148 bgp_connected_delete (c
);
150 /* Fast external-failover (Currently IPv4 only) */
152 struct listnode
*mnode
;
155 struct interface
*peer_if
;
157 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
159 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
162 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
167 if (peer
->su
.sa
.sa_family
== AF_INET
)
168 peer_if
= if_lookup_by_ipv4 (&peer
->su
.sin
.sin_addr
);
173 BGP_EVENT_ADD (peer
, BGP_Stop
);
182 bgp_interface_address_add (int command
, struct zclient
*zclient
,
185 struct connected
*ifc
;
187 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
192 if (BGP_DEBUG(zebra
, ZEBRA
))
195 prefix2str(ifc
->address
, buf
, sizeof(buf
));
196 zlog_debug("Zebra rcvd: interface %s address add %s",
197 ifc
->ifp
->name
, buf
);
200 if (if_is_operative (ifc
->ifp
))
201 bgp_connected_add (ifc
);
207 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
210 struct connected
*ifc
;
212 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
217 if (BGP_DEBUG(zebra
, ZEBRA
))
220 prefix2str(ifc
->address
, buf
, sizeof(buf
));
221 zlog_debug("Zebra rcvd: interface %s address delete %s",
222 ifc
->ifp
->name
, buf
);
225 if (if_is_operative (ifc
->ifp
))
226 bgp_connected_delete (ifc
);
228 connected_free (ifc
);
233 /* Zebra route add and delete treatment. */
235 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
238 struct zapi_ipv4 api
;
239 struct in_addr nexthop
;
240 struct prefix_ipv4 p
;
245 /* Type, flags, message. */
246 api
.type
= stream_getc (s
);
247 api
.flags
= stream_getc (s
);
248 api
.message
= stream_getc (s
);
251 memset (&p
, 0, sizeof (struct prefix_ipv4
));
253 p
.prefixlen
= stream_getc (s
);
254 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
256 /* Nexthop, ifindex, distance, metric. */
257 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
259 api
.nexthop_num
= stream_getc (s
);
260 nexthop
.s_addr
= stream_get_ipv4 (s
);
262 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
264 api
.ifindex_num
= stream_getc (s
);
265 stream_getl (s
); /* ifindex, unused */
267 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
268 api
.distance
= stream_getc (s
);
269 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
270 api
.metric
= stream_getl (s
);
274 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
276 if (BGP_DEBUG(zebra
, ZEBRA
))
278 char buf
[2][INET_ADDRSTRLEN
];
279 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
280 zebra_route_string(api
.type
),
281 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
283 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
286 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
,
287 api
.metric
, api
.type
);
291 if (BGP_DEBUG(zebra
, ZEBRA
))
293 char buf
[2][INET_ADDRSTRLEN
];
294 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
295 "nexthop %s metric %u",
296 zebra_route_string(api
.type
),
297 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
299 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
302 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
);
309 /* Zebra route add and delete treatment. */
311 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
314 struct zapi_ipv6 api
;
315 struct in6_addr nexthop
;
316 struct prefix_ipv6 p
;
319 memset (&nexthop
, 0, sizeof (struct in6_addr
));
321 /* Type, flags, message. */
322 api
.type
= stream_getc (s
);
323 api
.flags
= stream_getc (s
);
324 api
.message
= stream_getc (s
);
327 memset (&p
, 0, sizeof (struct prefix_ipv6
));
329 p
.prefixlen
= stream_getc (s
);
330 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
332 /* Nexthop, ifindex, distance, metric. */
333 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
335 api
.nexthop_num
= stream_getc (s
);
336 stream_get (&nexthop
, s
, 16);
338 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
340 api
.ifindex_num
= stream_getc (s
);
341 stream_getl (s
); /* ifindex, unused */
343 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
344 api
.distance
= stream_getc (s
);
347 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
348 api
.metric
= stream_getl (s
);
352 /* Simply ignore link-local address. */
353 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
356 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
358 if (BGP_DEBUG(zebra
, ZEBRA
))
360 char buf
[2][INET6_ADDRSTRLEN
];
361 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
362 zebra_route_string(api
.type
),
363 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
365 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
368 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
,
369 api
.metric
, api
.type
);
373 if (BGP_DEBUG(zebra
, ZEBRA
))
375 char buf
[2][INET6_ADDRSTRLEN
];
376 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
377 "nexthop %s metric %u",
378 zebra_route_string(api
.type
),
379 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
381 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
384 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
389 #endif /* HAVE_IPV6 */
392 if_lookup_by_ipv4 (struct in_addr
*addr
)
394 struct listnode
*ifnode
;
395 struct listnode
*cnode
;
396 struct interface
*ifp
;
397 struct connected
*connected
;
398 struct prefix_ipv4 p
;
403 p
.prefixlen
= IPV4_MAX_BITLEN
;
405 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
407 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
409 cp
= connected
->address
;
411 if (cp
->family
== AF_INET
)
412 if (prefix_match (cp
, (struct prefix
*)&p
))
420 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
422 struct listnode
*ifnode
;
423 struct listnode
*cnode
;
424 struct interface
*ifp
;
425 struct connected
*connected
;
428 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
430 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
432 cp
= connected
->address
;
434 if (cp
->family
== AF_INET
)
435 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
444 if_lookup_by_ipv6 (struct in6_addr
*addr
)
446 struct listnode
*ifnode
;
447 struct listnode
*cnode
;
448 struct interface
*ifp
;
449 struct connected
*connected
;
450 struct prefix_ipv6 p
;
455 p
.prefixlen
= IPV6_MAX_BITLEN
;
457 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
459 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
461 cp
= connected
->address
;
463 if (cp
->family
== AF_INET6
)
464 if (prefix_match (cp
, (struct prefix
*)&p
))
472 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
474 struct listnode
*ifnode
;
475 struct listnode
*cnode
;
476 struct interface
*ifp
;
477 struct connected
*connected
;
480 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
482 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
484 cp
= connected
->address
;
486 if (cp
->family
== AF_INET6
)
487 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
495 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
497 struct listnode
*cnode
;
498 struct connected
*connected
;
501 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
503 cp
= connected
->address
;
505 if (cp
->family
== AF_INET6
)
506 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
508 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
516 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
518 struct listnode
*cnode
;
519 struct connected
*connected
;
522 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
524 cp
= connected
->address
;
526 if (cp
->family
== AF_INET6
)
527 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
529 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
535 #endif /* HAVE_IPV6 */
538 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
540 struct listnode
*cnode
;
541 struct connected
*connected
;
544 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
546 cp
= connected
->address
;
547 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
549 *addr
= cp
->u
.prefix4
;
557 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
558 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
561 struct interface
*ifp
= NULL
;
563 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
570 if (local
->sa
.sa_family
== AF_INET
)
572 nexthop
->v4
= local
->sin
.sin_addr
;
573 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
576 if (local
->sa
.sa_family
== AF_INET6
)
578 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
581 ifp
= if_lookup_by_index (if_nametoindex (peer
->ifname
));
584 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
586 #endif /* HAVE_IPV6 */
593 /* IPv4 connection. */
594 if (local
->sa
.sa_family
== AF_INET
)
598 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
600 /* There is no global nexthop. */
602 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
604 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
605 #endif /* HAVE_IPV6 */
609 /* IPv6 connection. */
610 if (local
->sa
.sa_family
== AF_INET6
)
612 struct interface
*direct
= NULL
;
615 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
616 if (!ret
&& peer
->local_id
.s_addr
)
617 nexthop
->v4
= peer
->local_id
;
620 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
622 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
625 /* If directory connected set link-local address. */
626 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
628 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
631 /* Link-local address. */
633 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
635 /* If there is no global address. Set link-local address as
636 global. I know this break RFC specification... */
638 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
641 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
646 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
647 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
648 peer
->shared_network
= 1;
650 peer
->shared_network
= 0;
652 /* KAME stack specific treatment. */
654 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
655 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
657 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
659 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
660 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
662 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
665 #endif /* HAVE_IPV6 */
670 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
, safi_t safi
)
675 struct bgp_info
*mpinfo
;
676 size_t oldsize
, newsize
;
678 if (zclient
->sock
< 0)
681 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
687 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
689 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
690 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
693 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
694 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
695 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
697 /* resize nexthop buffer size if necessary */
698 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
699 (sizeof (struct in_addr
*) * (bgp_info_mpath_count (info
) + 1)))
701 newsize
= (sizeof (struct in_addr
*) * (bgp_info_mpath_count (info
) + 1));
702 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
703 if (newsize
== oldsize
)
705 zlog_err ("can't resize nexthop buffer");
710 stream_reset (bgp_nexthop_buf
);
712 if (p
->family
== AF_INET
)
714 struct zapi_ipv4 api
;
715 struct in_addr
*nexthop
;
718 nexthop
= &info
->attr
->nexthop
;
719 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
720 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
721 mpinfo
= bgp_info_mpath_next (mpinfo
))
723 nexthop
= &mpinfo
->attr
->nexthop
;
724 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
727 api
.type
= ZEBRA_ROUTE_BGP
;
730 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
731 api
.nexthop_num
= 1 + bgp_info_mpath_count (info
);
732 api
.nexthop
= (struct in_addr
**)STREAM_DATA (bgp_nexthop_buf
);
734 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
735 api
.metric
= info
->attr
->med
;
737 distance
= bgp_distance_apply (p
, info
, bgp
);
741 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
742 api
.distance
= distance
;
745 if (BGP_DEBUG(zebra
, ZEBRA
))
748 char buf
[2][INET_ADDRSTRLEN
];
749 zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u"
751 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
753 inet_ntop(AF_INET
, api
.nexthop
[0], buf
[1], sizeof(buf
[1])),
754 api
.metric
, api
.nexthop_num
);
755 for (i
= 1; i
< api
.nexthop_num
; i
++)
756 zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s",
757 i
, inet_ntop(AF_INET
, api
.nexthop
[i
], buf
[1],
761 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
,
762 (struct prefix_ipv4
*) p
, &api
);
765 /* We have to think about a IPv6 link-local address curse. */
766 if (p
->family
== AF_INET6
)
768 unsigned int ifindex
;
769 struct in6_addr
*nexthop
;
770 struct zapi_ipv6 api
;
775 assert (info
->attr
->extra
);
777 /* Only global address nexthop exists. */
778 if (info
->attr
->extra
->mp_nexthop_len
== 16)
779 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
781 /* If both global and link-local address present. */
782 if (info
->attr
->extra
->mp_nexthop_len
== 32)
784 /* Workaround for Cisco's nexthop bug. */
785 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->extra
->mp_nexthop_global
)
786 && peer
->su_remote
->sa
.sa_family
== AF_INET6
)
787 nexthop
= &peer
->su_remote
->sin6
.sin6_addr
;
789 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
791 if (info
->peer
->nexthop
.ifp
)
792 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
798 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
800 if (info
->peer
->ifname
)
801 ifindex
= if_nametoindex (info
->peer
->ifname
);
802 else if (info
->peer
->nexthop
.ifp
)
803 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
806 /* Make Zebra API structure. */
808 api
.type
= ZEBRA_ROUTE_BGP
;
811 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
813 api
.nexthop
= &nexthop
;
814 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
816 api
.ifindex
= &ifindex
;
817 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
818 api
.metric
= info
->attr
->med
;
820 if (BGP_DEBUG(zebra
, ZEBRA
))
822 char buf
[2][INET6_ADDRSTRLEN
];
823 zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u",
824 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
826 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
830 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD
, zclient
,
831 (struct prefix_ipv6
*) p
, &api
);
833 #endif /* HAVE_IPV6 */
837 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
842 if (zclient
->sock
< 0)
845 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
851 if (peer
->sort
== BGP_PEER_IBGP
)
853 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
854 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
857 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
858 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
859 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
861 if (p
->family
== AF_INET
)
863 struct zapi_ipv4 api
;
864 struct in_addr
*nexthop
;
867 nexthop
= &info
->attr
->nexthop
;
869 api
.type
= ZEBRA_ROUTE_BGP
;
872 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
874 api
.nexthop
= &nexthop
;
876 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
877 api
.metric
= info
->attr
->med
;
879 if (BGP_DEBUG(zebra
, ZEBRA
))
881 char buf
[2][INET_ADDRSTRLEN
];
882 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
883 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
885 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
889 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
890 (struct prefix_ipv4
*) p
, &api
);
893 /* We have to think about a IPv6 link-local address curse. */
894 if (p
->family
== AF_INET6
)
896 struct zapi_ipv6 api
;
897 unsigned int ifindex
;
898 struct in6_addr
*nexthop
;
900 assert (info
->attr
->extra
);
905 /* Only global address nexthop exists. */
906 if (info
->attr
->extra
->mp_nexthop_len
== 16)
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
== 32)
912 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
913 if (info
->peer
->nexthop
.ifp
)
914 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
920 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
921 if (info
->peer
->ifname
)
922 ifindex
= if_nametoindex (info
->peer
->ifname
);
925 api
.type
= ZEBRA_ROUTE_BGP
;
928 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
930 api
.nexthop
= &nexthop
;
931 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
933 api
.ifindex
= &ifindex
;
934 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
935 api
.metric
= info
->attr
->med
;
937 if (BGP_DEBUG(zebra
, ZEBRA
))
939 char buf
[2][INET6_ADDRSTRLEN
];
940 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
941 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
943 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
947 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
948 (struct prefix_ipv6
*) p
, &api
);
950 #endif /* HAVE_IPV6 */
953 /* Other routes redistribution into BGP. */
955 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
957 /* Set flag to BGP instance. */
958 bgp
->redist
[afi
][type
] = 1;
960 /* Return if already redistribute flag is set. */
961 if (zclient
->redist
[type
])
964 zclient
->redist
[type
] = 1;
966 /* Return if zebra connection is not established. */
967 if (zclient
->sock
< 0)
970 if (BGP_DEBUG(zebra
, ZEBRA
))
971 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type
));
973 /* Send distribute add message to zebra. */
974 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
979 /* Redistribute with route-map specification. */
981 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
984 if (bgp
->rmap
[afi
][type
].name
985 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
988 if (bgp
->rmap
[afi
][type
].name
)
989 free (bgp
->rmap
[afi
][type
].name
);
990 bgp
->rmap
[afi
][type
].name
= strdup (name
);
991 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
996 /* Redistribute with metric specification. */
998 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
1001 if (bgp
->redist_metric_flag
[afi
][type
]
1002 && bgp
->redist_metric
[afi
][type
] == metric
)
1005 bgp
->redist_metric_flag
[afi
][type
] = 1;
1006 bgp
->redist_metric
[afi
][type
] = metric
;
1011 /* Unset redistribution. */
1013 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1015 /* Unset flag from BGP instance. */
1016 bgp
->redist
[afi
][type
] = 0;
1018 /* Unset route-map. */
1019 if (bgp
->rmap
[afi
][type
].name
)
1020 free (bgp
->rmap
[afi
][type
].name
);
1021 bgp
->rmap
[afi
][type
].name
= NULL
;
1022 bgp
->rmap
[afi
][type
].map
= NULL
;
1025 bgp
->redist_metric_flag
[afi
][type
] = 0;
1026 bgp
->redist_metric
[afi
][type
] = 0;
1028 /* Return if zebra connection is disabled. */
1029 if (! zclient
->redist
[type
])
1031 zclient
->redist
[type
] = 0;
1033 if (bgp
->redist
[AFI_IP
][type
] == 0
1034 && bgp
->redist
[AFI_IP6
][type
] == 0
1035 && zclient
->sock
>= 0)
1037 /* Send distribute delete message to zebra. */
1038 if (BGP_DEBUG(zebra
, ZEBRA
))
1039 zlog_debug("Zebra send: redistribute delete %s",
1040 zebra_route_string(type
));
1041 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
1044 /* Withdraw redistributed routes from current BGP's routing table. */
1045 bgp_redistribute_withdraw (bgp
, afi
, type
);
1050 /* Unset redistribution route-map configuration. */
1052 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1054 if (! bgp
->rmap
[afi
][type
].name
)
1057 /* Unset route-map. */
1058 free (bgp
->rmap
[afi
][type
].name
);
1059 bgp
->rmap
[afi
][type
].name
= NULL
;
1060 bgp
->rmap
[afi
][type
].map
= NULL
;
1065 /* Unset redistribution metric configuration. */
1067 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1069 if (! bgp
->redist_metric_flag
[afi
][type
])
1073 bgp
->redist_metric_flag
[afi
][type
] = 0;
1074 bgp
->redist_metric
[afi
][type
] = 0;
1080 bgp_zclient_reset (void)
1082 zclient_reset (zclient
);
1086 bgp_zebra_init (void)
1088 /* Set default values. */
1089 zclient
= zclient_new ();
1090 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
1091 zclient
->router_id_update
= bgp_router_id_update
;
1092 zclient
->interface_add
= bgp_interface_add
;
1093 zclient
->interface_delete
= bgp_interface_delete
;
1094 zclient
->interface_address_add
= bgp_interface_address_add
;
1095 zclient
->interface_address_delete
= bgp_interface_address_delete
;
1096 zclient
->ipv4_route_add
= zebra_read_ipv4
;
1097 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
1098 zclient
->interface_up
= bgp_interface_up
;
1099 zclient
->interface_down
= bgp_interface_down
;
1101 zclient
->ipv6_route_add
= zebra_read_ipv6
;
1102 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
1103 #endif /* HAVE_IPV6 */
1105 /* Interface related init. */
1108 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);