Beispiel #1
0
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);
}
Beispiel #2
0
void
bgp_stop(struct bgp_proto *p, unsigned subcode)
{
    proto_notify_state(&p->p, PS_STOP);
    bgp_graceful_close_conn(&p->outgoing_conn, subcode);
    bgp_graceful_close_conn(&p->incoming_conn, subcode);
    ev_schedule(p->event);
}
Beispiel #3
0
static void
bgp_down(struct bgp_proto *p)
{
    if (p->start_state > BSS_PREPARE)
        bgp_close(p, 1);

    BGP_TRACE(D_EVENTS, "Down");
    proto_notify_state(&p->p, PS_DOWN);
}
Beispiel #4
0
/**
 * bgp_handle_graceful_restart - handle detected BGP graceful restart
 * @p: BGP instance
 *
 * This function is called when a BGP graceful restart of the neighbor is
 * detected (when the TCP connection fails or when a new TCP connection
 * appears). The function activates processing of the restart - starts routing
 * table refresh cycle and activates BGP restart timer. The protocol state goes
 * back to %PS_START, but changing BGP state back to %BS_IDLE is left for the
 * caller.
 */
void
bgp_handle_graceful_restart(struct bgp_proto *p)
{
  ASSERT(p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready);

  BGP_TRACE(D_EVENTS, "Neighbor graceful restart detected%s",
	    p->gr_active ? " - already pending" : "");
  proto_notify_state(&p->p, PS_START);

  if (p->gr_active)
    rt_refresh_end(p->p.main_ahook->table, p->p.main_ahook);

  p->gr_active = 1;
  bgp_start_timer(p->gr_timer, p->conn->peer_gr_time);
  rt_refresh_begin(p->p.main_ahook->table, p->p.main_ahook);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
/**
 * bgp_open - open a BGP instance
 * @p: BGP instance
 *
 * This function allocates and configures shared BGP resources.
 * Should be called as the last step during initialization
 * (when lock is acquired and neighbor is ready).
 * When error, state changed to PS_DOWN, -1 is returned and caller
 * should return immediately.
 */
static int
bgp_open(struct bgp_proto *p)
{
    struct config *cfg = p->cf->c.global;
    int errcode;

    bgp_counter++;

    if (!bgp_listen_sk)
        bgp_listen_sk = bgp_setup_listen_sk(cfg->listen_bgp_addr, cfg->listen_bgp_port, cfg->listen_bgp_flags);

    if (!bgp_listen_sk)
    {
        bgp_counter--;
        errcode = BEM_NO_SOCKET;
        goto err;
    }

    if (!bgp_linpool)
        bgp_linpool = lp_new(&root_pool, 4080);

    if (p->cf->password)
    {
        int rv = sk_set_md5_auth(bgp_listen_sk, p->cf->remote_ip, p->cf->iface, p->cf->password);
        if (rv < 0)
        {
            bgp_close(p, 0);
            errcode = BEM_INVALID_MD5;
            goto err;
        }
    }

    return 0;

err:
    p->p.disabled = 1;
    bgp_store_error(p, NULL, BE_MISC, errcode);
    proto_notify_state(&p->p, PS_DOWN);
    return -1;
}