void bgp_sync_init (struct peer *peer) { afi_t afi; safi_t safi; struct bgp_synchronize *sync; for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { sync = XCALLOC (MTYPE_BGP_SYNCHRONISE, sizeof (struct bgp_synchronize)); FIFO_INIT (&sync->update); FIFO_INIT (&sync->withdraw); FIFO_INIT (&sync->withdraw_low); peer->sync[afi][safi] = sync; peer->hash[afi][safi] = hash_create (baa_hash_key, baa_hash_cmp); } }
/* BGP Peer Incoming Connection Accept thread handler */ s_int32_t bpn_sock_accept (struct thread *t_accept) { struct bgp_listen_sock_lnode *tmp_lnode; struct bgp_peer_inconn_req *peer_icr; u_int8_t su_buf [SU_ADDRSTRLEN]; pal_sock_handle_t accept_sock; pal_sock_handle_t bgp_sock; struct lib_globals *blg; struct bgp_peer *peer; union sockunion su; struct bgp *bgp; s_int32_t ret; bgp_sock = THREAD_FD (t_accept); blg = THREAD_GLOB (t_accept); bgp = THREAD_ARG (t_accept); ret = 0; /* Sanity check thread variables */ if (! blg || &BLG != blg) { ret = -1; goto EXIT; } if (! bgp) { zlog_err (&BLG, "[NETWORK] Accept Thread: Invalid Vital Vars, " "blg(%p) bgp(%p)", blg, bgp); ret = -1; goto EXIT; } /* Verify integrity of thread variables */ for (tmp_lnode = bgp->listen_sock_lnode; tmp_lnode; tmp_lnode = tmp_lnode->next) { if (tmp_lnode->listen_sock == bgp_sock) break; } if (! tmp_lnode) { zlog_err (&BLG, "[NETWORK] Accept Thread: Mismatch in thread args" "blg(%p) bgp(%p)", blg, bgp); ret = -1; goto EXIT; } /* Set BGP VR Context */ BGP_SET_VR_CONTEXT (&BLG, bgp->owning_bvr); /* Re-regiser accept thread */ t_accept = NULL; BGP_READ_ON (&BLG, t_accept, bgp, bpn_sock_accept, bgp_sock); /* Update the Accept Thread List Node */ tmp_lnode->t_accept = t_accept; /* Accept Incoming Connection (Blocking) */ accept_sock = sockunion_accept (&BLG, bgp_sock, &su); if (accept_sock < 0) { zlog_err (&BLG, "[NETWORK] Accept Thread: accept() Failed for Server" " Sock %d, Err:%d-%s", bgp_sock, errno, pal_strerror (errno)); ret = -1; goto EXIT; } if (BGP_DEBUG (events, EVENTS)) zlog_info (&BLG, "[NETWORK] Accept Thread: Incoming conn from host" " %s (FD=%u)", inet_sutop (&su, su_buf), accept_sock); /* Search for Configured Peer with same Remote IP address */ peer = bgp_peer_search (bgp, &su); if (! peer) { if (BGP_DEBUG (events, EVENTS)) zlog_info (&BLG, "[NETWORK] Accept Thread: %s - No such Peer " "configured", inet_sutop (&su, su_buf)); SSOCK_FD_CLOSE (&BLG, accept_sock); ret = -1; goto EXIT; } /* Prepare an Incoming Connection Req. Info structure */ peer_icr = XCALLOC (MTYPE_TMP, sizeof (struct bgp_peer_inconn_req)); if (! peer_icr) { zlog_err (&BLG, "[NETWORK] Accept Thread:" " Cannot allocate memory (%d) @ %s:%d", sizeof (struct bgp_peer_inconn_req), __FILE__, __LINE__); SSOCK_FD_CLOSE (&BLG, accept_sock); ret = -1; goto EXIT; } /* Initialize the FIFO Node */ FIFO_INIT (&peer_icr->icr_fifo); /* Store the ICR Information */ peer_icr->icr_sock = accept_sock; switch (su.sa.sa_family) { case AF_INET: peer_icr->icr_port = su.sin.sin_port; break; #ifdef HAVE_IPV6 case AF_INET6: peer_icr->icr_port = su.sin6.sin6_port; break; #endif /* HAVE_IPV6 */ } /* Enqueue into Peer's 'bicr_fifo' */ FIFO_ADD (&peer->bicr_fifo, &peer_icr->icr_fifo); /* Generate BGP Peer FSM ICR Event */ BGP_PEER_FSM_EVENT_ADD (&BLG, peer, BPF_EVENT_TCP_CONN_VALID); EXIT: return ret; }