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"
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_route.h"
38 #include "bgpd/bgp_attr.h"
39 #include "bgpd/bgp_nexthop.h"
40 #include "bgpd/bgp_zebra.h"
41 #include "bgpd/bgp_fsm.h"
42 #include "bgpd/bgp_debug.h"
43 #include "bgpd/bgp_mpath.h"
44 #include "bgpd/bgp_nexthop.h"
45 #include "bgpd/bgp_nht.h"
46 #include "bgpd/bgp_bfd.h"
48 /* All information about zebra. */
49 struct zclient
*zclient
= NULL
;
50 struct in_addr router_id_zebra
;
52 /* Growable buffer for nexthops sent to zebra */
53 struct stream
*bgp_nexthop_buf
= NULL
;
54 struct stream
*bgp_ifindices_buf
= NULL
;
56 /* These array buffers are used in making a copy of the attributes for
57 route-map apply. Arrays are being used here to minimize mallocs and
58 frees for the temporary copy of the attributes.
59 Given the zapi api expects the nexthop buffer to contain pointer to
60 pointers for nexthops, we couldnt have used a single nexthop variable
61 on the stack, hence we had two options:
62 1. maintain a linked-list and free it after zapi_*_route call
63 2. use an array to avoid number of mallocs.
64 Number of supported next-hops are finite, use of arrays should be ok. */
65 struct attr attr_cp
[BGP_MAXIMUM_MAXPATHS
];
66 struct attr_extra attr_extra_cp
[BGP_MAXIMUM_MAXPATHS
];
69 /* Once per address-family initialization of the attribute array */
70 #define BGP_INFO_ATTR_BUF_INIT()\
72 memset(attr_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr));\
73 memset(attr_extra_cp, 0, BGP_MAXIMUM_MAXPATHS * sizeof(struct attr_extra));\
77 #define BGP_INFO_ATTR_BUF_COPY(info_src, info_dst)\
79 *info_dst = *info_src; \
80 assert(attr_index != BGP_MAXIMUM_MAXPATHS);\
81 attr_cp[attr_index].extra = &attr_extra_cp[attr_index]; \
82 bgp_attr_dup (&attr_cp[attr_index], info_src->attr); \
83 bgp_attr_deep_dup (&attr_cp[attr_index], info_src->attr); \
84 info_dst->attr = &attr_cp[attr_index]; \
88 #define BGP_INFO_ATTR_BUF_FREE(info) \
90 bgp_attr_deep_free(info->attr); \
93 /* Router-id update message from zebra. */
95 bgp_router_id_update (int command
, struct zclient
*zclient
, zebra_size_t length
)
97 struct prefix router_id
;
98 struct listnode
*node
, *nnode
;
101 zebra_router_id_update_read(zclient
->ibuf
,&router_id
);
103 if (BGP_DEBUG (zebra
, ZEBRA
))
106 prefix2str(&router_id
, buf
, sizeof(buf
));
107 zlog_debug("Zebra rcvd: router id update %s", buf
);
110 router_id_zebra
= router_id
.u
.prefix4
;
112 for (ALL_LIST_ELEMENTS (bm
->bgp
, node
, nnode
, bgp
))
114 if (!bgp
->router_id_static
.s_addr
)
115 bgp_router_id_set (bgp
, &router_id
.u
.prefix4
);
121 /* Nexthop update message from zebra. */
123 bgp_read_nexthop_update (int command
, struct zclient
*zclient
,
126 bgp_parse_nexthop_update(command
);
131 bgp_read_import_check_update(int command
, struct zclient
*zclient
,
134 bgp_parse_nexthop_update(command
);
139 bgp_start_interface_nbrs (struct interface
*ifp
)
141 struct listnode
*node
, *nnode
, *mnode
;
145 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
147 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
150 (strcmp (peer
->conf_if
, ifp
->name
) == 0) &&
151 peer
->status
!= Established
)
153 if (peer_active(peer
))
154 BGP_EVENT_ADD (peer
, BGP_Stop
);
155 BGP_EVENT_ADD (peer
, BGP_Start
);
162 bgp_nbr_connected_add (struct nbr_connected
*ifc
)
164 struct listnode
*node
;
165 struct connected
*connected
;
166 struct interface
*ifp
;
169 /* Kick-off the FSM for any relevant peers only if there is a
170 * valid local address on the interface.
173 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, node
, connected
))
175 p
= connected
->address
;
176 if (p
->family
== AF_INET6
&&
177 IN6_IS_ADDR_LINKLOCAL (&p
->u
.prefix6
))
183 bgp_start_interface_nbrs (ifp
);
187 bgp_nbr_connected_delete (struct nbr_connected
*ifc
, int del
)
189 struct listnode
*node
, *nnode
, *mnode
;
192 struct interface
*ifp
;
194 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
196 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
198 if (peer
->conf_if
&& (strcmp (peer
->conf_if
, ifc
->ifp
->name
) == 0))
200 BGP_EVENT_ADD (peer
, BGP_Stop
);
204 /* Free neighbor also, if we're asked to. */
208 listnode_delete (ifp
->nbr_connected
, ifc
);
209 nbr_connected_free (ifc
);
213 /* Inteface addition message from zebra. */
215 bgp_interface_add (int command
, struct zclient
*zclient
, zebra_size_t length
)
217 struct interface
*ifp
;
219 ifp
= zebra_interface_add_read (zclient
->ibuf
);
221 if (BGP_DEBUG (zebra
, ZEBRA
) && ifp
)
222 zlog_debug("Zebra rcvd: interface add %s", ifp
->name
);
228 bgp_interface_delete (int command
, struct zclient
*zclient
,
232 struct interface
*ifp
;
235 ifp
= zebra_interface_state_read (s
);
236 ifp
->ifindex
= IFINDEX_INTERNAL
;
238 if (BGP_DEBUG (zebra
, ZEBRA
))
239 zlog_debug("Zebra rcvd: interface delete %s", ifp
->name
);
245 bgp_interface_up (int command
, struct zclient
*zclient
, zebra_size_t length
)
248 struct interface
*ifp
;
250 struct nbr_connected
*nc
;
251 struct listnode
*node
, *nnode
;
254 ifp
= zebra_interface_state_read (s
);
259 if (BGP_DEBUG (zebra
, ZEBRA
))
260 zlog_debug("Zebra rcvd: interface %s up", ifp
->name
);
262 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
263 bgp_connected_add (c
);
265 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
266 bgp_nbr_connected_add (nc
);
272 bgp_interface_down (int command
, struct zclient
*zclient
, zebra_size_t length
)
275 struct interface
*ifp
;
277 struct nbr_connected
*nc
;
278 struct listnode
*node
, *nnode
;
281 ifp
= zebra_interface_state_read (s
);
285 if (BGP_DEBUG (zebra
, ZEBRA
))
286 zlog_debug("Zebra rcvd: interface %s down", ifp
->name
);
288 for (ALL_LIST_ELEMENTS (ifp
->connected
, node
, nnode
, c
))
289 bgp_connected_delete (c
);
291 for (ALL_LIST_ELEMENTS (ifp
->nbr_connected
, node
, nnode
, nc
))
292 bgp_nbr_connected_delete (nc
, 1);
294 /* Fast external-failover */
296 struct listnode
*mnode
;
300 for (ALL_LIST_ELEMENTS_RO (bm
->bgp
, mnode
, bgp
))
302 if (CHECK_FLAG (bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
305 for (ALL_LIST_ELEMENTS (bgp
->peer
, node
, nnode
, peer
))
307 if ((peer
->ttl
!= 1) && (peer
->gtsm_hops
!= 1))
310 if (ifp
== peer
->nexthop
.ifp
)
311 BGP_EVENT_ADD (peer
, BGP_Stop
);
320 bgp_interface_address_add (int command
, struct zclient
*zclient
,
323 struct connected
*ifc
;
325 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
330 if (bgp_debug_zebra(ifc
->address
))
333 prefix2str(ifc
->address
, buf
, sizeof(buf
));
334 zlog_debug("Zebra rcvd: interface %s address add %s",
335 ifc
->ifp
->name
, buf
);
338 if (if_is_operative (ifc
->ifp
))
340 bgp_connected_add (ifc
);
341 /* If we have learnt of any neighbors on this interface,
342 * check to kick off any BGP interface-based neighbors,
343 * but only if this is a link-local address.
345 if (IN6_IS_ADDR_LINKLOCAL(&ifc
->address
->u
.prefix6
) &&
346 !list_isempty(ifc
->ifp
->nbr_connected
))
347 bgp_start_interface_nbrs (ifc
->ifp
);
354 bgp_interface_address_delete (int command
, struct zclient
*zclient
,
357 struct connected
*ifc
;
359 ifc
= zebra_interface_address_read (command
, zclient
->ibuf
);
364 if (bgp_debug_zebra(ifc
->address
))
367 prefix2str(ifc
->address
, buf
, sizeof(buf
));
368 zlog_debug("Zebra rcvd: interface %s address delete %s",
369 ifc
->ifp
->name
, buf
);
372 if (if_is_operative (ifc
->ifp
))
373 bgp_connected_delete (ifc
);
375 connected_free (ifc
);
381 bgp_interface_nbr_address_add (int command
, struct zclient
*zclient
,
384 struct nbr_connected
*ifc
= NULL
;
386 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
391 if (bgp_debug_zebra(ifc
->address
))
394 prefix2str(ifc
->address
, buf
, sizeof(buf
));
395 zlog_debug("Zebra rcvd: interface %s nbr address add %s",
396 ifc
->ifp
->name
, buf
);
399 if (if_is_operative (ifc
->ifp
))
400 bgp_nbr_connected_add (ifc
);
406 bgp_interface_nbr_address_delete (int command
, struct zclient
*zclient
,
409 struct nbr_connected
*ifc
= NULL
;
411 ifc
= zebra_interface_nbr_address_read (command
, zclient
->ibuf
);
416 if (bgp_debug_zebra(ifc
->address
))
419 prefix2str(ifc
->address
, buf
, sizeof(buf
));
420 zlog_debug("Zebra rcvd: interface %s nbr address delete %s",
421 ifc
->ifp
->name
, buf
);
424 if (if_is_operative (ifc
->ifp
))
425 bgp_nbr_connected_delete (ifc
, 0);
427 nbr_connected_free (ifc
);
432 /* Zebra route add and delete treatment. */
434 zebra_read_ipv4 (int command
, struct zclient
*zclient
, zebra_size_t length
)
437 struct zapi_ipv4 api
;
438 struct in_addr nexthop
;
439 struct prefix_ipv4 p
;
440 unsigned int ifindex
;
445 /* Type, flags, message. */
446 api
.type
= stream_getc (s
);
447 api
.instance
= stream_getw (s
);
448 api
.flags
= stream_getc (s
);
449 api
.message
= stream_getc (s
);
452 memset (&p
, 0, sizeof (struct prefix_ipv4
));
454 p
.prefixlen
= stream_getc (s
);
455 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
457 /* Nexthop, ifindex, distance, metric. */
458 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
460 api
.nexthop_num
= stream_getc (s
);
461 nexthop
.s_addr
= stream_get_ipv4 (s
);
464 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
466 api
.ifindex_num
= stream_getc (s
);
467 ifindex
= stream_getl (s
); /* ifindex, unused */
474 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
475 api
.distance
= stream_getc (s
);
477 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
478 api
.metric
= stream_getl (s
);
482 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
483 api
.tag
= stream_getw (s
);
487 if (command
== ZEBRA_IPV4_ROUTE_ADD
)
489 if (bgp_debug_zebra((struct prefix
*)&p
))
491 char buf
[2][INET_ADDRSTRLEN
];
492 zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
493 zebra_route_string(api
.type
), api
.instance
,
494 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
496 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
500 bgp_redistribute_add((struct prefix
*)&p
, &nexthop
, NULL
, ifindex
,
501 api
.metric
, api
.type
, api
.instance
, api
.tag
);
505 if (bgp_debug_zebra((struct prefix
*)&p
))
507 char buf
[2][INET_ADDRSTRLEN
];
508 zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
509 "nexthop %s metric %u tag %d",
510 zebra_route_string(api
.type
), api
.instance
,
511 inet_ntop(AF_INET
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
513 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
517 bgp_redistribute_delete((struct prefix
*)&p
, api
.type
, api
.instance
);
524 /* Zebra route add and delete treatment. */
526 zebra_read_ipv6 (int command
, struct zclient
*zclient
, zebra_size_t length
)
529 struct zapi_ipv6 api
;
530 struct in6_addr nexthop
;
531 struct prefix_ipv6 p
;
532 unsigned int ifindex
;
535 memset (&nexthop
, 0, sizeof (struct in6_addr
));
537 /* Type, flags, message. */
538 api
.type
= stream_getc (s
);
539 api
.instance
= stream_getw (s
);
540 api
.flags
= stream_getc (s
);
541 api
.message
= stream_getc (s
);
544 memset (&p
, 0, sizeof (struct prefix_ipv6
));
546 p
.prefixlen
= stream_getc (s
);
547 stream_get (&p
.prefix
, s
, PSIZE (p
.prefixlen
));
549 /* Nexthop, ifindex, distance, metric. */
550 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
))
552 api
.nexthop_num
= stream_getc (s
);
553 stream_get (&nexthop
, s
, 16);
556 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
))
558 api
.ifindex_num
= stream_getc (s
);
559 ifindex
= stream_getl (s
); /* ifindex, unused */
566 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
))
567 api
.distance
= stream_getc (s
);
571 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
))
572 api
.metric
= stream_getl (s
);
576 if (CHECK_FLAG (api
.message
, ZAPI_MESSAGE_TAG
))
577 api
.tag
= stream_getw (s
);
581 /* Simply ignore link-local address. */
582 if (IN6_IS_ADDR_LINKLOCAL (&p
.prefix
))
585 if (command
== ZEBRA_IPV6_ROUTE_ADD
)
587 if (bgp_debug_zebra((struct prefix
*)&p
))
589 char buf
[2][INET6_ADDRSTRLEN
];
590 zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
591 zebra_route_string(api
.type
), api
.instance
,
592 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
594 inet_ntop(AF_INET
, &nexthop
, buf
[1], sizeof(buf
[1])),
598 bgp_redistribute_add ((struct prefix
*)&p
, NULL
, &nexthop
, ifindex
,
599 api
.metric
, api
.type
, api
.instance
, api
.tag
);
603 if (bgp_debug_zebra((struct prefix
*)&p
))
605 char buf
[2][INET6_ADDRSTRLEN
];
606 zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
607 "nexthop %s metric %u tag %d",
608 zebra_route_string(api
.type
), api
.instance
,
609 inet_ntop(AF_INET6
, &p
.prefix
, buf
[0], sizeof(buf
[0])),
611 inet_ntop(AF_INET6
, &nexthop
, buf
[1], sizeof(buf
[1])),
615 bgp_redistribute_delete ((struct prefix
*) &p
, api
.type
, api
.instance
);
620 #endif /* HAVE_IPV6 */
623 if_lookup_by_ipv4 (struct in_addr
*addr
)
625 struct listnode
*ifnode
;
626 struct listnode
*cnode
;
627 struct interface
*ifp
;
628 struct connected
*connected
;
629 struct prefix_ipv4 p
;
634 p
.prefixlen
= IPV4_MAX_BITLEN
;
636 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
638 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
640 cp
= connected
->address
;
642 if (cp
->family
== AF_INET
)
643 if (prefix_match (cp
, (struct prefix
*)&p
))
651 if_lookup_by_ipv4_exact (struct in_addr
*addr
)
653 struct listnode
*ifnode
;
654 struct listnode
*cnode
;
655 struct interface
*ifp
;
656 struct connected
*connected
;
659 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
661 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
663 cp
= connected
->address
;
665 if (cp
->family
== AF_INET
)
666 if (IPV4_ADDR_SAME (&cp
->u
.prefix4
, addr
))
675 if_lookup_by_ipv6 (struct in6_addr
*addr
, unsigned int ifindex
)
677 struct listnode
*ifnode
;
678 struct listnode
*cnode
;
679 struct interface
*ifp
;
680 struct connected
*connected
;
681 struct prefix_ipv6 p
;
686 p
.prefixlen
= IPV6_MAX_BITLEN
;
688 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
690 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
692 cp
= connected
->address
;
694 if (cp
->family
== AF_INET6
)
695 if (prefix_match (cp
, (struct prefix
*)&p
))
697 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
.s6_addr32
[0]))
699 if (ifindex
== ifp
->ifindex
)
711 if_lookup_by_ipv6_exact (struct in6_addr
*addr
, unsigned int ifindex
)
713 struct listnode
*ifnode
;
714 struct listnode
*cnode
;
715 struct interface
*ifp
;
716 struct connected
*connected
;
719 for (ALL_LIST_ELEMENTS_RO (iflist
, ifnode
, ifp
))
721 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
723 cp
= connected
->address
;
725 if (cp
->family
== AF_INET6
)
726 if (IPV6_ADDR_SAME (&cp
->u
.prefix6
, addr
))
728 if (IN6_IS_ADDR_LINKLOCAL(&cp
->u
.prefix6
))
730 if (ifindex
== ifp
->ifindex
)
742 if_get_ipv6_global (struct interface
*ifp
, struct in6_addr
*addr
)
744 struct listnode
*cnode
;
745 struct connected
*connected
;
748 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
750 cp
= connected
->address
;
752 if (cp
->family
== AF_INET6
)
753 if (! IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
755 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
763 if_get_ipv6_local (struct interface
*ifp
, struct in6_addr
*addr
)
765 struct listnode
*cnode
;
766 struct connected
*connected
;
769 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
771 cp
= connected
->address
;
773 if (cp
->family
== AF_INET6
)
774 if (IN6_IS_ADDR_LINKLOCAL (&cp
->u
.prefix6
))
776 memcpy (addr
, &cp
->u
.prefix6
, IPV6_MAX_BYTELEN
);
782 #endif /* HAVE_IPV6 */
785 if_get_ipv4_address (struct interface
*ifp
, struct in_addr
*addr
)
787 struct listnode
*cnode
;
788 struct connected
*connected
;
791 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, cnode
, connected
))
793 cp
= connected
->address
;
794 if ((cp
->family
== AF_INET
) && !ipv4_martian(&(cp
->u
.prefix4
)))
796 *addr
= cp
->u
.prefix4
;
804 bgp_nexthop_set (union sockunion
*local
, union sockunion
*remote
,
805 struct bgp_nexthop
*nexthop
, struct peer
*peer
)
808 struct interface
*ifp
= NULL
;
810 memset (nexthop
, 0, sizeof (struct bgp_nexthop
));
817 if (local
->sa
.sa_family
== AF_INET
)
819 nexthop
->v4
= local
->sin
.sin_addr
;
821 ifp
= if_lookup_by_name (peer
->update_if
);
823 ifp
= if_lookup_by_ipv4_exact (&local
->sin
.sin_addr
);
826 if (local
->sa
.sa_family
== AF_INET6
)
828 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
830 if (peer
->conf_if
|| peer
->ifname
)
831 ifp
= if_lookup_by_index (if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
));
833 else if (peer
->update_if
)
834 ifp
= if_lookup_by_name (peer
->update_if
);
836 ifp
= if_lookup_by_ipv6_exact (&local
->sin6
.sin6_addr
,
837 local
->sin6
.sin6_scope_id
);
839 #endif /* HAVE_IPV6 */
846 /* IPv4 connection, fetch and store IPv6 local address(es) if any. */
847 if (local
->sa
.sa_family
== AF_INET
)
851 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
853 /* There is no global nexthop. */
855 if_get_ipv6_local (ifp
, &nexthop
->v6_global
);
857 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
858 #endif /* HAVE_IPV6 */
862 /* IPv6 connection, fetch and store IPv4 local address if any. */
863 if (local
->sa
.sa_family
== AF_INET6
)
865 struct interface
*direct
= NULL
;
868 ret
= if_get_ipv4_address(ifp
, &nexthop
->v4
);
869 if (!ret
&& peer
->local_id
.s_addr
)
870 nexthop
->v4
= peer
->local_id
;
873 if (! IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
))
875 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
878 /* If directory connected set link-local address. */
879 direct
= if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
,
880 remote
->sin6
.sin6_scope_id
);
882 if_get_ipv6_local (ifp
, &nexthop
->v6_local
);
885 /* Link-local address. */
887 ret
= if_get_ipv6_global (ifp
, &nexthop
->v6_global
);
889 /* If there is no global address. Set link-local address as
890 global. I know this break RFC specification... */
891 /* In this scenario, the expectation for interop is that the
892 * network admin would use a route-map to specify the global
896 memcpy (&nexthop
->v6_global
, &local
->sin6
.sin6_addr
,
898 /* Always set the link-local address */
899 memcpy (&nexthop
->v6_local
, &local
->sin6
.sin6_addr
,
904 if (IN6_IS_ADDR_LINKLOCAL (&local
->sin6
.sin6_addr
) ||
905 if_lookup_by_ipv6 (&remote
->sin6
.sin6_addr
, remote
->sin6
.sin6_scope_id
))
906 peer
->shared_network
= 1;
908 peer
->shared_network
= 0;
910 /* KAME stack specific treatment. */
912 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_global
)
913 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
))
915 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_global
, 0);
917 if (IN6_IS_ADDR_LINKLOCAL (&nexthop
->v6_local
)
918 && IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
))
920 SET_IN6_LINKLOCAL_IFINDEX (nexthop
->v6_local
, 0);
923 #endif /* HAVE_IPV6 */
925 /* If we have identified the local interface, there is no error for now. */
929 static struct in6_addr
*
930 bgp_info_to_ipv6_nexthop (struct bgp_info
*info
)
932 struct in6_addr
*nexthop
= NULL
;
934 /* Only global address nexthop exists. */
935 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
)
936 nexthop
= &info
->attr
->extra
->mp_nexthop_global
;
938 /* If both global and link-local address present. */
939 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
941 /* Workaround for Cisco's nexthop bug. */
942 if (IN6_IS_ADDR_UNSPECIFIED (&info
->attr
->extra
->mp_nexthop_global
)
943 && info
->peer
->su_remote
->sa
.sa_family
== AF_INET6
)
944 nexthop
= &info
->peer
->su_remote
->sin6
.sin6_addr
;
946 nexthop
= &info
->attr
->extra
->mp_nexthop_local
;
953 bgp_table_map_apply (struct route_map
*map
, struct prefix
*p
,
954 struct bgp_info
*info
)
956 if (route_map_apply(map
, p
, RMAP_BGP
, info
) != RMAP_DENYMATCH
)
959 if (bgp_debug_zebra(p
))
961 if (p
->family
== AF_INET
)
963 char buf
[2][INET_ADDRSTRLEN
];
964 zlog_debug("Zebra rmap deny: IPv4 route %s/%d nexthop %s",
965 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
967 inet_ntop(AF_INET
, &info
->attr
->nexthop
, buf
[1],
970 if (p
->family
== AF_INET6
)
972 char buf
[2][INET6_ADDRSTRLEN
];
973 zlog_debug("Zebra rmap deny: IPv6 route %s/%d nexthop %s",
974 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
976 inet_ntop(AF_INET6
, bgp_info_to_ipv6_nexthop(info
), buf
[1],
984 bgp_zebra_announce (struct prefix
*p
, struct bgp_info
*info
, struct bgp
*bgp
,
985 afi_t afi
, safi_t safi
)
990 struct bgp_info
*mpinfo
;
991 size_t oldsize
, newsize
;
992 u_int32_t nhcount
, metric
;
993 struct bgp_info local_info
;
994 struct bgp_info
*info_cp
= &local_info
;
997 if (zclient
->sock
< 0)
1000 if ((p
->family
== AF_INET
&& !zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BGP
].enabled
)
1001 || (p
->family
== AF_INET6
&& !zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_BGP
].enabled
))
1004 if (bgp
->main_zebra_update_hold
)
1010 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1011 tag
= info
->attr
->extra
->tag
;
1015 /* When we create an aggregate route we must also install a Null0 route in
1017 if (info
->sub_type
== BGP_ROUTE_AGGREGATE
)
1018 SET_FLAG (flags
, ZEBRA_FLAG_BLACKHOLE
);
1020 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
||
1021 info
->sub_type
== BGP_ROUTE_AGGREGATE
)
1023 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
1024 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1027 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
1028 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
1029 || bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
1031 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1033 nhcount
= 1 + bgp_info_mpath_count (info
);
1035 if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(info
->attr
))
1037 struct zapi_ipv4 api
;
1038 struct in_addr
*nexthop
;
1039 char buf
[2][INET_ADDRSTRLEN
];
1040 int valid_nh_count
= 0;
1042 /* resize nexthop buffer size if necessary */
1043 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1044 (sizeof (struct in_addr
*) * nhcount
))
1046 newsize
= (sizeof (struct in_addr
*) * nhcount
);
1047 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1048 if (newsize
== oldsize
)
1050 zlog_err ("can't resize nexthop buffer");
1054 stream_reset (bgp_nexthop_buf
);
1057 /* Metric is currently based on the best-path only. */
1058 metric
= info
->attr
->med
;
1060 if (bgp
->table_map
[afi
][safi
].name
)
1062 BGP_INFO_ATTR_BUF_INIT();
1064 /* Copy info and attributes, so the route-map apply doesn't modify the
1066 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1067 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1069 metric
= info_cp
->attr
->med
;
1070 nexthop
= &info_cp
->attr
->nexthop
;
1072 if (info_cp
->attr
->extra
)
1073 tag
= info_cp
->attr
->extra
->tag
;
1075 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1079 nexthop
= &info
->attr
->nexthop
;
1084 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1088 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1089 mpinfo
= bgp_info_mpath_next (mpinfo
))
1093 if (bgp
->table_map
[afi
][safi
].name
)
1095 /* Copy info and attributes, so the route-map apply doesn't modify the
1097 BGP_INFO_ATTR_BUF_COPY(mpinfo
, info_cp
);
1098 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1099 nexthop
= &info_cp
->attr
->nexthop
;
1100 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1104 nexthop
= &mpinfo
->attr
->nexthop
;
1107 if (nexthop
== NULL
)
1110 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in_addr
*));
1115 api
.type
= ZEBRA_ROUTE_BGP
;
1119 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1121 /* Note that this currently only applies to Null0 routes for aggregates.
1122 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv4_route to encode a special
1123 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1124 * do not want to also encode the 0.0.0.0 nexthop for the aggregate route.
1126 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1127 api
.nexthop_num
= 0;
1129 api
.nexthop_num
= valid_nh_count
;
1131 api
.nexthop
= (struct in_addr
**)STREAM_DATA (bgp_nexthop_buf
);
1132 api
.ifindex_num
= 0;
1133 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1134 api
.metric
= metric
;
1138 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1142 distance
= bgp_distance_apply (p
, info
, bgp
);
1146 SET_FLAG (api
.message
, ZAPI_MESSAGE_DISTANCE
);
1147 api
.distance
= distance
;
1150 if (bgp_debug_zebra(p
))
1153 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d"
1154 " count %d", (valid_nh_count
? "add":"delete"),
1155 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1156 p
->prefixlen
, api
.metric
, api
.tag
, api
.nexthop_num
);
1157 for (i
= 0; i
< api
.nexthop_num
; i
++)
1158 zlog_debug(" IPv4 [nexthop %d] %s", i
+1,
1159 inet_ntop(AF_INET
, api
.nexthop
[i
], buf
[1], sizeof(buf
[1])));
1162 zapi_ipv4_route (valid_nh_count
? ZEBRA_IPV4_ROUTE_ADD
: ZEBRA_IPV4_ROUTE_DELETE
,
1163 zclient
, (struct prefix_ipv4
*) p
, &api
);
1167 /* We have to think about a IPv6 link-local address curse. */
1168 if (p
->family
== AF_INET6
||
1169 (p
->family
== AF_INET
&& BGP_ATTR_NEXTHOP_AFI_IP6(info
->attr
)))
1171 unsigned int ifindex
;
1172 struct in6_addr
*nexthop
;
1173 struct zapi_ipv6 api
;
1174 int valid_nh_count
= 0;
1175 char buf
[2][INET6_ADDRSTRLEN
];
1177 /* resize nexthop buffer size if necessary */
1178 if ((oldsize
= stream_get_size (bgp_nexthop_buf
)) <
1179 (sizeof (struct in6_addr
*) * nhcount
))
1181 newsize
= (sizeof (struct in6_addr
*) * nhcount
);
1182 newsize
= stream_resize (bgp_nexthop_buf
, newsize
);
1183 if (newsize
== oldsize
)
1185 zlog_err ("can't resize nexthop buffer");
1189 stream_reset (bgp_nexthop_buf
);
1191 /* resize ifindices buffer size if necessary */
1192 if ((oldsize
= stream_get_size (bgp_ifindices_buf
)) <
1193 (sizeof (unsigned int) * nhcount
))
1195 newsize
= (sizeof (unsigned int) * nhcount
);
1196 newsize
= stream_resize (bgp_ifindices_buf
, newsize
);
1197 if (newsize
== oldsize
)
1199 zlog_err ("can't resize nexthop buffer");
1203 stream_reset (bgp_ifindices_buf
);
1208 assert (info
->attr
->extra
);
1210 /* Metric is currently based on the best-path only. */
1211 metric
= info
->attr
->med
;
1213 if (bgp
->table_map
[afi
][safi
].name
)
1215 BGP_INFO_ATTR_BUF_INIT();
1217 /* Copy info and attributes, so the route-map apply doesn't modify the
1219 BGP_INFO_ATTR_BUF_COPY(info
, info_cp
);
1220 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1222 metric
= info_cp
->attr
->med
;
1223 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1225 if (info_cp
->attr
->extra
)
1226 tag
= info_cp
->attr
->extra
->tag
;
1228 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1232 nexthop
= bgp_info_to_ipv6_nexthop(info
);
1237 if (info
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1238 if (info
->peer
->nexthop
.ifp
)
1239 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1243 if (info
->peer
->conf_if
|| info
->peer
->ifname
)
1244 ifindex
= if_nametoindex (info
->peer
->conf_if
? info
->peer
->conf_if
: info
->peer
->ifname
);
1245 else if (info
->peer
->nexthop
.ifp
)
1246 ifindex
= info
->peer
->nexthop
.ifp
->ifindex
;
1248 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1249 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1253 for (mpinfo
= bgp_info_mpath_first (info
); mpinfo
;
1254 mpinfo
= bgp_info_mpath_next (mpinfo
))
1259 if (bgp
->table_map
[afi
][safi
].name
)
1261 /* Copy info and attributes, so the route-map apply doesn't modify the
1263 BGP_INFO_ATTR_BUF_COPY(mpinfo
, info_cp
);
1264 if (bgp_table_map_apply(bgp
->table_map
[afi
][safi
].map
, p
, info_cp
))
1265 nexthop
= bgp_info_to_ipv6_nexthop(info_cp
);
1266 BGP_INFO_ATTR_BUF_FREE(info_cp
);
1270 nexthop
= bgp_info_to_ipv6_nexthop(mpinfo
);
1273 if (nexthop
== NULL
)
1276 if (mpinfo
->attr
->extra
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
)
1277 if (mpinfo
->peer
->nexthop
.ifp
)
1278 ifindex
= mpinfo
->peer
->nexthop
.ifp
->ifindex
;
1282 if (mpinfo
->peer
->conf_if
|| mpinfo
->peer
->ifname
)
1283 ifindex
= if_nametoindex (mpinfo
->peer
->conf_if
? mpinfo
->peer
->conf_if
: mpinfo
->peer
->ifname
);
1284 else if (mpinfo
->peer
->nexthop
.ifp
)
1285 ifindex
= mpinfo
->peer
->nexthop
.ifp
->ifindex
;
1290 stream_put (bgp_nexthop_buf
, &nexthop
, sizeof (struct in6_addr
*));
1291 stream_put (bgp_ifindices_buf
, &ifindex
, sizeof (unsigned int));
1295 /* Make Zebra API structure. */
1297 api
.type
= ZEBRA_ROUTE_BGP
;
1301 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1303 /* Note that this currently only applies to Null0 routes for aggregates.
1304 * ZEBRA_FLAG_BLACKHOLE signals zapi_ipv6_route to encode a special
1305 * BLACKHOLE nexthop. We want to set api.nexthop_num to zero since we
1306 * do not want to also encode the :: nexthop for the aggregate route.
1308 if (CHECK_FLAG(flags
, ZEBRA_FLAG_BLACKHOLE
))
1309 api
.nexthop_num
= 0;
1311 api
.nexthop_num
= valid_nh_count
;
1313 api
.nexthop
= (struct in6_addr
**)STREAM_DATA (bgp_nexthop_buf
);
1314 SET_FLAG (api
.message
, ZAPI_MESSAGE_IFINDEX
);
1315 api
.ifindex_num
= valid_nh_count
;
1316 api
.ifindex
= (unsigned int *)STREAM_DATA (bgp_ifindices_buf
);
1317 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1318 api
.metric
= metric
;
1322 SET_FLAG (api
.message
, ZAPI_MESSAGE_TAG
);
1326 if (p
->family
== AF_INET
)
1328 if (bgp_debug_zebra(p
))
1331 zlog_debug("Zebra send: IPv4 route %s %s/%d metric %u tag %d",
1332 valid_nh_count
? "add" : "delete",
1333 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1334 p
->prefixlen
, api
.metric
, api
.tag
);
1335 for (i
= 0; i
< api
.nexthop_num
; i
++)
1336 zlog_debug(" IPv6 [nexthop %d] %s", i
+1,
1337 inet_ntop(AF_INET6
, api
.nexthop
[i
], buf
[1], sizeof(buf
[1])));
1341 zapi_ipv4_route_ipv6_nexthop (ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD
,
1342 zclient
, (struct prefix_ipv4
*) p
,
1343 (struct zapi_ipv6
*)&api
);
1345 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
,
1346 zclient
, (struct prefix_ipv4
*) p
, (struct zapi_ipv4
*)&api
);
1350 if (bgp_debug_zebra(p
))
1353 zlog_debug("Zebra send: IPv6 route %s %s/%d metric %u tag %d",
1354 valid_nh_count
? "add" : "delete",
1355 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
1356 p
->prefixlen
, api
.metric
, api
.tag
);
1357 for (i
= 0; i
< api
.nexthop_num
; i
++)
1358 zlog_debug(" IPv6 [nexthop %d] %s", i
+1,
1359 inet_ntop(AF_INET6
, api
.nexthop
[i
], buf
[1], sizeof(buf
[1])));
1362 zapi_ipv6_route (valid_nh_count
?
1363 ZEBRA_IPV6_ROUTE_ADD
: ZEBRA_IPV6_ROUTE_DELETE
,
1364 zclient
, (struct prefix_ipv6
*) p
, &api
);
1367 #endif /* HAVE_IPV6 */
1370 /* Announce all routes of a table to zebra */
1372 bgp_zebra_announce_table (struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1374 struct bgp_node
*rn
;
1375 struct bgp_table
*table
;
1376 struct bgp_info
*ri
;
1378 table
= bgp
->rib
[afi
][safi
];
1381 for (rn
= bgp_table_top (table
); rn
; rn
= bgp_route_next (rn
))
1382 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
1383 if (CHECK_FLAG (ri
->flags
, BGP_INFO_SELECTED
)
1384 && ri
->type
== ZEBRA_ROUTE_BGP
1385 && ri
->sub_type
== BGP_ROUTE_NORMAL
)
1386 bgp_zebra_announce (&rn
->p
, ri
, bgp
, afi
, safi
);
1390 bgp_zebra_withdraw (struct prefix
*p
, struct bgp_info
*info
, safi_t safi
)
1395 if (zclient
->sock
< 0)
1398 if ((p
->family
== AF_INET
&& !zclient
->redist
[AFI_IP
][ZEBRA_ROUTE_BGP
].enabled
)
1399 || (p
->family
== AF_INET6
&& !zclient
->redist
[AFI_IP6
][ZEBRA_ROUTE_BGP
].enabled
))
1406 if (peer
->sort
== BGP_PEER_IBGP
)
1408 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1409 SET_FLAG (flags
, ZEBRA_FLAG_IBGP
);
1412 if ((peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
!= 1)
1413 || CHECK_FLAG (peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)
1414 || bgp_flag_check(peer
->bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
1415 SET_FLAG (flags
, ZEBRA_FLAG_INTERNAL
);
1417 if (p
->family
== AF_INET
)
1419 struct zapi_ipv4 api
;
1423 api
.type
= ZEBRA_ROUTE_BGP
;
1427 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1428 api
.nexthop_num
= 0;
1430 api
.ifindex_num
= 0;
1431 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1432 api
.metric
= info
->attr
->med
;
1434 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1436 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1437 api
.tag
= info
->attr
->extra
->tag
;
1440 if (bgp_debug_zebra(p
))
1442 char buf
[2][INET_ADDRSTRLEN
];
1443 zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
1444 inet_ntop(AF_INET
, &p
->u
.prefix4
, buf
[0], sizeof(buf
[0])),
1445 p
->prefixlen
, api
.metric
, api
.tag
);
1448 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
1449 (struct prefix_ipv4
*) p
, &api
);
1452 /* We have to think about a IPv6 link-local address curse. */
1453 if (p
->family
== AF_INET6
)
1455 struct zapi_ipv6 api
;
1457 assert (info
->attr
->extra
);
1460 api
.type
= ZEBRA_ROUTE_BGP
;
1464 SET_FLAG (api
.message
, ZAPI_MESSAGE_NEXTHOP
);
1465 api
.nexthop_num
= 0;
1467 api
.ifindex_num
= 0;
1468 SET_FLAG (api
.message
, ZAPI_MESSAGE_METRIC
);
1469 api
.metric
= info
->attr
->med
;
1471 if ((info
->attr
->extra
) && (info
->attr
->extra
->tag
!= 0))
1473 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
1474 api
.tag
= info
->attr
->extra
->tag
;
1477 if (bgp_debug_zebra(p
))
1479 char buf
[2][INET6_ADDRSTRLEN
];
1480 zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
1481 inet_ntop(AF_INET6
, &p
->u
.prefix6
, buf
[0], sizeof(buf
[0])),
1482 p
->prefixlen
, api
.metric
, api
.tag
);
1485 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
1486 (struct prefix_ipv6
*) p
, &api
);
1488 #endif /* HAVE_IPV6 */
1491 bgp_redist_lookup (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1493 struct list
*red_list
;
1494 struct listnode
*node
;
1495 struct bgp_redist
*red
;
1497 red_list
= bgp
->redist
[afi
][type
];
1501 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
1502 if (red
->instance
== instance
)
1509 bgp_redist_add (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1511 struct list
*red_list
;
1512 struct bgp_redist
*red
;
1514 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1518 if (!bgp
->redist
[afi
][type
])
1519 bgp
->redist
[afi
][type
] = list_new();
1521 red_list
= bgp
->redist
[afi
][type
];
1522 red
= (struct bgp_redist
*)XCALLOC(MTYPE_BGP_REDIST
, sizeof(struct bgp_redist
));
1523 red
->instance
= instance
;
1525 listnode_add(red_list
, red
);
1531 bgp_redist_del (struct bgp
*bgp
, afi_t afi
, u_char type
, u_short instance
)
1533 struct bgp_redist
*red
;
1535 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1539 listnode_delete(bgp
->redist
[afi
][type
], red
);
1540 if (!bgp
->redist
[afi
][type
]->count
)
1542 list_free(bgp
->redist
[afi
][type
]);
1543 bgp
->redist
[afi
][type
] = NULL
;
1548 /* Other routes redistribution into BGP. */
1550 bgp_redistribute_set (afi_t afi
, int type
, u_short instance
)
1553 /* Return if already redistribute flag is set. */
1554 if (redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1557 redist_add_instance(&zclient
->redist
[afi
][type
], instance
);
1559 /* Return if zebra connection is not established. */
1560 if (zclient
->sock
< 0)
1563 if (BGP_DEBUG (zebra
, ZEBRA
))
1564 zlog_debug("Zebra send: redistribute add afi %d %s %d", afi
,
1565 zebra_route_string(type
), instance
);
1567 /* Send distribute add message to zebra. */
1568 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, instance
);
1574 bgp_redistribute_resend (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1576 /* Return if zebra connection is not established. */
1577 if (zclient
->sock
< 0)
1580 if (BGP_DEBUG (zebra
, ZEBRA
))
1581 zlog_debug("Zebra send: redistribute delete/add afi %d %s %d", afi
,
1582 zebra_route_string(type
), instance
);
1584 /* Send distribute add message to zebra. */
1585 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, afi
, type
, instance
);
1586 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD
, zclient
, afi
, type
, instance
);
1591 /* Redistribute with route-map specification. */
1593 bgp_redistribute_rmap_set (struct bgp_redist
*red
, const char *name
)
1596 && (strcmp (red
->rmap
.name
, name
) == 0))
1600 XFREE(MTYPE_ROUTE_MAP_NAME
, red
->rmap
.name
);
1601 red
->rmap
.name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, name
);
1602 red
->rmap
.map
= route_map_lookup_by_name (name
);
1607 /* Redistribute with metric specification. */
1609 bgp_redistribute_metric_set (struct bgp
*bgp
, struct bgp_redist
*red
, afi_t afi
,
1610 int type
, u_int32_t metric
)
1612 struct bgp_node
*rn
;
1613 struct bgp_info
*ri
;
1615 if (red
->redist_metric_flag
1616 && red
->redist_metric
== metric
)
1619 red
->redist_metric_flag
= 1;
1620 red
->redist_metric
= metric
;
1622 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_UNICAST
]); rn
; rn
= bgp_route_next(rn
)) {
1623 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1624 if (ri
->sub_type
== BGP_ROUTE_REDISTRIBUTE
&& ri
->type
== type
) {
1625 ri
->attr
->med
= red
->redist_metric
;
1626 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
1627 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
1635 /* Unset redistribution. */
1637 bgp_redistribute_unset (struct bgp
*bgp
, afi_t afi
, int type
, u_short instance
)
1639 struct bgp_redist
*red
;
1641 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
1645 /* Unset route-map. */
1647 XFREE(MTYPE_ROUTE_MAP_NAME
, red
->rmap
.name
);
1648 red
->rmap
.name
= NULL
;
1649 red
->rmap
.map
= NULL
;
1652 red
->redist_metric_flag
= 0;
1653 red
->redist_metric
= 0;
1655 bgp_redist_del(bgp
, afi
, type
, instance
);
1657 /* Return if zebra connection is disabled. */
1658 if (!redist_check_instance(&zclient
->redist
[afi
][type
], instance
))
1660 redist_del_instance(&zclient
->redist
[afi
][type
], instance
);
1662 if (zclient
->sock
>= 0)
1664 /* Send distribute delete message to zebra. */
1665 if (BGP_DEBUG (zebra
, ZEBRA
))
1666 zlog_debug("Zebra send: redistribute delete afi %d %s %d",
1667 afi
, zebra_route_string(type
), instance
);
1668 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE
, zclient
, afi
, type
, instance
);
1671 /* Withdraw redistributed routes from current BGP's routing table. */
1672 bgp_redistribute_withdraw (bgp
, afi
, type
, instance
);
1678 bgp_zclient_reset (void)
1680 zclient_reset (zclient
);
1684 bgp_zebra_init (void)
1686 /* Set default values. */
1687 zclient
= zclient_new ();
1688 zclient_init (zclient
, ZEBRA_ROUTE_BGP
, 0);
1689 zclient
->router_id_update
= bgp_router_id_update
;
1690 zclient
->interface_add
= bgp_interface_add
;
1691 zclient
->interface_delete
= bgp_interface_delete
;
1692 zclient
->interface_address_add
= bgp_interface_address_add
;
1693 zclient
->interface_address_delete
= bgp_interface_address_delete
;
1694 zclient
->interface_nbr_address_add
= bgp_interface_nbr_address_add
;
1695 zclient
->interface_nbr_address_delete
= bgp_interface_nbr_address_delete
;
1696 zclient
->ipv4_route_add
= zebra_read_ipv4
;
1697 zclient
->ipv4_route_delete
= zebra_read_ipv4
;
1698 zclient
->interface_up
= bgp_interface_up
;
1699 zclient
->interface_down
= bgp_interface_down
;
1701 zclient
->ipv6_route_add
= zebra_read_ipv6
;
1702 zclient
->ipv6_route_delete
= zebra_read_ipv6
;
1703 #endif /* HAVE_IPV6 */
1704 zclient
->nexthop_update
= bgp_read_nexthop_update
;
1705 zclient
->import_check_update
= bgp_read_import_check_update
;
1707 /* Interface related init. */
1710 bgp_nexthop_buf
= stream_new(BGP_NEXTHOP_BUF_SIZE
);
1711 bgp_ifindices_buf
= stream_new(BGP_IFINDICES_BUF_SIZE
);