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"
41 #include "bgpd/bgp_nexthop.h"
43 /* All information about zebra. */
44 struct zclient
*zclient
= NULL
;
45 struct in_addr router_id_zebra
;
47 /* Growable buffer for nexthops sent to zebra */
48 struct stream
*bgp_nexthop_buf
= NULL
;
49 struct stream
*bgp_ifindices_buf
= NULL
;
51 /* These array buffers are used in making a copy of the attributes for
52 route-map apply. Arrays are being used here to minimize mallocs and
53 frees for the temporary copy of the attributes.
54 Given the zapi api expects the nexthop buffer to contain pointer to
55 pointers for nexthops, we couldnt have used a single nexthop variable
56 on the stack, hence we had two options:
57 1. maintain a linked-list and free it after zapi_*_route call
58 2. use an array to avoid number of mallocs.
59 Number of supported next-hops are finite, use of arrays should be ok. */
60 struct attr attr_cp
[BGP_MAXIMUM_MAXPATHS
];
61 struct attr_extra attr_extra_cp
[BGP_MAXIMUM_MAXPATHS
];
64 /* Once per address-family initialization of the attribute array */
65 #define BGP_INFO_ATTR_BUF_INIT()\
67 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
68 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
72 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
74 *info_dst = *info_src; \
75 assert(attr_index != BGP_MAXIMUM_MAXPATHS);\
76 attr_cp[attr_index].extra = &attr_extra_cp[attr_index]; \
77 bgp_attr_dup (&attr_cp[attr_index], info_src->attr); \
78 bgp_attr_deep_dup (&attr_cp[attr_index], info_src->attr); \
79 info_dst->attr = &attr_cp[attr_index]; \
83 #define BGP_INFO_ATTR_BUF_FREE(info) \
85 bgp_attr_deep_free(info->attr); \
88 /* Router-id update message from zebra. */
90 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
92 struct prefix router_id
;
93 struct listnode
*node
, *nnode
;
96 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
98 if (BGP_DEBUG(zebra
, ZEBRA
))
101 prefix2str(&router_id
, buf
, sizeof(buf
));
102 zlog_debug("Zebra rcvd: router id update %s", buf
);
105 router_id_zebra
= router_id
.u
.prefix4
;
107 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
109 if (!bgp
->router_id_static
.s_addr
)
110 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
116 /* Nexthop update message from zebra. */
118 bgp_read_nexthop_update (int command
, struct zclient
*zclient
,
121 bgp_parse_nexthop_update();
126 bgp_nbr_connected_add (struct nbr_connected
*ifc
)
128 struct listnode
*node
, *nnode
, *mnode
;
132 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
134 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
136 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
138 if (peer_active(peer
))
139 BGP_EVENT_ADD (peer
, BGP_Stop
);
140 BGP_EVENT_ADD (peer
, BGP_Start
);
147 bgp_nbr_connected_delete (struct nbr_connected
*ifc
)
149 struct listnode
*node
, *nnode
, *mnode
;
153 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
155 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
157 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
159 BGP_EVENT_ADD (peer
, BGP_Stop
);
165 /* Inteface addition message from zebra. */
167 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
169 struct interface
*ifp
;
171 ifp
= zebra_interface_add_read (zclient
->ibuf
);
173 if (BGP_DEBUG(zebra
, ZEBRA
) && ifp
)
174 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
180 bgp_interface_delete (int command
, struct zclient
*zclient
,
184 struct interface
*ifp
;
187 ifp
= zebra_interface_state_read (s
);
188 ifp
->ifindex
= IFINDEX_INTERNAL
;
190 if (BGP_DEBUG(zebra
, ZEBRA
))
191 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
197 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
200 struct interface
*ifp
;
202 struct nbr_connected
*nc
;
203 struct listnode
*node
, *nnode
;
206 ifp
= zebra_interface_state_read (s
);
211 if (BGP_DEBUG(zebra
, ZEBRA
))
212 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
214 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
215 bgp_connected_add (c
);
217 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
218 bgp_nbr_connected_add (nc
);
224 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
227 struct interface
*ifp
;
229 struct nbr_connected
*nc
;
230 struct listnode
*node
, *nnode
;
233 ifp
= zebra_interface_state_read (s
);
237 if (BGP_DEBUG(zebra
, ZEBRA
))
238 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
240 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
241 bgp_connected_delete (c
);
243 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
244 bgp_nbr_connected_delete (nc
);
246 /* Fast external-failover */
248 struct listnode
*mnode
;
252 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
254 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
257 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
259 if ((peer
->ttl
!= 1) && (peer
->gtsm_hops
!= 1))
262 if (ifp
== peer
->nexthop
.ifp
)
263 BGP_EVENT_ADD (peer
, BGP_Stop
);
272 bgp_interface_address_add (int command
, struct zclient
*zclient
,
275 struct connected
*ifc
;
277 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
282 if (BGP_DEBUG(zebra
, ZEBRA
))
285 prefix2str(ifc
->address
, buf
, sizeof(buf
));
286 zlog_debug("Zebra rcvd: interface %s address add %s",
287 ifc
->ifp
->name
, buf
);
290 if (if_is_operative (ifc
->ifp
))
291 bgp_connected_add (ifc
);
297 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
300 struct connected
*ifc
;
302 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
307 if (BGP_DEBUG(zebra
, ZEBRA
))
310 prefix2str(ifc
->address
, buf
, sizeof(buf
));
311 zlog_debug("Zebra rcvd: interface %s address delete %s",
312 ifc
->ifp
->name
, buf
);
315 if (if_is_operative (ifc
->ifp
))
316 bgp_connected_delete (ifc
);
318 connected_free (ifc
);
324 bgp_interface_nbr_address_add (int command
, struct zclient
*zclient
,
327 struct nbr_connected
*ifc
= NULL
;
329 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
334 if (BGP_DEBUG(zebra
, ZEBRA
))
337 prefix2str(ifc
->address
, buf
, sizeof(buf
));
338 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
339 ifc
->ifp
->name
, buf
);
342 if (if_is_operative (ifc
->ifp
))
343 bgp_nbr_connected_add (ifc
);
349 bgp_interface_nbr_address_delete (int command
, struct zclient
*zclient
,
352 struct nbr_connected
*ifc
= NULL
;
354 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
359 if (BGP_DEBUG(zebra
, ZEBRA
))
362 prefix2str(ifc
->address
, buf
, sizeof(buf
));
363 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
364 ifc
->ifp
->name
, buf
);
367 if (if_is_operative (ifc
->ifp
))
368 bgp_nbr_connected_delete (ifc
);
370 nbr_connected_free (ifc
);
375 /* Zebra route add and delete treatment. */
377 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
380 struct zapi_ipv4 api
;
381 struct in_addr nexthop
;
382 struct prefix_ipv4 p
;
387 /* Type, flags, message. */
388 api
.type
= stream_getc (s
);
389 api
.flags
= stream_getc (s
);
390 api
.message
= stream_getc (s
);
393 memset (&p
, 0, sizeof (struct prefix_ipv4
));
395 p
.prefixlen
= stream_getc (s
);
396 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
398 /* Nexthop, ifindex, distance, metric. */
399 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
401 api
.nexthop_num
= stream_getc (s
);
402 nexthop
.s_addr
= stream_get_ipv4 (s
);
404 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
406 api
.ifindex_num
= stream_getc (s
);
407 stream_getl (s
); /* ifindex, unused */
409 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
410 api
.distance
= stream_getc (s
);
411 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
412 api
.metric
= stream_getl (s
);
416 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
418 if (BGP_DEBUG(zebra
, ZEBRA
))
420 char buf
[2][INET_ADDRSTRLEN
];
421 zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
422 zebra_route_string(api
.type
),
423 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
425 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
428 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
,
429 api
.metric
, api
.type
);
433 if (BGP_DEBUG(zebra
, ZEBRA
))
435 char buf
[2][INET_ADDRSTRLEN
];
436 zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
437 "nexthop %s metric %u",
438 zebra_route_string(api
.type
),
439 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
441 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
444 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
);
451 /* Zebra route add and delete treatment. */
453 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
456 struct zapi_ipv6 api
;
457 struct in6_addr nexthop
;
458 struct prefix_ipv6 p
;
461 memset (&nexthop
, 0, sizeof (struct in6_addr
));
463 /* Type, flags, message. */
464 api
.type
= stream_getc (s
);
465 api
.flags
= stream_getc (s
);
466 api
.message
= stream_getc (s
);
469 memset (&p
, 0, sizeof (struct prefix_ipv6
));
471 p
.prefixlen
= stream_getc (s
);
472 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
474 /* Nexthop, ifindex, distance, metric. */
475 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
477 api
.nexthop_num
= stream_getc (s
);
478 stream_get (&nexthop
, s
, 16);
480 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
482 api
.ifindex_num
= stream_getc (s
);
483 stream_getl (s
); /* ifindex, unused */
485 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
486 api
.distance
= stream_getc (s
);
489 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
490 api
.metric
= stream_getl (s
);
494 /* Simply ignore link-local address. */
495 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
498 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
500 if (BGP_DEBUG(zebra
, ZEBRA
))
502 char buf
[2][INET6_ADDRSTRLEN
];
503 zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
504 zebra_route_string(api
.type
),
505 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
507 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
510 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
,
511 api
.metric
, api
.type
);
515 if (BGP_DEBUG(zebra
, ZEBRA
))
517 char buf
[2][INET6_ADDRSTRLEN
];
518 zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
519 "nexthop %s metric %u",
520 zebra_route_string(api
.type
),
521 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
523 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
526 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
);
531 #endif /* HAVE_IPV6 */
534 if_lookup_by_ipv4 (struct in_addr
*addr
)
536 struct listnode
*ifnode
;
537 struct listnode
*cnode
;
538 struct interface
*ifp
;
539 struct connected
*connected
;
540 struct prefix_ipv4 p
;
545 p
.prefixlen
= IPV4_MAX_BITLEN
;
547 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
549 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
551 cp
= connected
->address
;
553 if (cp
->family
== AF_INET
)
554 if (prefix_match (cp
, (struct prefix
*)&p
))
562 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
564 struct listnode
*ifnode
;
565 struct listnode
*cnode
;
566 struct interface
*ifp
;
567 struct connected
*connected
;
570 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
572 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
574 cp
= connected
->address
;
576 if (cp
->family
== AF_INET
)
577 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
586 if_lookup_by_ipv6 (struct in6_addr
*addr
)
588 struct listnode
*ifnode
;
589 struct listnode
*cnode
;
590 struct interface
*ifp
;
591 struct connected
*connected
;
592 struct prefix_ipv6 p
;
597 p
.prefixlen
= IPV6_MAX_BITLEN
;
599 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
601 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
603 cp
= connected
->address
;
605 if (cp
->family
== AF_INET6
)
606 if (prefix_match (cp
, (struct prefix
*)&p
))
614 if_lookup_by_ipv6_exact (struct in6_addr
*addr
)
616 struct listnode
*ifnode
;
617 struct listnode
*cnode
;
618 struct interface
*ifp
;
619 struct connected
*connected
;
622 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
624 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
626 cp
= connected
->address
;
628 if (cp
->family
== AF_INET6
)
629 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
637 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
639 struct listnode
*cnode
;
640 struct connected
*connected
;
643 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
645 cp
= connected
->address
;
647 if (cp
->family
== AF_INET6
)
648 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
650 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
658 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
660 struct listnode
*cnode
;
661 struct connected
*connected
;
664 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
666 cp
= connected
->address
;
668 if (cp
->family
== AF_INET6
)
669 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
671 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
677 #endif /* HAVE_IPV6 */
680 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
682 struct listnode
*cnode
;
683 struct connected
*connected
;
686 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
688 cp
= connected
->address
;
689 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
691 *addr
= cp
->u
.prefix4
;
699 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
700 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
703 struct interface
*ifp
= NULL
;
705 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
712 if (local
->sa
.sa_family
== AF_INET
)
714 nexthop
->v4
= local
->sin
.sin_addr
;
715 ifp
= if_lookup_by_ipv4 (&local
->sin
.sin_addr
);
718 if (local
->sa
.sa_family
== AF_INET6
)
720 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
722 if (peer
->conf_if
|| peer
->ifname
)
723 ifp
= if_lookup_by_index (if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
));
726 ifp
= if_lookup_by_ipv6 (&local
->sin6
.sin6_addr
);
728 #endif /* HAVE_IPV6 */
735 /* IPv4 connection. */
736 if (local
->sa
.sa_family
== AF_INET
)
740 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
742 /* There is no global nexthop. */
744 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
746 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
747 #endif /* HAVE_IPV6 */
751 /* IPv6 connection. */
752 if (local
->sa
.sa_family
== AF_INET6
)
754 struct interface
*direct
= NULL
;
757 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
758 if (!ret
&& peer
->local_id
.s_addr
)
759 nexthop
->v4
= peer
->local_id
;
762 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
764 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
767 /* If directory connected set link-local address. */
768 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
);
770 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
773 /* Link-local address. */
775 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
777 /* If there is no global address. Set link-local address as
778 global. I know this break RFC specification... */
780 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
783 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
788 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
789 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
))
790 peer
->shared_network
= 1;
792 peer
->shared_network
= 0;
794 /* KAME stack specific treatment. */
796 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
797 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
799 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
801 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
802 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
804 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
807 #endif /* HAVE_IPV6 */
811 static struct in6_addr
*
812 bgp_info_to_ipv6_nexthop (struct bgp_info
*info
)
814 struct in6_addr
*nexthop
= NULL
;
816 /* Only global address nexthop exists. */
817 if (info
->attr
->extra
->mp_nexthop_len
== 16)
818 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
820 /* If both global and link-local address present. */
821 if (info
->attr
->extra
->mp_nexthop_len
== 32)
823 /* Workaround for Cisco's nexthop bug. */
824 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->extra
->mp_nexthop_global
)
825 && info
->peer
->su_remote
->sa
.sa_family
== AF_INET6
)
826 nexthop
= &info
->peer
->su_remote
->sin6
.sin6_addr
;
828 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
835 bgp_table_map_apply (struct route_map
*map
, struct prefix
*p
,
836 struct bgp_info
*info
)
838 if (route_map_apply(map
, p
, RMAP_BGP
, info
) != RMAP_DENYMATCH
)
841 if (BGP_DEBUG(zebra
, ZEBRA
))
843 if (p
->family
== AF_INET
)
845 char buf
[2][INET_ADDRSTRLEN
];
846 zlog_debug("Zebra rmap deny: IPv4 route %s/%d nexthop %s",
847 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
849 inet_ntop(AF_INET
, &info
->attr
->nexthop
, buf
[1],
852 if (p
->family
== AF_INET6
)
854 char buf
[2][INET6_ADDRSTRLEN
];
855 zlog_debug("Zebra rmap deny: IPv6 route %s/%d nexthop %s",
856 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
858 inet_ntop(AF_INET6
, bgp_info_to_ipv6_nexthop(info
), buf
[1],
866 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
,
867 afi_t afi
, safi_t safi
)
872 struct bgp_info
*mpinfo
;
873 size_t oldsize
, newsize
;
874 u_int32_t nhcount
, metric
;
875 struct bgp_info local_info
;
876 struct bgp_info
*info_cp
= &local_info
;
878 if (zclient
->sock
< 0)
881 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
887 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
889 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
890 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
893 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
894 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
895 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
897 nhcount
= 1 + bgp_info_mpath_count (info
);
899 if (p
->family
== AF_INET
)
901 struct zapi_ipv4 api
;
902 struct in_addr
*nexthop
;
903 char buf
[2][INET_ADDRSTRLEN
];
904 int valid_nh_count
= 0;
906 /* resize nexthop buffer size if necessary */
907 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
908 (sizeof (struct in_addr
*) * nhcount
))
910 newsize
= (sizeof (struct in_addr
*) * nhcount
);
911 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
912 if (newsize
== oldsize
)
914 zlog_err ("can't resize nexthop buffer");
918 stream_reset (bgp_nexthop_buf
);
921 /* Metric is currently based on the best-path only. */
922 metric
= info
->attr
->med
;
924 if (bgp
->table_map
[afi
][safi
].name
)
926 BGP_INFO_ATTR_BUF_INIT();
928 /* Copy info and attributes, so the route-map apply doesn't modify the
930 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
931 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
933 metric
= info_cp
->attr
->med
;
934 nexthop
= &info_cp
->attr
->nexthop
;
936 BGP_INFO_ATTR_BUF_FREE(info_cp
);
940 nexthop
= &info
->attr
->nexthop
;
945 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
949 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
950 mpinfo
= bgp_info_mpath_next (mpinfo
))
954 if (bgp
->table_map
[afi
][safi
].name
)
956 /* Copy info and attributes, so the route-map apply doesn't modify the
958 BGP_INFO_ATTR_BUF_COPY(mpinfo
, info_cp
);
959 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
960 nexthop
= &info_cp
->attr
->nexthop
;
961 BGP_INFO_ATTR_BUF_FREE(info_cp
);
965 nexthop
= &mpinfo
->attr
->nexthop
;
971 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
976 api
.type
= ZEBRA_ROUTE_BGP
;
979 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
980 api
.nexthop_num
= valid_nh_count
;
981 api
.nexthop
= (struct in_addr
**)STREAM_DATA (bgp_nexthop_buf
);
983 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
986 distance
= bgp_distance_apply (p
, info
, bgp
);
990 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
991 api
.distance
= distance
;
994 if (BGP_DEBUG(zebra
, ZEBRA
))
997 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u"
998 " count %d", (valid_nh_count
? "add":"delete"),
999 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1000 p
->prefixlen
, api
.metric
, api
.nexthop_num
);
1001 for (i
= 0; i
< api
.nexthop_num
; i
++)
1002 zlog_debug(" IPv4 [nexthop %d] %s", i
+1,
1003 inet_ntop(AF_INET
, api
.nexthop
[i
], buf
[1], sizeof(buf
[1])));
1006 zapi_ipv4_route (valid_nh_count
? ZEBRA_IPV4_ROUTE_ADD
: ZEBRA_IPV4_ROUTE_DELETE
,
1007 zclient
, (struct prefix_ipv4
*) p
, &api
);
1011 /* We have to think about a IPv6 link-local address curse. */
1012 if (p
->family
== AF_INET6
)
1014 unsigned int ifindex
;
1015 struct in6_addr
*nexthop
;
1016 struct zapi_ipv6 api
;
1017 int valid_nh_count
= 0;
1018 char buf
[2][INET6_ADDRSTRLEN
];
1020 /* resize nexthop buffer size if necessary */
1021 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1022 (sizeof (struct in6_addr
*) * nhcount
))
1024 newsize
= (sizeof (struct in6_addr
*) * nhcount
);
1025 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1026 if (newsize
== oldsize
)
1028 zlog_err ("can't resize nexthop buffer");
1032 stream_reset (bgp_nexthop_buf
);
1034 /* resize ifindices buffer size if necessary */
1035 if ((oldsize
= stream_get_size (bgp_ifindices_buf
)) <
1036 (sizeof (unsigned int) * nhcount
))
1038 newsize
= (sizeof (unsigned int) * nhcount
);
1039 newsize
= stream_resize (bgp_ifindices_buf
, newsize
);
1040 if (newsize
== oldsize
)
1042 zlog_err ("can't resize nexthop buffer");
1046 stream_reset (bgp_ifindices_buf
);
1051 assert (info
->attr
->extra
);
1053 /* Metric is currently based on the best-path only. */
1054 metric
= info
->attr
->med
;
1056 if (bgp
->table_map
[afi
][safi
].name
)
1058 BGP_INFO_ATTR_BUF_INIT();
1060 /* Copy info and attributes, so the route-map apply doesn't modify the
1062 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1063 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1065 metric
= info_cp
->attr
->med
;
1066 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1068 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1072 nexthop
= bgp_info_to_ipv6_nexthop(info
);
1077 if (info
->attr
->extra
->mp_nexthop_len
== 32)
1078 if (info
->peer
->nexthop
.ifp
)
1079 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1082 if (info
->peer
->conf_if
|| info
->peer
->ifname
)
1083 ifindex
= if_nametoindex (info
->peer
->conf_if
? info
->peer
->conf_if
: info
->peer
->ifname
);
1084 else if (info
->peer
->nexthop
.ifp
)
1085 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1087 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1088 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1092 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1093 mpinfo
= bgp_info_mpath_next (mpinfo
))
1098 if (bgp
->table_map
[afi
][safi
].name
)
1100 /* Copy info and attributes, so the route-map apply doesn't modify the
1102 BGP_INFO_ATTR_BUF_COPY(mpinfo
, info_cp
);
1103 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1104 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1105 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1109 nexthop
= bgp_info_to_ipv6_nexthop(mpinfo
);
1112 if (nexthop
== NULL
)
1115 if (mpinfo
->attr
->extra
->mp_nexthop_len
== 32)
1116 if (mpinfo
->peer
->nexthop
.ifp
)
1117 ifindex
= mpinfo
->peer
->nexthop
.ifp
->ifindex
;
1120 if (mpinfo
->peer
->conf_if
|| mpinfo
->peer
->ifname
)
1121 ifindex
= if_nametoindex (mpinfo
->peer
->conf_if
? mpinfo
->peer
->conf_if
: mpinfo
->peer
->ifname
);
1122 else if (mpinfo
->peer
->nexthop
.ifp
)
1123 ifindex
= mpinfo
->peer
->nexthop
.ifp
->ifindex
;
1128 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1129 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1133 /* Make Zebra API structure. */
1135 api
.type
= ZEBRA_ROUTE_BGP
;
1138 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1139 api
.nexthop_num
= valid_nh_count
;
1140 api
.nexthop
= (struct in6_addr
**)STREAM_DATA (bgp_nexthop_buf
);
1141 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
1142 api
.ifindex_num
= valid_nh_count
;
1143 api
.ifindex
= (unsigned int *)STREAM_DATA (bgp_ifindices_buf
);
1144 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1145 api
.metric
= metric
;
1147 if (BGP_DEBUG(zebra
, ZEBRA
))
1150 zlog_debug("Zebra send: IPv6 route %s %s/%d metric %u",
1151 valid_nh_count
? "add" : "delete",
1152 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
1153 p
->prefixlen
, api
.metric
);
1154 for (i
= 0; i
< api
.nexthop_num
; i
++)
1155 zlog_debug(" IPv6 [nexthop %d] %s", i
+1,
1156 inet_ntop(AF_INET6
, api
.nexthop
[i
], buf
[1], sizeof(buf
[1])));
1159 zapi_ipv6_route (valid_nh_count
? ZEBRA_IPV6_ROUTE_ADD
: ZEBRA_IPV6_ROUTE_DELETE
,
1160 zclient
, (struct prefix_ipv6
*) p
, &api
);
1162 #endif /* HAVE_IPV6 */
1165 /* Announce all routes of a table to zebra */
1167 bgp_zebra_announce_table (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1169 struct bgp_node
*rn
;
1170 struct bgp_table
*table
;
1171 struct bgp_info
*ri
;
1173 table
= bgp
->rib
[afi
][safi
];
1175 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
1176 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1177 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
1178 && ri
->type
== ZEBRA_ROUTE_BGP
1179 && ri
->sub_type
== BGP_ROUTE_NORMAL
)
1180 bgp_zebra_announce (&rn
->p
, ri
, bgp
, afi
, safi
);
1184 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
1189 if (zclient
->sock
< 0)
1192 if (! zclient
->redist
[ZEBRA_ROUTE_BGP
])
1198 if (peer
->sort
== BGP_PEER_IBGP
)
1200 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1201 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
1204 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
1205 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
1206 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1208 if (p
->family
== AF_INET
)
1210 struct zapi_ipv4 api
;
1211 struct in_addr
*nexthop
;
1214 nexthop
= &info
->attr
->nexthop
;
1216 api
.type
= ZEBRA_ROUTE_BGP
;
1219 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1220 api
.nexthop_num
= 1;
1221 api
.nexthop
= &nexthop
;
1222 api
.ifindex_num
= 0;
1223 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1224 api
.metric
= info
->attr
->med
;
1226 if (BGP_DEBUG(zebra
, ZEBRA
))
1228 char buf
[2][INET_ADDRSTRLEN
];
1229 zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u",
1230 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1232 inet_ntop(AF_INET
, nexthop
, buf
[1], sizeof(buf
[1])),
1236 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
1237 (struct prefix_ipv4
*) p
, &api
);
1240 /* We have to think about a IPv6 link-local address curse. */
1241 if (p
->family
== AF_INET6
)
1243 struct zapi_ipv6 api
;
1244 unsigned int ifindex
;
1245 struct in6_addr
*nexthop
;
1247 assert (info
->attr
->extra
);
1252 /* Only global address nexthop exists. */
1253 if (info
->attr
->extra
->mp_nexthop_len
== 16)
1254 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
1256 /* If both global and link-local address present. */
1257 if (info
->attr
->extra
->mp_nexthop_len
== 32)
1259 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
1260 if (info
->peer
->nexthop
.ifp
)
1261 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1264 if (nexthop
== NULL
)
1267 if (IN6_IS_ADDR_LINKLOCAL (nexthop
) && ! ifindex
)
1268 if (info
->peer
->conf_if
|| info
->peer
->ifname
)
1269 ifindex
= if_nametoindex (info
->peer
->conf_if
? info
->peer
->conf_if
: info
->peer
->ifname
);
1272 api
.type
= ZEBRA_ROUTE_BGP
;
1275 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1276 api
.nexthop_num
= 1;
1277 api
.nexthop
= &nexthop
;
1278 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
1279 api
.ifindex_num
= 1;
1280 api
.ifindex
= &ifindex
;
1281 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1282 api
.metric
= info
->attr
->med
;
1284 if (BGP_DEBUG(zebra
, ZEBRA
))
1286 char buf
[2][INET6_ADDRSTRLEN
];
1287 zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u",
1288 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
1290 inet_ntop(AF_INET6
, nexthop
, buf
[1], sizeof(buf
[1])),
1294 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
1295 (struct prefix_ipv6
*) p
, &api
);
1297 #endif /* HAVE_IPV6 */
1300 /* Other routes redistribution into BGP. */
1302 bgp_redistribute_set (struct bgp
*bgp
, afi_t afi
, int type
)
1304 /* Set flag to BGP instance. */
1305 bgp
->redist
[afi
][type
] = 1;
1307 /* Return if already redistribute flag is set. */
1308 if (zclient
->redist
[type
])
1311 zclient
->redist
[type
] = 1;
1313 /* Return if zebra connection is not established. */
1314 if (zclient
->sock
< 0)
1317 if (BGP_DEBUG(zebra
, ZEBRA
))
1318 zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type
));
1320 /* Send distribute add message to zebra. */
1321 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, type
);
1326 /* Redistribute with route-map specification. */
1328 bgp_redistribute_rmap_set (struct bgp
*bgp
, afi_t afi
, int type
,
1331 if (bgp
->rmap
[afi
][type
].name
1332 && (strcmp (bgp
->rmap
[afi
][type
].name
, name
) == 0))
1335 if (bgp
->rmap
[afi
][type
].name
)
1336 free (bgp
->rmap
[afi
][type
].name
);
1337 bgp
->rmap
[afi
][type
].name
= strdup (name
);
1338 bgp
->rmap
[afi
][type
].map
= route_map_lookup_by_name (name
);
1343 /* Redistribute with metric specification. */
1345 bgp_redistribute_metric_set (struct bgp
*bgp
, afi_t afi
, int type
,
1348 if (bgp
->redist_metric_flag
[afi
][type
]
1349 && bgp
->redist_metric
[afi
][type
] == metric
)
1352 bgp
->redist_metric_flag
[afi
][type
] = 1;
1353 bgp
->redist_metric
[afi
][type
] = metric
;
1358 /* Unset redistribution. */
1360 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1362 /* Unset flag from BGP instance. */
1363 bgp
->redist
[afi
][type
] = 0;
1365 /* Unset route-map. */
1366 if (bgp
->rmap
[afi
][type
].name
)
1367 free (bgp
->rmap
[afi
][type
].name
);
1368 bgp
->rmap
[afi
][type
].name
= NULL
;
1369 bgp
->rmap
[afi
][type
].map
= NULL
;
1372 bgp
->redist_metric_flag
[afi
][type
] = 0;
1373 bgp
->redist_metric
[afi
][type
] = 0;
1375 /* Return if zebra connection is disabled. */
1376 if (! zclient
->redist
[type
])
1378 zclient
->redist
[type
] = 0;
1380 if (bgp
->redist
[AFI_IP
][type
] == 0
1381 && bgp
->redist
[AFI_IP6
][type
] == 0
1382 && zclient
->sock
>= 0)
1384 /* Send distribute delete message to zebra. */
1385 if (BGP_DEBUG(zebra
, ZEBRA
))
1386 zlog_debug("Zebra send: redistribute delete %s",
1387 zebra_route_string(type
));
1388 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, type
);
1391 /* Withdraw redistributed routes from current BGP's routing table. */
1392 bgp_redistribute_withdraw (bgp
, afi
, type
);
1397 /* Unset redistribution route-map configuration. */
1399 bgp_redistribute_routemap_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1401 if (! bgp
->rmap
[afi
][type
].name
)
1404 /* Unset route-map. */
1405 free (bgp
->rmap
[afi
][type
].name
);
1406 bgp
->rmap
[afi
][type
].name
= NULL
;
1407 bgp
->rmap
[afi
][type
].map
= NULL
;
1412 /* Unset redistribution metric configuration. */
1414 bgp_redistribute_metric_unset (struct bgp
*bgp
, afi_t afi
, int type
)
1416 if (! bgp
->redist_metric_flag
[afi
][type
])
1420 bgp
->redist_metric_flag
[afi
][type
] = 0;
1421 bgp
->redist_metric
[afi
][type
] = 0;
1427 bgp_zclient_reset (void)
1429 zclient_reset (zclient
);
1433 bgp_zebra_init (void)
1435 /* Set default values. */
1436 zclient
= zclient_new ();
1437 zclient_init (zclient
, ZEBRA_ROUTE_BGP
);
1438 zclient
->router_id_update
= bgp_router_id_update
;
1439 zclient
->interface_add
= bgp_interface_add
;
1440 zclient
->interface_delete
= bgp_interface_delete
;
1441 zclient
->interface_address_add
= bgp_interface_address_add
;
1442 zclient
->interface_address_delete
= bgp_interface_address_delete
;
1443 zclient
->interface_nbr_address_add
= bgp_interface_nbr_address_add
;
1444 zclient
->interface_nbr_address_delete
= bgp_interface_nbr_address_delete
;
1445 zclient
->ipv4_route_add
= zebra_read_ipv4
;
1446 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
1447 zclient
->interface_up
= bgp_interface_up
;
1448 zclient
->interface_down
= bgp_interface_down
;
1450 zclient
->ipv6_route_add
= zebra_read_ipv6
;
1451 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
1452 #endif /* HAVE_IPV6 */
1453 zclient
->nexthop_update
= bgp_read_nexthop_update
;
1455 /* Interface related init. */
1458 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);
1459 bgp_ifindices_buf
= stream_new(BGP_IFINDICES_BUF_SIZE
);