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