Example #1
0
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);
      }
}
Example #2
0
/* 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;
}