예제 #1
0
파일: bgp.c 프로젝트: deepfield/bird
void
bgp_conn_enter_established_state(struct bgp_conn *conn)
{
  struct bgp_proto *p = conn->bgp;
 
  BGP_TRACE(D_EVENTS, "BGP session established");
  DBG("BGP: UP!!!\n");

  /* For multi-hop BGP sessions */
  if (ipa_zero(p->source_addr))
    p->source_addr = conn->sk->saddr;

  p->conn = conn;
  p->last_error_class = 0;
  p->last_error_code = 0;
  bgp_init_bucket_table(p);
  bgp_init_prefix_table(p, 8);

  int peer_gr_ready = conn->peer_gr_aware && !(conn->peer_gr_flags & BGP_GRF_RESTART);

  if (p->p.gr_recovery && !peer_gr_ready)
    proto_graceful_restart_unlock(&p->p);

  if (p->p.gr_recovery && (p->cf->gr_mode == BGP_GR_ABLE) && peer_gr_ready)
    p->p.gr_wait = 1;

  if (p->gr_active)
    tm_stop(p->gr_timer);

  if (p->gr_active && (!conn->peer_gr_able || !(conn->peer_gr_aflags & BGP_GRF_FORWARDING)))
    bgp_graceful_restart_done(p);

  bgp_conn_set_state(conn, BS_ESTABLISHED);
  proto_notify_state(&p->p, PS_UP);
}
예제 #2
0
파일: bgp.c 프로젝트: petitecoccinelle/bird
static void
bgp_send_open(struct bgp_conn *conn)
{
  conn->start_state = conn->bgp->start_state;

  // Default values, possibly changed by receiving capabilities.
  conn->advertised_as = 0;
  conn->peer_refresh_support = 0;
  conn->peer_as4_support = 0;
  conn->peer_add_path = 0;
  conn->peer_enhanced_refresh_support = 0;
  conn->peer_gr_aware = 0;
  conn->peer_gr_able = 0;
  conn->peer_gr_time = 0;
  conn->peer_gr_flags = 0;
  conn->peer_gr_aflags = 0;
  conn->peer_ext_messages_support = 0;

  DBG("BGP: Sending open\n");
  conn->sk->rx_hook = bgp_rx;
  conn->sk->tx_hook = bgp_tx;
  tm_stop(conn->connect_retry_timer);
  bgp_schedule_packet(conn, PKT_OPEN);
  bgp_conn_set_state(conn, BS_OPENSENT);
  bgp_start_timer(conn->hold_timer, conn->bgp->cf->initial_hold_time);
}
예제 #3
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
static void
bgp_active(struct bgp_proto *p)
{
    int delay = MAX(1, p->cf->start_delay_time);
    struct bgp_conn *conn = &p->outgoing_conn;

    BGP_TRACE(D_EVENTS, "Connect delayed by %d seconds", delay);
    bgp_setup_conn(p, conn);
    bgp_conn_set_state(conn, BS_ACTIVE);
    bgp_start_timer(conn->connect_retry_timer, delay);
}
예제 #4
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
void
bgp_conn_enter_idle_state(struct bgp_conn *conn)
{
    struct bgp_proto *p = conn->bgp;
    int os = conn->state;

    bgp_close_conn(conn);
    bgp_conn_set_state(conn, BS_IDLE);
    ev_schedule(p->event);

    if (os == BS_ESTABLISHED)
        bgp_conn_leave_established_state(p);
}
예제 #5
0
파일: bgp.c 프로젝트: i3149/bird
void
bgp_conn_enter_close_state(struct bgp_conn *conn)
{
  struct bgp_proto *p = conn->bgp;
  int os = conn->state;

  bgp_conn_set_state(conn, BS_CLOSE);
  tm_stop(conn->hold_timer);
  tm_stop(conn->keepalive_timer);
  conn->sk->rx_hook = NULL;

  if (os == BS_ESTABLISHED)
    bgp_conn_leave_established_state(p);
}
예제 #6
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
static void
bgp_send_open(struct bgp_conn *conn)
{
    conn->start_state = conn->bgp->start_state;
    conn->want_as4_support = conn->bgp->cf->enable_as4 && (conn->start_state != BSS_CONNECT_NOCAP);
    conn->peer_as4_support = 0;	// Default value, possibly changed by receiving capability.
    conn->advertised_as = 0;

    DBG("BGP: Sending open\n");
    conn->sk->rx_hook = bgp_rx;
    conn->sk->tx_hook = bgp_tx;
    tm_stop(conn->connect_retry_timer);
    bgp_schedule_packet(conn, PKT_OPEN);
    bgp_conn_set_state(conn, BS_OPENSENT);
    bgp_start_timer(conn->hold_timer, conn->bgp->cf->initial_hold_time);
}
예제 #7
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
void
bgp_conn_enter_close_state(struct bgp_conn *conn)
{
    struct bgp_proto *p = conn->bgp;
    int os = conn->state;

    bgp_conn_set_state(conn, BS_CLOSE);
    tm_stop(conn->keepalive_timer);
    conn->sk->rx_hook = NULL;

    /* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */
    bgp_start_timer(conn->hold_timer, 10);

    if (os == BS_ESTABLISHED)
        bgp_conn_leave_established_state(p);
}
예제 #8
0
파일: bgp.c 프로젝트: 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);
}
예제 #9
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
void
bgp_conn_enter_established_state(struct bgp_conn *conn)
{
    struct bgp_proto *p = conn->bgp;

    BGP_TRACE(D_EVENTS, "BGP session established");
    DBG("BGP: UP!!!\n");

    /* For multi-hop BGP sessions */
    if (ipa_zero(p->source_addr))
        p->source_addr = conn->sk->saddr;

    p->conn = conn;
    p->last_error_class = 0;
    p->last_error_code = 0;
    bgp_attr_init(conn->bgp);
    bgp_conn_set_state(conn, BS_ESTABLISHED);
    proto_notify_state(&p->p, PS_UP);
}
예제 #10
0
파일: bgp.c 프로젝트: petitecoccinelle/bird
/**
 * 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;
}
예제 #11
0
파일: bgp.c 프로젝트: petitecoccinelle/bird
void
bgp_conn_enter_established_state(struct bgp_conn *conn)
{
  struct bgp_proto *p = conn->bgp;

  BGP_TRACE(D_EVENTS, "BGP session established");
  DBG("BGP: UP!!!\n");

  /* For multi-hop BGP sessions */
  if (ipa_zero(p->source_addr))
    p->source_addr = conn->sk->saddr;

  p->conn = conn;
  p->last_error_class = 0;
  p->last_error_code = 0;
  p->feed_state = BFS_NONE;
  p->load_state = BFS_NONE;
  bgp_init_bucket_table(p);
  bgp_init_prefix_table(p, 8);

  int peer_gr_ready = conn->peer_gr_aware && !(conn->peer_gr_flags & BGP_GRF_RESTART);

  if (p->p.gr_recovery && !peer_gr_ready)
    proto_graceful_restart_unlock(&p->p);

  if (p->p.gr_recovery && (p->cf->gr_mode == BGP_GR_ABLE) && peer_gr_ready)
    p->p.gr_wait = 1;

  if (p->gr_active)
    tm_stop(p->gr_timer);

  if (p->gr_active && (!conn->peer_gr_able || !(conn->peer_gr_aflags & BGP_GRF_FORWARDING)))
    bgp_graceful_restart_done(p);

  /* GR capability implies that neighbor will send End-of-RIB */
  if (conn->peer_gr_aware)
    p->load_state = BFS_LOADING;

  /* proto_notify_state() will likely call bgp_feed_begin(), setting p->feed_state */

  bgp_conn_set_state(conn, BS_ESTABLISHED);
  proto_notify_state(&p->p, PS_UP);
}
예제 #12
0
파일: bgp.c 프로젝트: rogerhu/dd-wrt
void
bgp_conn_enter_openconfirm_state(struct bgp_conn *conn)
{
    /* Really, most of the work is done in bgp_rx_open(). */
    bgp_conn_set_state(conn, BS_OPENCONFIRM);
}