Ejemplo n.º 1
0
static int
bfd_ioctl_state_change (struct bfd_nl_peerinfo *peerinfo)
{
	struct bfd_peer peer;
	struct zserv *client;
	struct listnode *node;


	if (IS_ZEBRA_DEBUG_KERNEL)
		zlog_info ("rcvd peerinfo %s: state=%d, ifindex=%d",
		    sockunion_log ((union sockunion *) &peerinfo->dst),
		    peerinfo->state, peerinfo->ifindex);

	memcpy (&peer.su, &peerinfo->dst.sa, sizeof (union sockunion));
	peer.ifindex = peerinfo->ifindex;

	if (peerinfo->state == BSM_Up)
	{
		for (node = listhead (client_list); node; nextnode (node))
			if ((client = getdata (node)) != NULL)
				zsend_bfd_peer_up (client, &peer);
	}
	else if (peerinfo->state == BSM_Down)
	{
		for (node = listhead (client_list); node; nextnode (node))
			if ((client = getdata (node)) != NULL)
				zsend_bfd_peer_down (client, &peer);
	}
	else
	{
	}

	return 0;
}
Ejemplo n.º 2
0
/* sockunion_connect returns
   -1 : error occured
   0 : connect success
   1 : connect is in progress */
enum connect_result
sockunion_connect (int fd, union sockunion *peersu, unsigned short port,
		   unsigned int ifindex)
{
	int ret;
	int val = 1;		
	union sockunion su;

        
	//inet_ntop(AF_INET, &sin.sin_addr, buf, 256);
	//fprintf(stderr, "convert from dstip %s address to union address success\n", buf);


	memcpy(&su, peersu, sizeof(union sockunion));
	
	printf ( "try connect to %s:%d fd %d : %s",sockunion_log ( &su ), ntohs(port), fd, strerror ( errno ) );	


	/* Call connect function. */
	ret = connect(fd, (struct sockaddr *) &su, sockunion_sizeof(&su));


	val = 0;		/* added by fanky 2004 0601 */

	/* Immediate success */
	if (ret == 0)
	{
		ret = ioctl(fd, FIONBIO, &val);	
		return connect_success;
	}

	/* If connect is in progress then return 1 else it's real error. */
	if (ret < 0)
	{
		if (errno != EINPROGRESS)		
		{
			printf ( "can't connect to %s fd %d : %s",
												 sockunion_log ( &su ), fd, strerror ( errno ) );	
			return connect_error;
		}
	}
	
	return connect_in_progress;
}
Ejemplo n.º 3
0
/* Return socket of sockunion. */
int sockunion_socket(const union sockunion *su)
{
	int sock;

	sock = socket(su->sa.sa_family, SOCK_STREAM, 0);
	if (sock < 0) {
		char buf[SU_ADDRSTRLEN];
		zlog_warn("Can't make socket for %s : %s",
			  sockunion_log(su, buf, SU_ADDRSTRLEN),
			  safe_strerror(errno));
		return -1;
	}

	return sock;
}
Ejemplo n.º 4
0
/* Performs a non-blocking connect().  */
enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
				      unsigned short port, ifindex_t ifindex)
{
	int ret;
	union sockunion su;

	memcpy(&su, peersu, sizeof(union sockunion));

	switch (su.sa.sa_family) {
	case AF_INET:
		su.sin.sin_port = port;
		break;
	case AF_INET6:
		su.sin6.sin6_port = port;
#ifdef KAME
		if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) {
			su.sin6.sin6_scope_id = ifindex;
			SET_IN6_LINKLOCAL_IFINDEX(su.sin6.sin6_addr, ifindex);
		}
#endif /* KAME */
		break;
	}

	/* Call connect function. */
	ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su));

	/* Immediate success */
	if (ret == 0)
		return connect_success;

	/* If connect is in progress then return 1 else it's real error. */
	if (ret < 0) {
		if (errno != EINPROGRESS) {
			char str[SU_ADDRSTRLEN];
			zlog_info("can't connect to %s fd %d : %s",
				  sockunion_log(&su, str, sizeof str), fd,
				  safe_strerror(errno));
			return connect_error;
		}
	}

	return connect_in_progress;
}
Ejemplo n.º 5
0
/* Bind socket to specified address. */
int sockunion_bind(int sock, union sockunion *su, unsigned short port,
		   union sockunion *su_addr)
{
	int size = 0;
	int ret;

	if (su->sa.sa_family == AF_INET) {
		size = sizeof(struct sockaddr_in);
		su->sin.sin_port = htons(port);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		su->sin.sin_len = size;
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
		if (su_addr == NULL)
			sockunion2ip(su) = htonl(INADDR_ANY);
	} else if (su->sa.sa_family == AF_INET6) {
		size = sizeof(struct sockaddr_in6);
		su->sin6.sin6_port = htons(port);
#ifdef SIN6_LEN
		su->sin6.sin6_len = size;
#endif /* SIN6_LEN */
		if (su_addr == NULL) {
#ifdef LINUX_IPV6
			memset(&su->sin6.sin6_addr, 0, sizeof(struct in6_addr));
#else
			su->sin6.sin6_addr = in6addr_any;
#endif /* LINUX_IPV6 */
		}
	}

	ret = bind(sock, (struct sockaddr *)su, size);
	if (ret < 0) {
		char buf[SU_ADDRSTRLEN];
		zlog_warn("can't bind socket for %s : %s",
			  sockunion_log(su, buf, SU_ADDRSTRLEN),
			  safe_strerror(errno));
	}

	return ret;
}
Ejemplo n.º 6
0
/* User=>Kernel IOCTL message */
static int
bfd_ioctl_peer (int cmd, struct bfd_peer *peer)
{
	int ret;
	int size;
	struct bfd_nl_peerinfo req;

	if(bfd_ioctl_sock < 0)
		return -1;

	if (peer->su.sa.sa_family == AF_INET)
		size = sizeof (struct sockaddr_in);
	else if (peer->su.sa.sa_family == AF_INET6)
		size = sizeof (struct sockaddr_in6);
	else
	{
		zlog_warn ("peer sockaddr is invalid");
		return -1;
	}

	memcpy (&req.dst.sa, &peer->su, size);
	req.ifindex = peer->ifindex;

	ret = ioctl(bfd_ioctl_sock, cmd, &req);
	if (ret == -1)
	{
		zlog_warn ("ioctl %s", strerror(errno));
		return -1;
	}

	if (IS_ZEBRA_DEBUG_KERNEL)
		zlog_info ("bfd peer %s (%s)", 
		    cmd == BFD_NEWPEER ? "BFD_NEWPEER" : "BFD_DELPEER",
		    sockunion_log (&peer->su));
	return 0;
}
Ejemplo n.º 7
0
/* sockunion_connect returns
   -1 : error occured
   0 : connect success
   1 : connect is in progress */
enum connect_result
sockunion_connect (int fd, union sockunion *peersu, unsigned short port,
		   unsigned int ifindex)
{
  int ret;
  int val;
  union sockunion su;

  memcpy (&su, peersu, sizeof (union sockunion));

  switch (su.sa.sa_family)
    {
    case AF_INET:
      su.sin.sin_port = port;
      break;
#ifdef HAVE_IPV6
    case AF_INET6:
      su.sin6.sin6_port  = port;
#ifdef KAME
      if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex)
	{
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
	  /* su.sin6.sin6_scope_id = ifindex; */
#ifdef MUSICA
	  su.sin6.sin6_scope_id = ifindex; 
#endif
#endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
#ifndef MUSICA
	  SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex);
#endif
	}
#endif /* KAME */
      break;
#endif /* HAVE_IPV6 */
    }      

  /* Make socket non-block. */
  val = fcntl (fd, F_GETFL, 0);
  fcntl (fd, F_SETFL, val|O_NONBLOCK);

  /* Call connect function. */
  ret = connect (fd, (struct sockaddr *) &su, sockunion_sizeof (&su));

  /* Immediate success */
  if (ret == 0)
    {
      fcntl (fd, F_SETFL, val);
      return connect_success;
    }

  /* If connect is in progress then return 1 else it's real error. */
  if (ret < 0)
    {
      if (errno != EINPROGRESS)
	{
	  char str[SU_ADDRSTRLEN];
	  zlog_info ("can't connect to %s fd %d : %s",
		     sockunion_log (&su, str, sizeof str),
		     fd, safe_strerror (errno));
	  return connect_error;
	}
    }

  fcntl (fd, F_SETFL, val);

  return connect_in_progress;
}
Ejemplo n.º 8
0
/* sockunion_connect returns
   -1 : error occured
   0 : connect success
   1 : connect is in progress */
enum connect_result
sockunion_connect (int fd, union sockunion *peersu, unsigned short port,
		   unsigned int ifindex)
{
  int ret;
  int val;
  union sockunion su;
  int ret2=0;

  memcpy (&su, peersu, sizeof (union sockunion));

  switch (su.sa.sa_family)
    {
    case AF_INET:
      su.sin.sin_port = port;
      break;
#ifdef HAVE_IPV6
    case AF_INET6:
      su.sin6.sin6_port  = port;
#ifdef KAME
      if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex)
	{
#ifdef HAVE_SIN6_SCOPE_ID
	  /* su.sin6.sin6_scope_id = ifindex; */
#ifdef MUSICA
	  su.sin6.sin6_scope_id = ifindex; 
#endif
#endif /* HAVE_SIN6_SCOPE_ID */
#ifndef MUSICA
	  SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex);
#endif
	}
#endif /* KAME */
      break;
#endif /* HAVE_IPV6 */
    }      

  /* Make socket non-block. */
  val = fcntl (fd, F_GETFL, 0);
  /*CID 10316 (#1 of 3): Unchecked return value from library (CHECKED_RETURN)
	3. check_return: Calling function "fcntl(fd, 4, val | 0x80)" without checking return value. This library function may fail and return an error code.
	Add check return value.*/
  /*fcntl (fd, F_SETFL, val|O_NONBLOCK);*/
  ret = fcntl (fd, F_SETFL, val|O_NONBLOCK);
  if(ret < 0)
	zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno));

  /* Call connect function. */
  ret = connect (fd, (struct sockaddr *) &su, sockunion_sizeof (&su));

  /* Immediate success */
  if (ret == 0)
    {
    /*CID 10316 (#2 of 3): Unchecked return value from library (CHECKED_RETURN)
	4. check_return: Calling function "fcntl(fd, 4, val)" without checking return value. This library function may fail and return an error code.
	Change , add check return value.*/
      /*fcntl (fd, F_SETFL, val);*/
	  ret2 = fcntl (fd, F_SETFL, val);
	  if(ret < 0)
		zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno));
      return connect_success;
    }

  /* If connect is in progress then return 1 else it's real error. */
  if (ret < 0)
    {
      if (errno != EINPROGRESS)
	{
		char *log_str = sockunion_log (&su);
		
	  zlog_info ("can't connect to %s fd %d : %s",
		     log_str, fd, safe_strerror (errno));
	  free(log_str);
	  return connect_error;
	}
    }
  /*CID 10316 (#3 of 3): Unchecked return value from library (CHECKED_RETURN)
	6. check_return: Calling function "fcntl(fd, 4, val)" without checking return value. This library function may fail and return an error code.
	Add check return value.*/
  /*fcntl (fd, F_SETFL, val);*/
  ret2 = fcntl (fd, F_SETFL, val);
  if(ret < 0)
  	zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno));

  return connect_in_progress;
}