Exemplo n.º 1
0
Arquivo: bgp.c Projeto: deepfield/bird
/**
 * bgp_incoming_connection - handle an incoming connection
 * @sk: TCP socket
 * @dummy: unused
 *
 * This function serves as a socket hook for accepting of new BGP
 * connections. It searches a BGP instance corresponding to the peer
 * which has connected and if such an instance exists, it creates a
 * &bgp_conn structure, attaches it to the instance and either sends
 * an Open message or (if there already is an active connection) it
 * closes the new connection by sending a Notification message.
 */
static int
bgp_incoming_connection(sock *sk, int dummy UNUSED)
{
  struct proto_config *pc;

  DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
  WALK_LIST(pc, config->protos)
    if (pc->protocol == &proto_bgp && pc->proto)
      {
	struct bgp_proto *p = (struct bgp_proto *) pc->proto;
	if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
	    (!ipa_has_link_scope(sk->daddr) || (p->cf->iface == sk->iface)))
	  {
	    /* We are in proper state and there is no other incoming connection */
	    int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
	      (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);

	    if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
	    {
	      bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
	      bgp_handle_graceful_restart(p);
	      bgp_conn_enter_idle_state(p->conn);
	      acc = 1;
	    }

	    BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
		      sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL,
		      sk->dport, acc ? "accepted" : "rejected");

	    if (!acc)
	      goto reject;

	    int hops = p->cf->multihop ? : 1;

	    if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
	      goto err;

	    if (p->cf->ttl_security)
	      if (sk_set_min_ttl(sk, 256 - hops) < 0)
		goto err;

	    bgp_setup_conn(p, &p->incoming_conn);
	    bgp_setup_sk(&p->incoming_conn, sk);
	    bgp_send_open(&p->incoming_conn);
	    return 0;

	  err:
	    sk_log_error(sk, p->p.name);
	    log(L_ERR "%s: Incoming connection aborted", p->p.name);
	    rfree(sk);
	    return 0;
	  }
      }
Exemplo n.º 2
0
Arquivo: bgp.c Projeto: rogerhu/dd-wrt
/**
 * bgp_connect - initiate an outgoing connection
 * @p: BGP instance
 *
 * The bgp_connect() function creates a new &bgp_conn and initiates
 * a TCP connection to the peer. The rest of connection setup is governed
 * by the BGP state machine as described in the standard.
 */
static void
bgp_connect(struct bgp_proto *p)	/* Enter Connect state and start establishing connection */
{
    sock *s;
    struct bgp_conn *conn = &p->outgoing_conn;
    int hops = p->cf->multihop ? : 1;

    DBG("BGP: Connecting\n");
    s = sk_new(p->p.pool);
    s->type = SK_TCP_ACTIVE;
    s->saddr = p->source_addr;
    s->daddr = p->cf->remote_ip;
    s->iface = p->neigh ? p->neigh->iface : NULL;
    s->dport = BGP_PORT;
    s->ttl = p->cf->ttl_security ? 255 : hops;
    s->rbsize = BGP_RX_BUFFER_SIZE;
    s->tbsize = BGP_TX_BUFFER_SIZE;
    s->tos = IP_PREC_INTERNET_CONTROL;
    s->password = p->cf->password;
    s->tx_hook = bgp_connected;
    BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J", s->daddr, p->cf->iface,
              s->saddr, ipa_has_link_scope(s->saddr) ? s->iface : NULL);
    bgp_setup_conn(p, conn);
    bgp_setup_sk(conn, s);
    bgp_conn_set_state(conn, BS_CONNECT);

    if (sk_open(s) < 0)
    {
        bgp_sock_err(s, 0);
        return;
    }

    /* Set minimal receive TTL if needed */
    if (p->cf->ttl_security)
    {
        DBG("Setting minimum received TTL to %d", 256 - hops);
        if (sk_set_min_ttl(s, 256 - hops) < 0)
        {
            log(L_ERR "TTL security configuration failed, closing session");
            bgp_sock_err(s, 0);
            return;
        }
    }

    DBG("BGP: Waiting for connect success\n");
    bgp_start_timer(conn->connect_retry_timer, p->cf->connect_retry_time);
}
Exemplo n.º 3
0
Arquivo: bgp.c Projeto: rogerhu/dd-wrt
/**
 * bgp_incoming_connection - handle an incoming connection
 * @sk: TCP socket
 * @dummy: unused
 *
 * This function serves as a socket hook for accepting of new BGP
 * connections. It searches a BGP instance corresponding to the peer
 * which has connected and if such an instance exists, it creates a
 * &bgp_conn structure, attaches it to the instance and either sends
 * an Open message or (if there already is an active connection) it
 * closes the new connection by sending a Notification message.
 */
static int
bgp_incoming_connection(sock *sk, int dummy UNUSED)
{
    struct proto_config *pc;

    DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
    WALK_LIST(pc, config->protos)
    if (pc->protocol == &proto_bgp && pc->proto)
    {
        struct bgp_proto *p = (struct bgp_proto *) pc->proto;
        if (ipa_equal(p->cf->remote_ip, sk->daddr) &&
                (!ipa_has_link_scope(sk->daddr) || (p->cf->iface == sk->iface)))
        {
            /* We are in proper state and there is no other incoming connection */
            int acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
                      (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);

            BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
                      sk->daddr, ipa_has_link_scope(sk->daddr) ? sk->iface : NULL,
                      sk->dport, acc ? "accepted" : "rejected");

            if (!acc)
                goto err;

            int hops = p->cf->multihop ? : 1;
            if (p->cf->ttl_security)
            {
                /* TTL security support */
                if ((sk_set_ttl(sk, 255) < 0) ||
                        (sk_set_min_ttl(sk, 256 - hops) < 0))
                {
                    log(L_ERR "TTL security configuration failed, closing session");
                    goto err;
                }
            }
            else
                sk_set_ttl(sk, hops);

            bgp_setup_conn(p, &p->incoming_conn);
            bgp_setup_sk(&p->incoming_conn, sk);
            bgp_send_open(&p->incoming_conn);
            return 0;
        }
    }
Exemplo n.º 4
0
/**
 * bgp_connect - initiate an outgoing connection
 * @p: BGP instance
 *
 * The bgp_connect() function creates a new &bgp_conn and initiates
 * a TCP connection to the peer. The rest of connection setup is governed
 * by the BGP state machine as described in the standard.
 */
static void
bgp_connect(struct bgp_proto *p)	/* Enter Connect state and start establishing connection */
{
  sock *s;
  struct bgp_conn *conn = &p->outgoing_conn;
  int hops = p->cf->multihop ? : 1;

  DBG("BGP: Connecting\n");
  s = sk_new(p->p.pool);
  s->type = SK_TCP_ACTIVE;
  s->saddr = p->source_addr;
  s->daddr = p->cf->remote_ip;
  s->dport = p->cf->remote_port;
  s->iface = p->neigh ? p->neigh->iface : NULL;
  s->ttl = p->cf->ttl_security ? 255 : hops;
  s->rbsize = p->cf->enable_extended_messages ? BGP_RX_BUFFER_EXT_SIZE : BGP_RX_BUFFER_SIZE;
  s->tbsize = p->cf->enable_extended_messages ? BGP_TX_BUFFER_EXT_SIZE : BGP_TX_BUFFER_SIZE;
  s->tos = IP_PREC_INTERNET_CONTROL;
  s->password = p->cf->password;
  s->tx_hook = bgp_connected;
  BGP_TRACE(D_EVENTS, "Connecting to %I%J from local address %I%J", s->daddr, p->cf->iface,
	    s->saddr, ipa_is_link_local(s->saddr) ? s->iface : NULL);
  bgp_setup_conn(p, conn);
  bgp_setup_sk(conn, s);
  bgp_conn_set_state(conn, BS_CONNECT);

  if (sk_open(s) < 0)
    goto err;

  /* Set minimal receive TTL if needed */
  if (p->cf->ttl_security)
    if (sk_set_min_ttl(s, 256 - hops) < 0)
      goto err;

  DBG("BGP: Waiting for connect success\n");
  bgp_start_timer(conn->connect_retry_timer, p->cf->connect_retry_time);
  return;

 err:
  sk_log_error(s, p->p.name);
  bgp_sock_err(s, 0);
  return;
}
Exemplo n.º 5
0
/**
 * bgp_incoming_connection - handle an incoming connection
 * @sk: TCP socket
 * @dummy: unused
 *
 * This function serves as a socket hook for accepting of new BGP
 * connections. It searches a BGP instance corresponding to the peer
 * which has connected and if such an instance exists, it creates a
 * &bgp_conn structure, attaches it to the instance and either sends
 * an Open message or (if there already is an active connection) it
 * closes the new connection by sending a Notification message.
 */
static int
bgp_incoming_connection(sock *sk, int dummy UNUSED)
{
  struct bgp_proto *p;
  int acc, hops;

  DBG("BGP: Incoming connection from %I port %d\n", sk->daddr, sk->dport);
  p = bgp_find_proto(sk);
  if (!p)
    {
      log(L_WARN "BGP: Unexpected connect from unknown address %I%J (port %d)",
	  sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL, sk->dport);
      rfree(sk);
      return 0;
    }

  /* We are in proper state and there is no other incoming connection */
  acc = (p->p.proto_state == PS_START || p->p.proto_state == PS_UP) &&
    (p->start_state >= BSS_CONNECT) && (!p->incoming_conn.sk);

  if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready)
    {
      bgp_store_error(p, NULL, BE_MISC, BEM_GRACEFUL_RESTART);
      bgp_handle_graceful_restart(p);
      bgp_conn_enter_idle_state(p->conn);
      acc = 1;
    }

  BGP_TRACE(D_EVENTS, "Incoming connection from %I%J (port %d) %s",
	    sk->daddr, ipa_is_link_local(sk->daddr) ? sk->iface : NULL,
	    sk->dport, acc ? "accepted" : "rejected");

  if (!acc)
    {
      rfree(sk);
      return 0;
    }

  hops = p->cf->multihop ? : 1;

  if (sk_set_ttl(sk, p->cf->ttl_security ? 255 : hops) < 0)
    goto err;

  if (p->cf->ttl_security)
    if (sk_set_min_ttl(sk, 256 - hops) < 0)
      goto err;

  if (p->cf->enable_extended_messages)
    {
      sk->rbsize = BGP_RX_BUFFER_EXT_SIZE;
      sk->tbsize = BGP_TX_BUFFER_EXT_SIZE;
      sk_reallocate(sk);
    }

  bgp_setup_conn(p, &p->incoming_conn);
  bgp_setup_sk(&p->incoming_conn, sk);
  bgp_send_open(&p->incoming_conn);
  return 0;

err:
  sk_log_error(sk, p->p.name);
  log(L_ERR "%s: Incoming connection aborted", p->p.name);
  rfree(sk);
  return 0;
}