#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_damp.h"
+#include "bgpd/bgp_fsm.h"
#include "zebra/rib.h"
#include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
/* Route table for next-hop lookup cache. */
struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
-static struct bgp_table *cache1_table[AFI_MAX];
/* Route table for connected route. */
static struct bgp_table *bgp_connected_table[AFI_MAX];
+/* Route table for import-check */
+struct bgp_table *bgp_import_check_table[AFI_MAX];
char *
bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
}
struct bgp_nexthop_cache *
-bnc_new ()
+bnc_new (void)
{
struct bgp_nexthop_cache *bnc;
XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
}
-/* If nexthop exists on connected network return 1. */
-int
-bgp_nexthop_onlink (afi_t afi, struct attr *attr)
-{
- struct bgp_node *rn;
-
- /* Lookup the address is onlink or not. */
- if (afi == AFI_IP)
- {
- rn = bgp_node_match_ipv4 (bgp_connected_table[AFI_IP], &attr->nexthop);
- if (rn)
- {
- bgp_unlock_node (rn);
- return 1;
- }
- }
-#ifdef HAVE_IPV6
- else if (afi == AFI_IP6)
- {
- if (attr->extra->mp_nexthop_len == 32)
- return 1;
- else if (attr->extra->mp_nexthop_len == 16)
- {
- if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
- return 1;
-
- rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
- &attr->extra->mp_nexthop_global);
- if (rn)
- {
- bgp_unlock_node (rn);
- return 1;
- }
- }
- }
-#endif /* HAVE_IPV6 */
- return 0;
-}
-
/* Reset and free all BGP nexthop cache. */
static void
bgp_nexthop_cache_reset (struct bgp_table *table)
static void *
bgp_address_hash_alloc (void *p)
{
- struct in_addr *val = p;
+ const struct in_addr *val = (const struct in_addr *)p;
struct bgp_addr *addr;
addr = XMALLOC (MTYPE_BGP_ADDR, sizeof (struct bgp_addr));
{
struct prefix p;
struct prefix *addr;
- struct interface *ifp;
struct bgp_node *rn;
struct bgp_connected_ref *bc;
-
- ifp = ifc->ifp;
-
- if (! ifp)
- return;
-
- if (if_is_loopback (ifp))
- return;
+ struct listnode *node, *nnode, *mnode;
+ struct bgp *bgp;
+ struct peer *peer;
addr = ifc->address;
+ p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
- PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
bc->refcnt = 1;
rn->info = bc;
}
+
+ for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
+ {
+ for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+ {
+ if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) &&
+ !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
+ {
+ if (peer_active(peer))
+ BGP_EVENT_ADD (peer, BGP_Stop);
+ BGP_EVENT_ADD (peer, BGP_Start);
+ }
+ }
+ }
}
#ifdef HAVE_IPV6
else if (addr->family == AF_INET6)
{
- PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
{
struct prefix p;
struct prefix *addr;
- struct interface *ifp;
struct bgp_node *rn;
struct bgp_connected_ref *bc;
- ifp = ifc->ifp;
-
- if (if_is_loopback (ifp))
- return;
-
addr = ifc->address;
+ p = *(CONNECTED_PREFIX(ifc));
if (addr->family == AF_INET)
{
- PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
#ifdef HAVE_IPV6
else if (addr->family == AF_INET6)
{
- PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
return 0;
}
-
int
bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
{
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
- char buf[INET6_ADDRSTRLEN];
+ char buf[PREFIX2STR_BUFFER];
struct nexthop *nexthop;
time_t tbuf;
- u_char i;
+ afi_t afi;
vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
- for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP]); rn; rn = bgp_route_next (rn))
- if ((bnc = rn->info) != NULL)
- {
- if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
+ for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
+ {
+ for (rn = bgp_table_top (bgp_nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
{
- vty_out (vty, " %s valid [IGP metric %d], #paths %d%s",
- inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN),
- bnc->metric, bnc->path_count, VTY_NEWLINE);
- if (detail)
- for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
- switch (nexthop->type)
+ if ((bnc = rn->info) != NULL)
+ {
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
{
- case NEXTHOP_TYPE_IPV4:
- vty_out (vty, " gate %s%s",
- inet_ntop (AF_INET, &nexthop->gate.ipv4, buf,
- INET6_ADDRSTRLEN), VTY_NEWLINE);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " if %s%s",
- ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
- break;
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out (vty, " gate %s, if %s%s",
- inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
- INET6_ADDRSTRLEN),
- ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
- break;
- default:
- vty_out (vty, " invalid nexthop type %u%s",
- nexthop->type, VTY_NEWLINE);
+ vty_out (vty, " %s valid [IGP metric %d], #paths %d%s",
+ inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
+ bnc->metric, bnc->path_count, VTY_NEWLINE);
+ if (detail)
+ for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
+ switch (nexthop->type)
+ {
+ case NEXTHOP_TYPE_IPV6:
+ vty_out (vty, " gate %s%s",
+ inet_ntop (AF_INET6, &nexthop->gate.ipv6,
+ buf, sizeof (buf)), VTY_NEWLINE);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ vty_out(vty, " gate %s, if %s%s",
+ inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
+ sizeof (buf)),
+ ifindex2ifname(nexthop->ifindex),
+ VTY_NEWLINE);
+ break;
+ case NEXTHOP_TYPE_IPV4:
+ vty_out (vty, " gate %s%s",
+ inet_ntop (AF_INET, &nexthop->gate.ipv4, buf,
+ sizeof (buf)), VTY_NEWLINE);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ vty_out (vty, " if %s%s",
+ ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
+ break;
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ vty_out (vty, " gate %s, if %s%s",
+ inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
+ sizeof (buf)),
+ ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
+ break;
+ default:
+ vty_out (vty, " invalid nexthop type %u%s",
+ nexthop->type, VTY_NEWLINE);
+ }
+ }
+ else
+ {
+ vty_out (vty, " %s invalid%s",
+ inet_ntop (rn->p.family, &rn->p.u.prefix,
+ buf, sizeof (buf)), VTY_NEWLINE);
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
+ vty_out (vty, " Must be Connected%s", VTY_NEWLINE);
}
- }
- else
- vty_out (vty, " %s invalid%s",
- inet_ntop (AF_INET, &rn->p.u.prefix4, buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
-#ifdef HAVE_CLOCK_MONOTONIC
- tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
- vty_out (vty, " Last update: %s", ctime(&tbuf));
-#else
- vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
-#endif /* HAVE_CLOCK_MONOTONIC */
-
- vty_out(vty, "%s", VTY_NEWLINE);
- }
-
-#ifdef HAVE_IPV6
- {
- for (rn = bgp_table_top (bgp_nexthop_cache_table[AFI_IP6]);
- rn;
- rn = bgp_route_next (rn))
- if ((bnc = rn->info) != NULL)
- {
- if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
- {
- vty_out (vty, " %s valid [IGP metric %d]%s",
- inet_ntop (AF_INET6, &rn->p.u.prefix6, buf,
- INET6_ADDRSTRLEN),
- bnc->metric, VTY_NEWLINE);
- if (detail)
- for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV6:
- vty_out (vty, " gate %s%s",
- inet_ntop (AF_INET6, &nexthop->gate.ipv6,
- buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
- break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out(vty, " gate %s, if %s%s",
- inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
- INET6_ADDRSTRLEN),
- ifindex2ifname(nexthop->ifindex),
- VTY_NEWLINE);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- vty_out (vty, " ifidx %u%s", nexthop->ifindex,
- VTY_NEWLINE);
- break;
- default:
- vty_out (vty, " invalid nexthop type %u%s",
- nexthop->type, VTY_NEWLINE);
- }
- }
- else
- vty_out (vty, " %s invalid%s",
- inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, INET6_ADDRSTRLEN),
- VTY_NEWLINE);
#ifdef HAVE_CLOCK_MONOTONIC
- tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
- vty_out (vty, " Last update: %s", ctime(&tbuf));
+ tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
+ vty_out (vty, " Last update: %s", ctime(&tbuf));
#else
- vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
+ vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
#endif /* HAVE_CLOCK_MONOTONIC */
-
- vty_out(vty, "%s", VTY_NEWLINE);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
}
- }
-#endif /* HAVE_IPV6 */
+ }
return CMD_SUCCESS;
}
void
bgp_scan_init (void)
{
- cache1_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
- bgp_nexthop_cache_table[AFI_IP] = cache1_table[AFI_IP];
-
+ bgp_nexthop_cache_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
bgp_connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
+ bgp_import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
#ifdef HAVE_IPV6
- cache1_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
- bgp_nexthop_cache_table[AFI_IP6] = cache1_table[AFI_IP6];
+ bgp_nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
bgp_connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
+ bgp_import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
#endif /* HAVE_IPV6 */
}
void
-bgp_scan_vty_init()
+bgp_scan_vty_init (void)
{
install_element (ENABLE_NODE, &show_ip_bgp_nexthop_cmd);
install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
/* Only the current one needs to be reset. */
bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP]);
- bgp_table_unlock (cache1_table[AFI_IP]);
- cache1_table[AFI_IP] = NULL;
+ bgp_table_unlock (bgp_nexthop_cache_table[AFI_IP]);
+ bgp_nexthop_cache_table[AFI_IP] = NULL;
bgp_table_unlock (bgp_connected_table[AFI_IP]);
bgp_connected_table[AFI_IP] = NULL;
+ bgp_table_unlock (bgp_import_check_table[AFI_IP]);
+ bgp_import_check_table[AFI_IP] = NULL;
+
#ifdef HAVE_IPV6
/* Only the current one needs to be reset. */
bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP6]);
- bgp_table_unlock (cache1_table[AFI_IP6]);
- cache1_table[AFI_IP6] = NULL;
+ bgp_table_unlock (bgp_nexthop_cache_table[AFI_IP6]);
+ bgp_nexthop_cache_table[AFI_IP6] = NULL;
bgp_table_unlock (bgp_connected_table[AFI_IP6]);
bgp_connected_table[AFI_IP6] = NULL;
+
+ bgp_table_unlock (bgp_import_check_table[AFI_IP6]);
+ bgp_import_check_table[AFI_IP6] = NULL;
#endif /* HAVE_IPV6 */
}