diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index f1ce97eff9..a3ad3cc9dc 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -541,7 +541,13 @@ bgp_getsockname (struct peer *peer) peer->su_remote = sockunion_getpeername (peer->fd); if (!peer->su_remote) return -1; - bgp_nexthop_set (peer->su_local, peer->su_remote, &peer->nexthop, peer); + if (bgp_nexthop_set (peer->su_local, peer->su_remote, + &peer->nexthop, peer)) + { + zlog_err ("%s: nexthop_set failed, resetting connection - intf %p", + peer->host, peer->nexthop.ifp); + return -1; + } return 0; } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index ddc03716e3..6bc0ef5c06 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1127,6 +1127,31 @@ bgp_open_receive (struct peer *peer, bgp_size_t size) return (ret); } + /* Verify valid local address present based on negotiated address-families. */ + if (peer->afc_nego[AFI_IP][SAFI_UNICAST] || + peer->afc_nego[AFI_IP][SAFI_MULTICAST] || + peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]) + { + if (!peer->nexthop.v4.s_addr) + { + zlog_err ("%s: No local IPv4 addr resetting connection, fd %d", + peer->host, peer->fd); + bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); + return -1; + } + } + if (peer->afc_nego[AFI_IP6][SAFI_UNICAST] || + peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) + { + if (IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_global)) + { + zlog_err ("%s: No local IPv6 addr resetting connection, fd %d", + peer->host, peer->fd); + bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC); + return -1; + } + } + if ((ret = bgp_event_update(peer, Receive_OPEN_message)) < 0) { zlog_err("%s: BGP event update failed for peer: %s", __FUNCTION__, diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f96fbfa6d9..1a27b195cb 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -843,7 +843,7 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote, nexthop->ifp = ifp; - /* IPv4 connection. */ + /* IPv4 connection, fetch and store IPv6 local address(es) if any. */ if (local->sa.sa_family == AF_INET) { #ifdef HAVE_IPV6 @@ -859,7 +859,7 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote, } #ifdef HAVE_IPV6 - /* IPv6 connection. */ + /* IPv6 connection, fetch and store IPv4 local address if any. */ if (local->sa.sa_family == AF_INET6) { struct interface *direct = NULL; @@ -921,7 +921,9 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote, } #endif /* KAME */ #endif /* HAVE_IPV6 */ - return ret; + + /* If we have identified the local interface, there is no error for now. */ + return 0; } static struct in6_addr *