version 1.1.1.3, 2013/07/21 23:54:38
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 29 Boston, MA 02111-1307, USA. */
|
Line 29 Boston, MA 02111-1307, USA. */
|
#include "zclient.h" |
#include "zclient.h" |
#include "routemap.h" |
#include "routemap.h" |
#include "thread.h" |
#include "thread.h" |
|
#include "filter.h" |
|
|
#include "bgpd/bgpd.h" |
#include "bgpd/bgpd.h" |
#include "bgpd/bgp_route.h" |
#include "bgpd/bgp_route.h" |
Line 38 Boston, MA 02111-1307, USA. */
|
Line 39 Boston, MA 02111-1307, USA. */
|
#include "bgpd/bgp_fsm.h" |
#include "bgpd/bgp_fsm.h" |
#include "bgpd/bgp_debug.h" |
#include "bgpd/bgp_debug.h" |
#include "bgpd/bgp_mpath.h" |
#include "bgpd/bgp_mpath.h" |
| |
/* All information about zebra. */ |
/* All information about zebra. */ |
struct zclient *zclient = NULL; |
struct zclient *zclient = NULL; |
struct in_addr router_id_zebra; |
struct in_addr router_id_zebra; |
Line 48 struct stream *bgp_nexthop_buf = NULL;
|
Line 49 struct stream *bgp_nexthop_buf = NULL;
|
|
|
/* Router-id update message from zebra. */ |
/* Router-id update message from zebra. */ |
static int |
static int |
bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length) | bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct prefix router_id; |
struct prefix router_id; |
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
Line 76 bgp_router_id_update (int command, struct zclient *zcl
|
Line 78 bgp_router_id_update (int command, struct zclient *zcl
|
|
|
/* Inteface addition message from zebra. */ |
/* Inteface addition message from zebra. */ |
static int |
static int |
bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length) | bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
|
|
ifp = zebra_interface_add_read (zclient->ibuf); | ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); |
|
|
if (BGP_DEBUG(zebra, ZEBRA) && ifp) |
if (BGP_DEBUG(zebra, ZEBRA) && ifp) |
zlog_debug("Zebra rcvd: interface add %s", ifp->name); |
zlog_debug("Zebra rcvd: interface add %s", ifp->name); |
Line 90 bgp_interface_add (int command, struct zclient *zclien
|
Line 93 bgp_interface_add (int command, struct zclient *zclien
|
|
|
static int |
static int |
bgp_interface_delete (int command, struct zclient *zclient, |
bgp_interface_delete (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct interface *ifp; |
struct interface *ifp; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
ifp = zebra_interface_state_read (s); | ifp = zebra_interface_state_read (s, vrf_id); |
ifp->ifindex = IFINDEX_INTERNAL; |
ifp->ifindex = IFINDEX_INTERNAL; |
|
|
if (BGP_DEBUG(zebra, ZEBRA)) |
if (BGP_DEBUG(zebra, ZEBRA)) |
Line 106 bgp_interface_delete (int command, struct zclient *zcl
|
Line 109 bgp_interface_delete (int command, struct zclient *zcl
|
} |
} |
|
|
static int |
static int |
bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length) | bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct interface *ifp; |
struct interface *ifp; |
Line 114 bgp_interface_up (int command, struct zclient *zclient
|
Line 118 bgp_interface_up (int command, struct zclient *zclient
|
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
ifp = zebra_interface_state_read (s); | ifp = zebra_interface_state_read (s, vrf_id); |
|
|
if (! ifp) |
if (! ifp) |
return 0; |
return 0; |
Line 129 bgp_interface_up (int command, struct zclient *zclient
|
Line 133 bgp_interface_up (int command, struct zclient *zclient
|
} |
} |
|
|
static int |
static int |
bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length) | bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct interface *ifp; |
struct interface *ifp; |
Line 137 bgp_interface_down (int command, struct zclient *zclie
|
Line 142 bgp_interface_down (int command, struct zclient *zclie
|
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
ifp = zebra_interface_state_read (s); | ifp = zebra_interface_state_read (s, vrf_id); |
if (! ifp) |
if (! ifp) |
return 0; |
return 0; |
|
|
Line 147 bgp_interface_down (int command, struct zclient *zclie
|
Line 152 bgp_interface_down (int command, struct zclient *zclie
|
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) |
for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) |
bgp_connected_delete (c); |
bgp_connected_delete (c); |
|
|
/* Fast external-failover (Currently IPv4 only) */ | /* Fast external-failover */ |
{ |
{ |
struct listnode *mnode; |
struct listnode *mnode; |
struct bgp *bgp; |
struct bgp *bgp; |
struct peer *peer; |
struct peer *peer; |
struct interface *peer_if; |
|
|
|
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) |
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) |
{ |
{ |
Line 161 bgp_interface_down (int command, struct zclient *zclie
|
Line 165 bgp_interface_down (int command, struct zclient *zclie
|
|
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) |
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) |
{ |
{ |
if (peer->ttl != 1) | if ((peer->ttl != 1) && (peer->gtsm_hops != 1)) |
continue; |
continue; |
|
|
if (peer->su.sa.sa_family == AF_INET) | if (ifp == peer->nexthop.ifp) |
peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr); | |
else | |
continue; | |
| |
if (ifp == peer_if) | |
BGP_EVENT_ADD (peer, BGP_Stop); |
BGP_EVENT_ADD (peer, BGP_Stop); |
} |
} |
} |
} |
Line 180 bgp_interface_down (int command, struct zclient *zclie
|
Line 179 bgp_interface_down (int command, struct zclient *zclie
|
|
|
static int |
static int |
bgp_interface_address_add (int command, struct zclient *zclient, |
bgp_interface_address_add (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct connected *ifc; |
struct connected *ifc; |
|
|
ifc = zebra_interface_address_read (command, zclient->ibuf); | ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id); |
|
|
if (ifc == NULL) |
if (ifc == NULL) |
return 0; |
return 0; |
Line 205 bgp_interface_address_add (int command, struct zclient
|
Line 204 bgp_interface_address_add (int command, struct zclient
|
|
|
static int |
static int |
bgp_interface_address_delete (int command, struct zclient *zclient, |
bgp_interface_address_delete (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct connected *ifc; |
struct connected *ifc; |
|
|
ifc = zebra_interface_address_read (command, zclient->ibuf); | ifc = zebra_interface_address_read (command, zclient->ibuf, vrf_id); |
|
|
if (ifc == NULL) |
if (ifc == NULL) |
return 0; |
return 0; |
Line 232 bgp_interface_address_delete (int command, struct zcli
|
Line 231 bgp_interface_address_delete (int command, struct zcli
|
|
|
/* Zebra route add and delete treatment. */ |
/* Zebra route add and delete treatment. */ |
static int |
static int |
zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) | zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct zapi_ipv4 api; |
struct zapi_ipv4 api; |
struct in_addr nexthop; |
struct in_addr nexthop; |
struct prefix_ipv4 p; |
struct prefix_ipv4 p; |
|
unsigned char plength = 0; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
nexthop.s_addr = 0; |
nexthop.s_addr = 0; |
Line 250 zebra_read_ipv4 (int command, struct zclient *zclient,
|
Line 251 zebra_read_ipv4 (int command, struct zclient *zclient,
|
/* IPv4 prefix. */ |
/* IPv4 prefix. */ |
memset (&p, 0, sizeof (struct prefix_ipv4)); |
memset (&p, 0, sizeof (struct prefix_ipv4)); |
p.family = AF_INET; |
p.family = AF_INET; |
p.prefixlen = stream_getc (s); | plength = stream_getc (s); |
| p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
|
|
/* Nexthop, ifindex, distance, metric. */ |
/* Nexthop, ifindex, distance, metric. */ |
Line 305 zebra_read_ipv4 (int command, struct zclient *zclient,
|
Line 307 zebra_read_ipv4 (int command, struct zclient *zclient,
|
return 0; |
return 0; |
} |
} |
|
|
#ifdef HAVE_IPV6 |
|
/* Zebra route add and delete treatment. */ |
/* Zebra route add and delete treatment. */ |
static int |
static int |
zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) | zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct zapi_ipv6 api; |
struct zapi_ipv6 api; |
struct in6_addr nexthop; |
struct in6_addr nexthop; |
struct prefix_ipv6 p; |
struct prefix_ipv6 p; |
|
unsigned char plength = 0; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
memset (&nexthop, 0, sizeof (struct in6_addr)); |
memset (&nexthop, 0, sizeof (struct in6_addr)); |
Line 326 zebra_read_ipv6 (int command, struct zclient *zclient,
|
Line 329 zebra_read_ipv6 (int command, struct zclient *zclient,
|
/* IPv6 prefix. */ |
/* IPv6 prefix. */ |
memset (&p, 0, sizeof (struct prefix_ipv6)); |
memset (&p, 0, sizeof (struct prefix_ipv6)); |
p.family = AF_INET6; |
p.family = AF_INET6; |
p.prefixlen = stream_getc (s); | plength = stream_getc (s); |
| p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, plength); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
stream_get (&p.prefix, s, PSIZE (p.prefixlen)); |
|
|
/* Nexthop, ifindex, distance, metric. */ |
/* Nexthop, ifindex, distance, metric. */ |
Line 386 zebra_read_ipv6 (int command, struct zclient *zclient,
|
Line 390 zebra_read_ipv6 (int command, struct zclient *zclient,
|
|
|
return 0; |
return 0; |
} |
} |
#endif /* HAVE_IPV6 */ | |
| |
struct interface * |
struct interface * |
if_lookup_by_ipv4 (struct in_addr *addr) |
if_lookup_by_ipv4 (struct in_addr *addr) |
{ |
{ |
Line 439 if_lookup_by_ipv4_exact (struct in_addr *addr)
|
Line 442 if_lookup_by_ipv4_exact (struct in_addr *addr)
|
return NULL; |
return NULL; |
} |
} |
|
|
#ifdef HAVE_IPV6 |
|
struct interface * |
struct interface * |
if_lookup_by_ipv6 (struct in6_addr *addr) |
if_lookup_by_ipv6 (struct in6_addr *addr) |
{ |
{ |
Line 532 if_get_ipv6_local (struct interface *ifp, struct in6_a
|
Line 534 if_get_ipv6_local (struct interface *ifp, struct in6_a
|
} |
} |
return 0; |
return 0; |
} |
} |
#endif /* HAVE_IPV6 */ |
|
|
|
|
static int |
|
if_get_ipv4_address (struct interface *ifp, struct in_addr *addr) |
|
{ |
|
struct listnode *cnode; |
|
struct connected *connected; |
|
struct prefix *cp; |
|
|
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) |
|
{ |
|
cp = connected->address; |
|
if ((cp->family == AF_INET) && !ipv4_martian(&(cp->u.prefix4))) |
|
{ |
|
*addr = cp->u.prefix4; |
|
return 1; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
int |
int |
bgp_nexthop_set (union sockunion *local, union sockunion *remote, |
bgp_nexthop_set (union sockunion *local, union sockunion *remote, |
struct bgp_nexthop *nexthop, struct peer *peer) |
struct bgp_nexthop *nexthop, struct peer *peer) |
Line 553 bgp_nexthop_set (union sockunion *local, union sockuni
|
Line 573 bgp_nexthop_set (union sockunion *local, union sockuni
|
nexthop->v4 = local->sin.sin_addr; |
nexthop->v4 = local->sin.sin_addr; |
ifp = if_lookup_by_ipv4 (&local->sin.sin_addr); |
ifp = if_lookup_by_ipv4 (&local->sin.sin_addr); |
} |
} |
#ifdef HAVE_IPV6 |
|
if (local->sa.sa_family == AF_INET6) |
if (local->sa.sa_family == AF_INET6) |
{ |
{ |
if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr)) |
if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr)) |
{ |
{ |
if (peer->ifname) |
if (peer->ifname) |
ifp = if_lookup_by_index (if_nametoindex (peer->ifname)); | ifp = if_lookup_by_name (peer->ifname); |
} |
} |
else |
else |
ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr); |
ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr); |
} |
} |
#endif /* HAVE_IPV6 */ |
|
|
|
if (!ifp) |
if (!ifp) |
return -1; |
return -1; |
Line 574 bgp_nexthop_set (union sockunion *local, union sockuni
|
Line 592 bgp_nexthop_set (union sockunion *local, union sockuni
|
/* IPv4 connection. */ |
/* IPv4 connection. */ |
if (local->sa.sa_family == AF_INET) |
if (local->sa.sa_family == AF_INET) |
{ |
{ |
#ifdef HAVE_IPV6 |
|
/* IPv6 nexthop*/ |
/* IPv6 nexthop*/ |
ret = if_get_ipv6_global (ifp, &nexthop->v6_global); |
ret = if_get_ipv6_global (ifp, &nexthop->v6_global); |
|
|
Line 583 bgp_nexthop_set (union sockunion *local, union sockuni
|
Line 600 bgp_nexthop_set (union sockunion *local, union sockuni
|
if_get_ipv6_local (ifp, &nexthop->v6_global); |
if_get_ipv6_local (ifp, &nexthop->v6_global); |
else |
else |
if_get_ipv6_local (ifp, &nexthop->v6_local); |
if_get_ipv6_local (ifp, &nexthop->v6_local); |
#endif /* HAVE_IPV6 */ |
|
} |
} |
|
|
#ifdef HAVE_IPV6 |
|
/* IPv6 connection. */ |
/* IPv6 connection. */ |
if (local->sa.sa_family == AF_INET6) |
if (local->sa.sa_family == AF_INET6) |
{ |
{ |
struct interface *direct = NULL; |
struct interface *direct = NULL; |
|
|
/* IPv4 nexthop. I don't care about it. */ | /* IPv4 nexthop. */ |
if (peer->local_id.s_addr) | ret = if_get_ipv4_address(ifp, &nexthop->v4); |
| if (!ret && peer->local_id.s_addr) |
nexthop->v4 = peer->local_id; |
nexthop->v4 = peer->local_id; |
|
|
/* Global address*/ |
/* Global address*/ |
Line 642 bgp_nexthop_set (union sockunion *local, union sockuni
|
Line 658 bgp_nexthop_set (union sockunion *local, union sockuni
|
SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0); |
SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0); |
} |
} |
#endif /* KAME */ |
#endif /* KAME */ |
#endif /* HAVE_IPV6 */ |
|
return ret; |
return ret; |
} |
} |
|
|
Line 658 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
Line 673 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
if (zclient->sock < 0) |
if (zclient->sock < 0) |
return; |
return; |
|
|
if (! zclient->redist[ZEBRA_ROUTE_BGP]) | if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT)) |
return; |
return; |
|
|
flags = 0; |
flags = 0; |
Line 694 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
Line 709 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
struct zapi_ipv4 api; |
struct zapi_ipv4 api; |
struct in_addr *nexthop; |
struct in_addr *nexthop; |
|
|
|
api.vrf_id = VRF_DEFAULT; |
api.flags = flags; |
api.flags = flags; |
nexthop = &info->attr->nexthop; |
nexthop = &info->attr->nexthop; |
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); |
stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); |
Line 741 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
Line 757 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, |
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, |
(struct prefix_ipv4 *) p, &api); |
(struct prefix_ipv4 *) p, &api); |
} |
} |
#ifdef HAVE_IPV6 | |
/* We have to think about a IPv6 link-local address curse. */ |
/* We have to think about a IPv6 link-local address curse. */ |
if (p->family == AF_INET6) |
if (p->family == AF_INET6) |
{ |
{ |
unsigned int ifindex; | ifindex_t ifindex; |
struct in6_addr *nexthop; |
struct in6_addr *nexthop; |
struct zapi_ipv6 api; |
struct zapi_ipv6 api; |
|
|
Line 778 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
Line 794 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) |
if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) |
{ |
{ |
if (info->peer->ifname) |
if (info->peer->ifname) |
ifindex = if_nametoindex (info->peer->ifname); | ifindex = ifname2ifindex (info->peer->ifname); |
else if (info->peer->nexthop.ifp) |
else if (info->peer->nexthop.ifp) |
ifindex = info->peer->nexthop.ifp->ifindex; |
ifindex = info->peer->nexthop.ifp->ifindex; |
} |
} |
|
|
/* Make Zebra API structure. */ |
/* Make Zebra API structure. */ |
|
api.vrf_id = VRF_DEFAULT; |
api.flags = flags; |
api.flags = flags; |
api.type = ZEBRA_ROUTE_BGP; |
api.type = ZEBRA_ROUTE_BGP; |
api.message = 0; |
api.message = 0; |
Line 810 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
Line 827 bgp_zebra_announce (struct prefix *p, struct bgp_info
|
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, |
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, |
(struct prefix_ipv6 *) p, &api); |
(struct prefix_ipv6 *) p, &api); |
} |
} |
#endif /* HAVE_IPV6 */ |
|
} |
} |
|
|
void |
void |
Line 822 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
Line 838 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
if (zclient->sock < 0) |
if (zclient->sock < 0) |
return; |
return; |
|
|
if (! zclient->redist[ZEBRA_ROUTE_BGP]) | if (! vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_BGP], VRF_DEFAULT)) |
return; |
return; |
|
|
peer = info->peer; |
peer = info->peer; |
Line 841 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
Line 857 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
if (p->family == AF_INET) |
if (p->family == AF_INET) |
{ |
{ |
struct zapi_ipv4 api; |
struct zapi_ipv4 api; |
struct in_addr *nexthop; |
|
|
|
|
api.vrf_id = VRF_DEFAULT; |
api.flags = flags; |
api.flags = flags; |
nexthop = &info->attr->nexthop; |
|
|
|
api.type = ZEBRA_ROUTE_BGP; |
api.type = ZEBRA_ROUTE_BGP; |
api.message = 0; |
api.message = 0; |
api.safi = safi; |
api.safi = safi; |
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); | api.nexthop_num = 0; |
api.nexthop_num = 1; | |
api.nexthop = &nexthop; | |
api.ifindex_num = 0; |
api.ifindex_num = 0; |
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); |
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); |
api.metric = info->attr->med; |
api.metric = info->attr->med; |
Line 859 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
Line 872 bgp_zebra_withdraw (struct prefix *p, struct bgp_info
|
if (BGP_DEBUG(zebra, ZEBRA)) |
if (BGP_DEBUG(zebra, ZEBRA)) |
{ |
{ |
char buf[2][INET_ADDRSTRLEN]; |
char buf[2][INET_ADDRSTRLEN]; |
zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u", | zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u", |
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), |
inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), |
p->prefixlen, |
p->prefixlen, |
inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])), |
|
api.metric); |
api.metric); |
} |
} |
|
|
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, |
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, |
(struct prefix_ipv4 *) p, &api); |
(struct prefix_ipv4 *) p, &api); |
} |
} |
#ifdef HAVE_IPV6 | |
/* We have to think about a IPv6 link-local address curse. */ |
/* We have to think about a IPv6 link-local address curse. */ |
if (p->family == AF_INET6) |
if (p->family == AF_INET6) |
{ |
{ |
struct zapi_ipv6 api; |
struct zapi_ipv6 api; |
unsigned int ifindex; |
|
struct in6_addr *nexthop; |
|
|
|
assert (info->attr->extra); | api.vrf_id = VRF_DEFAULT; |
| |
ifindex = 0; | |
nexthop = NULL; | |
| |
/* Only global address nexthop exists. */ | |
if (info->attr->extra->mp_nexthop_len == 16) | |
nexthop = &info->attr->extra->mp_nexthop_global; | |
| |
/* If both global and link-local address present. */ | |
if (info->attr->extra->mp_nexthop_len == 32) | |
{ | |
nexthop = &info->attr->extra->mp_nexthop_local; | |
if (info->peer->nexthop.ifp) | |
ifindex = info->peer->nexthop.ifp->ifindex; | |
} | |
| |
if (nexthop == NULL) | |
return; | |
| |
if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) | |
if (info->peer->ifname) | |
ifindex = if_nametoindex (info->peer->ifname); | |
| |
api.flags = flags; |
api.flags = flags; |
api.type = ZEBRA_ROUTE_BGP; |
api.type = ZEBRA_ROUTE_BGP; |
api.message = 0; |
api.message = 0; |
api.safi = safi; |
api.safi = safi; |
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); | api.nexthop_num = 0; |
api.nexthop_num = 1; | api.ifindex_num = 0; |
api.nexthop = &nexthop; | |
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); | |
api.ifindex_num = 1; | |
api.ifindex = &ifindex; | |
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); |
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); |
api.metric = info->attr->med; |
api.metric = info->attr->med; |
|
|
if (BGP_DEBUG(zebra, ZEBRA)) |
if (BGP_DEBUG(zebra, ZEBRA)) |
{ |
{ |
char buf[2][INET6_ADDRSTRLEN]; |
char buf[2][INET6_ADDRSTRLEN]; |
zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u", | zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u", |
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), |
inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), |
p->prefixlen, |
p->prefixlen, |
inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), |
|
api.metric); |
api.metric); |
} |
} |
|
|
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, |
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, |
(struct prefix_ipv6 *) p, &api); |
(struct prefix_ipv6 *) p, &api); |
} |
} |
#endif /* HAVE_IPV6 */ |
|
} |
} |
| |
/* Other routes redistribution into BGP. */ |
/* Other routes redistribution into BGP. */ |
int |
int |
bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type) |
bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type) |
Line 938 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int
|
Line 919 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int
|
bgp->redist[afi][type] = 1; |
bgp->redist[afi][type] = 1; |
|
|
/* Return if already redistribute flag is set. */ |
/* Return if already redistribute flag is set. */ |
if (zclient->redist[type]) | if (vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT)) |
return CMD_WARNING; |
return CMD_WARNING; |
|
|
zclient->redist[type] = 1; | vrf_bitmap_set (zclient->redist[type], VRF_DEFAULT); |
|
|
/* Return if zebra connection is not established. */ |
/* Return if zebra connection is not established. */ |
if (zclient->sock < 0) |
if (zclient->sock < 0) |
Line 951 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int
|
Line 932 bgp_redistribute_set (struct bgp *bgp, afi_t afi, int
|
zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type)); |
zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type)); |
|
|
/* Send distribute add message to zebra. */ |
/* Send distribute add message to zebra. */ |
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type); | zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT); |
|
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
Line 1006 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
|
Line 987 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
|
bgp->redist_metric[afi][type] = 0; |
bgp->redist_metric[afi][type] = 0; |
|
|
/* Return if zebra connection is disabled. */ |
/* Return if zebra connection is disabled. */ |
if (! zclient->redist[type]) | if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT)) |
return CMD_WARNING; |
return CMD_WARNING; |
zclient->redist[type] = 0; | vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT); |
|
|
if (bgp->redist[AFI_IP][type] == 0 |
if (bgp->redist[AFI_IP][type] == 0 |
&& bgp->redist[AFI_IP6][type] == 0 |
&& bgp->redist[AFI_IP6][type] == 0 |
Line 1018 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
|
Line 999 bgp_redistribute_unset (struct bgp *bgp, afi_t afi, in
|
if (BGP_DEBUG(zebra, ZEBRA)) |
if (BGP_DEBUG(zebra, ZEBRA)) |
zlog_debug("Zebra send: redistribute delete %s", |
zlog_debug("Zebra send: redistribute delete %s", |
zebra_route_string(type)); |
zebra_route_string(type)); |
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type); | zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, |
| VRF_DEFAULT); |
} |
} |
|
|
/* Withdraw redistributed routes from current BGP's routing table. */ |
/* Withdraw redistributed routes from current BGP's routing table. */ |
Line 1055 bgp_redistribute_metric_unset (struct bgp *bgp, afi_t
|
Line 1037 bgp_redistribute_metric_unset (struct bgp *bgp, afi_t
|
|
|
return 1; |
return 1; |
} |
} |
| |
void |
void |
bgp_zclient_reset (void) |
bgp_zclient_reset (void) |
{ |
{ |
zclient_reset (zclient); |
zclient_reset (zclient); |
} |
} |
|
|
|
static void |
|
bgp_zebra_connected (struct zclient *zclient) |
|
{ |
|
zclient_send_requests (zclient, VRF_DEFAULT); |
|
} |
|
|
void |
void |
bgp_zebra_init (void) | bgp_zebra_init (struct thread_master *master) |
{ |
{ |
/* Set default values. */ |
/* Set default values. */ |
zclient = zclient_new (); | zclient = zclient_new (master); |
zclient_init (zclient, ZEBRA_ROUTE_BGP); |
zclient_init (zclient, ZEBRA_ROUTE_BGP); |
|
zclient->zebra_connected = bgp_zebra_connected; |
zclient->router_id_update = bgp_router_id_update; |
zclient->router_id_update = bgp_router_id_update; |
zclient->interface_add = bgp_interface_add; |
zclient->interface_add = bgp_interface_add; |
zclient->interface_delete = bgp_interface_delete; |
zclient->interface_delete = bgp_interface_delete; |
Line 1077 bgp_zebra_init (void)
|
Line 1066 bgp_zebra_init (void)
|
zclient->ipv4_route_delete = zebra_read_ipv4; |
zclient->ipv4_route_delete = zebra_read_ipv4; |
zclient->interface_up = bgp_interface_up; |
zclient->interface_up = bgp_interface_up; |
zclient->interface_down = bgp_interface_down; |
zclient->interface_down = bgp_interface_down; |
#ifdef HAVE_IPV6 |
|
zclient->ipv6_route_add = zebra_read_ipv6; |
zclient->ipv6_route_add = zebra_read_ipv6; |
zclient->ipv6_route_delete = zebra_read_ipv6; |
zclient->ipv6_route_delete = zebra_read_ipv6; |
#endif /* HAVE_IPV6 */ |
|
|
|
/* Interface related init. */ |
|
if_init (); |
|
|
|
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE); |
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE); |
|
} |
|
|
|
void |
|
bgp_zebra_destroy(void) |
|
{ |
|
if (zclient == NULL) |
|
return; |
|
zclient_stop(zclient); |
|
zclient_free(zclient); |
|
zclient = NULL; |
} |
} |