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); }
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); }
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); }
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); }
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); }
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); }
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); }
/** * 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); }
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); }
/** * 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; }
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); }
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); }