/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  unsigned int ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  set_nonblocking (peer->fd);

  /* Set socket send buffer size */
  bgp_update_sock_send_buffer_size(peer->fd);

  bgp_set_socket_ttl (peer, peer->fd);

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);
  
#ifdef IPTOS_PREC_INTERNETCONTROL
  if (bgpd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs", __func__);
  if (sockunion_family (&peer->su) == AF_INET)
    setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
# ifdef HAVE_IPV6
  else if (sockunion_family (&peer->su) == AF_INET6)
    setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
# endif
  if (bgpd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs", __func__);
#endif

  if (peer->password)
    bgp_md5_set_connect (peer->fd, &peer->su, peer->password);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

#ifdef HAVE_IPV6
  if (peer->ifname)
    ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */

  if (BGP_DEBUG (events, EVENTS))
    plog_debug (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
예제 #2
0
/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  unsigned int ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  /* If we can get socket for the peer, adjest TTL and make connection. */
  if (peer->sort == BGP_PEER_EBGP) {
    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
    if (peer->gtsm_hops)
      sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops);
  }

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);
  
#ifdef IPTOS_PREC_INTERNETCONTROL
  if (bgpd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs", __func__);
  if (sockunion_family (&peer->su) == AF_INET)
    setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
# ifdef HAVE_IPV6
  else if (sockunion_family (&peer->su) == AF_INET6)
    setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
# endif
  if (bgpd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs", __func__);
#endif

  if (peer->password)
    bgp_md5_set_connect (peer->fd, &peer->su, peer->password);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

#ifdef HAVE_IPV6
  if (peer->ifname)
    ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */

  if (BGP_DEBUG (events, EVENTS))
    plog_debug (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
예제 #3
0
/* BGP try to connect to the peer.  */
int
bgp_connect (struct peer *peer)
{
  unsigned int ifindex = 0;

  /* Make socket for the peer. */
  peer->fd = sockunion_socket (&peer->su);
  if (peer->fd < 0)
    return -1;

  /* If we can get socket for the peer, adjest TTL and make connection. */
  if (peer_sort (peer) == BGP_PEER_EBGP)
    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);

  sockopt_reuseaddr (peer->fd);
  sockopt_reuseport (peer->fd);

  /* Bind socket. */
  bgp_bind (peer);

  /* Update source bind. */
  bgp_update_source (peer);

#ifdef HAVE_IPV6
  if (peer->ifname)
    ifindex = if_nametoindex (peer->ifname);
#endif /* HAVE_IPV6 */

  if (BGP_DEBUG (events, EVENTS))
    plog_info (peer->log, "%s [Event] Connect start to %s fd %d",
	       peer->host, peer->host, peer->fd);

#ifdef HAVE_TCP_SIGNATURE
  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
    bgp_tcpsig_set (peer->fd, peer);
#endif /* HAVE_TCP_SIGNATURE */

  /* Connect to the remote peer. */
  return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
}
예제 #4
0
파일: bgp_network.c 프로젝트: ton31337/frr
/* BGP try to connect to the peer.  */
int bgp_connect(struct peer *peer)
{
	assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
	assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
	ifindex_t ifindex = 0;

	if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) {
		zlog_debug("Peer address not learnt: Returning from connect");
		return 0;
	}
	frr_elevate_privs(&bgpd_privs) {
	/* Make socket for the peer. */
		peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
						bgp_get_bound_name(peer));
	}
	if (peer->fd < 0)
		return -1;

	set_nonblocking(peer->fd);

	/* Set socket send buffer size */
	setsockopt_so_sendbuf(peer->fd, BGP_SOCKET_SNDBUF_SIZE);

	if (bgp_set_socket_ttl(peer, peer->fd) < 0)
		return -1;

	sockopt_reuseaddr(peer->fd);
	sockopt_reuseport(peer->fd);

#ifdef IPTOS_PREC_INTERNETCONTROL
	frr_elevate_privs(&bgpd_privs) {
		if (sockunion_family(&peer->su) == AF_INET)
			setsockopt_ipv4_tos(peer->fd,
					    IPTOS_PREC_INTERNETCONTROL);
		else if (sockunion_family(&peer->su) == AF_INET6)
			setsockopt_ipv6_tclass(peer->fd,
					       IPTOS_PREC_INTERNETCONTROL);
	}
#endif

	if (peer->password) {
		uint16_t prefixlen = peer->su.sa.sa_family == AF_INET
					     ? IPV4_MAX_PREFIXLEN
					     : IPV6_MAX_PREFIXLEN;

		bgp_md5_set_connect(peer->fd, &peer->su, prefixlen,
				    peer->password);
	}

	/* Update source bind. */
	if (bgp_update_source(peer) < 0) {
		return connect_error;
	}

	if (peer->conf_if || peer->ifname)
		ifindex = ifname2ifindex(peer->conf_if ? peer->conf_if
						       : peer->ifname,
					 peer->bgp->vrf_id);

	if (bgp_debug_neighbor_events(peer))
		zlog_debug("%s [Event] Connect start to %s fd %d", peer->host,
			   peer->host, peer->fd);

	/* Connect to the remote peer. */
	return sockunion_connect(peer->fd, &peer->su, htons(peer->port),
				 ifindex);
}