Esempio n. 1
0
/* TCP connection open.  Next we send open message to remote peer. And
   add read thread for reading open message. */
static int
bgp_connect_success (struct peer *peer)
{
  char buf1[BUFSIZ];

  if (peer->fd < 0)
    {
      zlog_err ("bgp_connect_success peer's fd is negative value %d",
		peer->fd);
      return -1;
    }
  BGP_READ_ON (peer->t_read, bgp_read, peer->fd);

  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
    bgp_getsockname (peer);

  if (BGP_DEBUG (normal, NORMAL))
    {
      if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
	zlog_debug ("%s open active, local address %s", peer->host,
		    sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN));
      else
	zlog_debug ("%s passive open", peer->host);
    }

  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
    bgp_open_send (peer);

  return 0;
}
Esempio n. 2
0
/*
 * Set MD5 key for the socket, for the given IPv4 peer address.
 * If the password is NULL or zero-length, the option will be disabled.
 */
static int bgp_md5_set_socket(int socket, union sockunion *su,
			      uint16_t prefixlen, const char *password)
{
	int ret = -1;
	int en = ENOSYS;
#if HAVE_DECL_TCP_MD5SIG
	union sockunion su2;
#endif /* HAVE_TCP_MD5SIG */

	assert(socket >= 0);

#if HAVE_DECL_TCP_MD5SIG
	/* Ensure there is no extraneous port information. */
	memcpy(&su2, su, sizeof(union sockunion));
	if (su2.sa.sa_family == AF_INET)
		su2.sin.sin_port = 0;
	else
		su2.sin6.sin6_port = 0;

	/* For addresses, use the non-extended signature functionality */
	if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_PREFIXLEN)
	    || (su2.sa.sa_family == AF_INET6
		&& prefixlen == IPV6_MAX_PREFIXLEN))
		ret = sockopt_tcp_signature(socket, &su2, password);
	else
		ret = sockopt_tcp_signature_ext(socket, &su2, prefixlen,
						password);
	en = errno;
#endif /* HAVE_TCP_MD5SIG */

	if (ret < 0) {
		char sabuf[SU_ADDRSTRLEN];
		sockunion2str(su, sabuf, sizeof(sabuf));

		switch (ret) {
		case -2:
			flog_warn(
				EC_BGP_NO_TCP_MD5,
				"Unable to set TCP MD5 option on socket for peer %s (sock=%d): This platform does not support MD5 auth for prefixes",
				sabuf, socket);
			break;
		default:
			flog_warn(
				EC_BGP_NO_TCP_MD5,
				"Unable to set TCP MD5 option on socket for peer %s (sock=%d): %s",
				sabuf, socket, safe_strerror(en));
		}
	}

	return ret;
}
Esempio n. 3
0
s32 ws__showBgpNeighbor(WS_ENV * ws_env,s32 afi, s32 safi,s32 nstart, s32 nsize,struct BgpShowNeighborResponse * ret)
{
    s8 temp[SU_ADDRSTRLEN];
    s32 count = 0 , i = 0;
    s32 sum = 0 ;
    s32 max = 0;
    struct BgpShowNeighbor * out = NULL;
    web_bgp_neighbor_show_info_t * info = (void*)buff;

    if( socket_api_write(WEB_BGP_APICMD_SHOW_NBR,NULL,0) < 0 )
        return ws_send_soap_error(ws_env,"send command error!");

    do{
        count = socket_api_read(WEB_BGP_APICMD_SHOW_NBR,info,SOCKET_API_BUFFER_SIZE);
        if( count <= 0 )
        {
            break;
        }
        if( max < sum + count )
        {
            void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpShowNeighbor));
            if( out != NULL )
            {
                memcpy(tmp,out,sum * sizeof(struct BgpShowNeighbor));
                ws_free(ws_env,out);
            }
            out = tmp ;
            max = sum + count ;
        }
        for(i=0;i<count;i++)
        {
            out[sum].hostip = ws_strdup(ws_env, sockunion2str(&(info[i].su), temp, SU_ADDRSTRLEN) ) ;
            out[sum].asid   = info[i].asid ;
            out[sum].hostid = ws_strdup(ws_env,inet_ntoa(info[i].id));
            out[sum].state  = ws_strdup(ws_env,bgp_status_msg[(s32)info[i].state]);
            out[sum].localinterface = ws_strdup(ws_env,inet_ntoa(info[i].nexthop));
            out[sum].uptime = ws_strdup(ws_env,web_time_dump(info[i].t_uptime));
            out[sum].overtime = ws_strdup(ws_env,web_time_dump(info[i].t_dead));
            sum++;
        }
    }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) );

    ret->ret.sum = sum ;
    ret->ret.__ptrres = out ;
    ret->ret.__size = sum ;
    ret->ret.res_USCOREcount = sum ;

    return WS_OK;
}
Esempio n. 4
0
int nhrp_route_read(ZAPI_CALLBACK_ARGS)
{
	struct zapi_route api;
	struct zapi_nexthop *api_nh;
	struct interface *ifp = NULL;
	union sockunion nexthop_addr;
	char buf[2][PREFIX_STRLEN];
	int added;

	if (zapi_route_decode(zclient->ibuf, &api) < 0)
		return -1;

	/* we completely ignore srcdest routes for now. */
	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
		return 0;

	sockunion_family(&nexthop_addr) = AF_UNSPEC;
	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) {
		api_nh = &api.nexthops[0];

		nexthop_addr.sa.sa_family = api.prefix.family;
		switch (nexthop_addr.sa.sa_family) {
		case AF_INET:
			nexthop_addr.sin.sin_addr = api_nh->gate.ipv4;
			break;
		case AF_INET6:
			nexthop_addr.sin6.sin6_addr = api_nh->gate.ipv6;
			break;
		}

		if (api_nh->ifindex != IFINDEX_INTERNAL)
			ifp = if_lookup_by_index(api_nh->ifindex, VRF_DEFAULT);
	}

	added = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
	debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s",
	       added ? "add" : "del",
	       prefix2str(&api.prefix, buf[0], sizeof buf[0]),
	       sockunion2str(&nexthop_addr, buf[1], sizeof buf[1]),
	       ifp ? ifp->name : "(none)");

	nhrp_route_update_zebra(&api.prefix, &nexthop_addr, ifp);
	nhrp_shortcut_prefix_change(&api.prefix, !added);

	return 0;
}
Esempio n. 5
0
static void nhrp_interface_interface_notifier(struct notifier_block *n, unsigned long cmd)
{
	struct nhrp_interface *nifp = container_of(n, struct nhrp_interface, nbmanifp_notifier);
	struct interface *nbmaifp = nifp->nbmaifp;
	struct nhrp_interface *nbmanifp = nbmaifp->info;
	char buf[SU_ADDRSTRLEN];

	switch (cmd) {
	case NOTIFY_INTERFACE_CHANGED:
		nhrp_interface_update_mtu(nifp->ifp, AFI_IP);
		nhrp_interface_update_source(nifp->ifp);
		break;
	case NOTIFY_INTERFACE_ADDRESS_CHANGED:
		nifp->nbma = nbmanifp->afi[AFI_IP].addr;
		nhrp_interface_update(nifp->ifp);
		notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_NBMA_CHANGED);
		debugf(NHRP_DEBUG_IF, "%s: NBMA change: address %s",
			nifp->ifp->name,
			sockunion2str(&nifp->nbma, buf, sizeof buf));
		break;
	}
}
Esempio n. 6
0
/* passive peer socket accept */
static int pim_msdp_sock_accept(struct thread *thread)
{
	union sockunion su;
	struct pim_instance *pim = THREAD_ARG(thread);
	int accept_sock;
	int msdp_sock;
	struct pim_msdp_peer *mp;
	char buf[SU_ADDRSTRLEN];

	sockunion_init(&su);

	/* re-register accept thread */
	accept_sock = THREAD_FD(thread);
	if (accept_sock < 0) {
		flog_err(LIB_ERR_DEVELOPMENT,
			  "accept_sock is negative value %d", accept_sock);
		return -1;
	}
	pim->msdp.listener.thread = NULL;
	thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock,
			&pim->msdp.listener.thread);

	/* accept client connection. */
	msdp_sock = sockunion_accept(accept_sock, &su);
	if (msdp_sock < 0) {
		flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)",
			     safe_strerror(errno));
		return -1;
	}

	/* see if have peer config for this */
	mp = pim_msdp_peer_find(pim, su.sin.sin_addr);
	if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) {
		++pim->msdp.rejected_accepts;
		if (PIM_DEBUG_MSDP_EVENTS) {
			flog_err(PIM_ERR_MSDP_PACKET,
				  "msdp peer connection refused from %s",
				  sockunion2str(&su, buf, SU_ADDRSTRLEN));
		}
		close(msdp_sock);
		return -1;
	}

	if (PIM_DEBUG_MSDP_INTERNAL) {
		zlog_debug("MSDP peer %s accept success%s", mp->key_str,
			   mp->fd >= 0 ? "(dup)" : "");
	}

	/* if we have an existing connection we need to kill that one
	 * with this one */
	if (mp->fd >= 0) {
		if (PIM_DEBUG_MSDP_EVENTS) {
			zlog_notice(
				"msdp peer new connection from %s stop old connection",
				sockunion2str(&su, buf, SU_ADDRSTRLEN));
		}
		pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
	}
	mp->fd = msdp_sock;
	set_nonblocking(mp->fd);
	pim_msdp_update_sock_send_buffer_size(mp->fd);
	pim_msdp_peer_established(mp);
	return 0;
}
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;
  int accept_sock;
  union sockunion su;
  struct bgp_listener *listener = THREAD_ARG(thread);
  struct peer *peer;
  struct peer *peer1;
  char buf[SU_ADDRSTRLEN];

  /* Register accept thread. */
  accept_sock = THREAD_FD (thread);
  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
  listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock);

  /* Accept client connection. */
  bgp_sock = sockunion_accept (accept_sock, &su);
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
      return -1;
    }
  set_nonblocking (bgp_sock);

  /* Set socket send buffer size */
  bgp_update_sock_send_buffer_size(bgp_sock);

  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (NULL, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_debug ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_debug ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  bgp_set_socket_ttl (peer1, bgp_sock);

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN];

    peer = peer_create_accept (peer1->bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;
    peer->v_holdtime = peer1->v_holdtime;
    peer->v_keepalive = peer1->v_keepalive;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}
Esempio n. 8
0
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;
  int accept_sock;
  union sockunion su;
  struct peer *peer;
  struct peer *peer1;
  struct bgp *bgp;
  char buf[SU_ADDRSTRLEN];

  /* Regiser accept thread. */
  accept_sock = THREAD_FD (thread);
  bgp = THREAD_ARG (thread);

  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
  thread_add_read (master, bgp_accept, bgp, accept_sock);

  /* Accept client connection. */
  bgp_sock = sockunion_accept (accept_sock, &su);
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", strerror (errno));
      return -1;
    }

  if (BGP_DEBUG (events, EVENTS))
    zlog_info ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (bgp, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_info ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_info ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  /* In case of peer is EBGP, we should set TTL for this connection.  */
  if (peer_sort (peer1) == BGP_PEER_EBGP)
    sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);

  if (! bgp)
    bgp = peer1->bgp;

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_info ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN + 1];

    peer = peer_create_accept (bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = strdup (buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}
Esempio n. 9
0
s32  ws__getBgpNeighborInfo(WS_ENV * ws_env,s32 afi, s32 safi, s32 nstart, s32 nsize,  struct BgpNeighborInfosRespone * ret )
{
    s8 temp[SU_ADDRSTRLEN];
    s32 count = 0 , i = 0;
    s32 sum = 0 ;
    s32 max = 0;
    struct BgpNeighborInfos * out = NULL;
    web_bgp_neighbor_info_t * info = (void*)buff;

    if( socket_api_write(WEB_BGP_APICMD_GET_NBR,NULL,0) < 0 )
        return ws_send_soap_error(ws_env,"send command error!");

    do{
        count = socket_api_read(WEB_BGP_APICMD_GET_NBR,buff,SOCKET_API_BUFFER_SIZE);
        if( count <= 0 )
        {
            break;
        }
        if( max < sum + count )
        {
            void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpNeighborInfos));
            if( out != NULL )
            {
                memcpy(tmp,out,sum * sizeof(struct BgpNeighborInfos));
                ws_free(ws_env,out);
            }
            out = tmp ;
            max = sum + count ;
        }
        for(i=0;i<count;i++)
        {
            out[sum].addr = ws_strdup(ws_env, sockunion2str(&(info[i].su), temp, SU_ADDRSTRLEN) ) ;
            out[sum].asid = info[i].as ;
            out[sum].hop  = info[i].hop ;
            out[sum].af   = info[i].af ;
            out[sum].uptype=info[i].upsrc_type;
            out[sum].upvalue=ws_strdup(ws_env, (s8*)info[i].upsrc);
            out[sum].passvalue=ws_strdup(ws_env, (s8*)info[i].passwd);
            out[sum].passtype=(info[i].passwd[0]==0)?0:1;
            out[sum].defaultorg=info[i].default_org;
            out[sum].nexthopchg=info[i].nexthop_chg;
            out[sum].noroute   =info[i].no_route ;
            out[sum].allows    =info[i].allows_in ;
            out[sum].allowsmax =info[i].allows_in_max;
            out[sum].localas   =(info[i].localas>0)?1:0 ;
            out[sum].localasvalue = info[i].localas ;
            out[sum].keepalive = info[i].keepalive ;
            out[sum].holdtime  = info[i].holdtime ;
            out[sum].modtime   = (out[sum].keepalive||out[sum].holdtime)?1:0 ;
            out[sum].commnum   = info[i].comm_num ;
            out[sum].commstr   = ws_strdup(ws_env, (s8*)info[i].comm_str) ;
            out[sum].comm      = (out[sum].commnum||strlen(out[sum].commstr))?1:0 ;
            sum++;
        }
    }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) );

    ret->ret.sum = sum ;
    ret->ret.__ptrres = out ;
    ret->ret.__size = sum ;
    ret->ret.res_USCOREcount = sum ;

    return WS_OK;
}
Esempio n. 10
0
/* Accept bgp connection. */
static int
bgp_accept (struct thread *thread)
{
  int bgp_sock;		//socket used for BGP connection
  int accept_sock;
  union sockunion su;
  struct bgp_listener *listener = THREAD_ARG(thread);
  struct peer *peer;
  struct peer *peer1;
  char buf[SU_ADDRSTRLEN];
  

  /* Register accept thread to accept connections from a client */
  accept_sock = THREAD_FD (thread);
  if (accept_sock < 0)
    {
      zlog_err ("accept_sock is nevative value %d", accept_sock);
      return -1;
    }
    
    /*creating a new reading thread*/
  listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock);
  
  /* --------------------------------------------------
   * -               BGP ACCEPT                       -
   * --------------------------------------------------
   * 
   */

  printf("\n BGP ACCEPT: About to initialise SSL \n");
  ssl_init();		//initialise the library, method, contact of ssl session, returns nothing
  
  printf("\n BGP ACCEPT: About to do socket call \n");
  
  bgp_sock = sockunion_accept (accept_sock, &su);

  SSL_accept(BGPoTLS->ssl);
  
  if (bgp_sock < 0)
    {
      zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
      return -1;
    }
  set_nonblocking (bgp_sock);

  if (BGP_DEBUG (events, EVENTS))
		zlog_debug("[Event] BGP connection from host %s", inet_sutop (&su, buf));
  
  /* Check remote IP address */
  peer1 = peer_lookup (NULL, &su);
  if (! peer1 || peer1->status == Idle)
    {
      if (BGP_DEBUG (events, EVENTS))
	{
	  if (! peer1)
	    zlog_debug ("[Event] BGP connection IP address %s is not configured",
		       inet_sutop (&su, buf));
	  else
	    zlog_debug ("[Event] BGP connection IP address %s is Idle state",
		       inet_sutop (&su, buf));
	}
      close (bgp_sock);
      return -1;
    }

  /* In case of peer is EBGP, we should set TTL for this connection.  */
  if (peer1->sort == BGP_PEER_EBGP) {
    sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
    if (peer1->gtsm_hops)
      sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops);
  }

  /* Make dummy peer until read Open packet. */
  if (BGP_DEBUG (events, EVENTS))
    zlog_debug ("[Event] Make dummy peer structure until read Open packet");

  {
    char buf[SU_ADDRSTRLEN];

    peer = peer_create_accept (peer1->bgp);
    SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
    peer->su = su;
    peer->fd = bgp_sock;
    peer->status = Active;
    peer->local_id = peer1->local_id;
    peer->v_holdtime = peer1->v_holdtime;
    peer->v_keepalive = peer1->v_keepalive;

    /* Make peer's address string. */
    sockunion2str (&su, buf, SU_ADDRSTRLEN);
    peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
  }

  BGP_EVENT_ADD (peer, TCP_connection_open);

  return 0;
}