示例#1
0
int sock_read(struct socket *sock, void *buf, int len, struct  sockaddr *sockaddr)
{
	struct msghdr msg;
	struct iovec iov;
	mm_segment_t oldfs;
	int size = 0;

	if (sock->sk==NULL)
		return 0;

	iov.iov_base = buf;
	iov.iov_len = len;

	msg.msg_flags = 0;
	msg.msg_name = sockaddr;
	msg.msg_namelen  = sizeof(struct sockaddr);
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;

	oldfs = get_fs();
	set_fs(KERNEL_DS);
	size = sock_recvmsg(sock,&msg,len,msg.msg_flags);
	set_fs(oldfs);

	return size;
}
示例#2
0
文件: sbd.c 项目: sciciliani/sbdtcp
int recv_sync_buf(struct socket *sock, void *buf, const size_t length, unsigned long flags)
{       mm_segment_t oldmm;
        struct msghdr msg;
        struct iovec iov;
        int len;
        int max_size = length;

        msg.msg_name     = 0;
        msg.msg_namelen  = 0;
        msg.msg_iov      = &iov;
        msg.msg_iovlen   = 1;
        msg.msg_control  = NULL;
        msg.msg_controllen = 0;
        msg.msg_flags    = 0;

        msg.msg_iov->iov_base = buf;
        msg.msg_iov->iov_len  = max_size;

        oldmm = get_fs(); set_fs(KERNEL_DS);

read_again:
        len = sock_recvmsg(sock, &msg, max_size, 0); /* MSG_DONTWAIT); */
        if (len == -EAGAIN || len == -ERESTARTSYS) {
            goto read_again;
        }
        set_fs(oldmm);
        return len;
}
示例#3
0
static int
ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen)
{
	struct msghdr		msg;
	struct iovec		iov;
	int			len;
	mm_segment_t		oldfs;

	EnterFunction(7);

	/* Receive a packet */
	iov.iov_base     = buffer;
	iov.iov_len      = (size_t)buflen;
	msg.msg_name     = 0;
	msg.msg_namelen  = 0;
	msg.msg_iov	 = &iov;
	msg.msg_iovlen   = 1;
	msg.msg_control  = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags    = 0;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_recvmsg(sock, &msg, buflen, 0);
	set_fs(oldfs);

	if (len < 0)
		return -1;

	LeaveFunction(7);
	return len;
}
示例#4
0
int recv_msg ( struct socket *sock, char *buf, unsigned int max )
{
    int len;
    struct msghdr msg;
    struct iovec iov;
    mm_segment_t old_fs;

    iov.iov_base = buf;
    iov.iov_len = max;

    msg.msg_name = 0;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;

    old_fs = get_fs();
    set_fs(get_ds());

    len = sock_recvmsg(sock, &msg, max, 0);

    set_fs(old_fs);

    return len;
}
示例#5
0
static int ksocket_receive(struct socket *sock,
			   struct sockaddr_in *addr,
			   unsigned char *buf, int len)
{
	struct msghdr msg;
	struct iovec iov;
	mm_segment_t oldfs;
	int size = 0;

	if (sock->sk == NULL)
		return 0;

	iov.iov_base = buf;
	iov.iov_len = len;

	msg.msg_flags = 0;
	msg.msg_name = addr;
	msg.msg_namelen = sizeof(struct sockaddr_in);
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;

	oldfs = get_fs();
	set_fs(KERNEL_DS);
	size = sock_recvmsg(sock, &msg, len, msg.msg_flags);
	set_fs(oldfs);

	return size;
}
//-----------------------------------------------------------------------------
static int _gtpusp_ksocket_receive(struct socket* sock_pP, struct sockaddr_in* addr_pP, unsigned char* buf_pP, int lenP)
//-----------------------------------------------------------------------------
{
  struct msghdr msg;
  struct iovec iov;
  mm_segment_t oldfs;
  int size = 0;

  if (sock_pP->sk==NULL) return 0;

  iov.iov_base = buf_pP;
  iov.iov_len = lenP;

#if defined(FLAG_GTPV1U_KERNEL_THREAD_SOCK_NO_WAIT)
  msg.msg_flags = MSG_DONTWAIT;
#else
  msg.msg_flags = 0;
#endif
  msg.msg_name = addr_pP;
  msg.msg_namelen  = sizeof(struct sockaddr_in);
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = NULL;

  oldfs = get_fs();
  set_fs(KERNEL_DS);
  size = sock_recvmsg(sock_pP,&msg,lenP,msg.msg_flags);
  set_fs(oldfs);

  return size;
}
size_t RecvBuffer(struct socket *sock, const char *Buffer, size_t Length)
{
	struct msghdr msg;
	struct iovec iov;

	int len;
	mm_segment_t oldfs;
	printk("Server:Entering Rec. Buffer Server");
	/* Set the msghdr structure*/
	msg.msg_name = 0;
	msg.msg_namelen = 0;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags = 0;

	/* Set the iovec structure*/
	iov.iov_base = (void *) &Buffer[0];
	iov.iov_len = (size_t)Length;

	/* Recieve the message */
	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_recvmsg(sock,&msg,Length,0/*MSG_DONTWAIT*/); // let it wait if there is no message
	set_fs(oldfs);
	printk("Server msg sent:- %s", Buffer);
	//if ((len!=-EAGAIN)&&(len!=0)){
	printk("Server:RecvBuffer Recieved %i bytes \n",len);

	printk("Server:finish recvbuffer");
	return len;

}
示例#8
0
static int receive_data(rdma_ctx_t ctx, char* data, int size) {
    struct msghdr msg;
    struct iovec iov;
    int retval;
    mm_segment_t oldfs;
    
    LOG_KERN(LOG_INFO, ("receive_data\n"));
    
    msg.msg_name = 0;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;
    msg.msg_iov->iov_base= data;
    msg.msg_iov->iov_len = size;
    
    LOG_KERN(LOG_INFO, ("Receving data..\n"));

    oldfs = get_fs();
    set_fs(KERNEL_DS);

    retval = sock_recvmsg(ctx->sock, &msg, size, 0);

    set_fs(oldfs);

    return 0;
}
示例#9
0
static int rk_recvbuff(struct socket *sock, char *buffer, int length)
{
    struct msghdr msg;
    struct iovec iov;
    int len = 0;
    mm_segment_t oldfs;

    iov.iov_base = buffer;
    iov.iov_len  = length;

    #if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
       msg.msg_iov = &iov;
       msg.msg_iovlen = 1;
    #else
      iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, length);
    #endif

    oldfs = get_fs(); 
    set_fs(KERNEL_DS);
    len = sock_recvmsg(sock,&msg,length,0); //no wait
    set_fs(oldfs);

    if ((len!=-EAGAIN)&&(len!=0)&&(len!=(-107)))
        dbg("backdoor: rk_recvbuff recieved %i bytes \n",len);
    return len;
}
示例#10
0
static int run_network(void *data)
{
  struct msghdr msg;
  struct iovec iov;
  mm_segment_t oldfs;
  char buffer[0x200];// = "Hello";
  int cc;
  struct socket *csock = data;
  struct nm_packet_rp *reply;

  printk(KERN_INFO "NetMalloc: creating client thread\n");
  while (network_is_running)
    {
      memset(&msg, 0, sizeof(msg));
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      msg.msg_flags = MSG_DONTWAIT;
      msg.msg_iov->iov_len = sizeof(buffer);
      msg.msg_iov->iov_base = buffer;
      oldfs = get_fs();
      set_fs(KERNEL_DS);
      cc = sock_recvmsg(csock, &msg, sizeof(buffer), MSG_DONTWAIT);
      set_fs(oldfs);

      if (!cc)
	break;
      else if (cc == -EWOULDBLOCK)
        schedule_timeout_interruptible(125);
      else if (cc > 0)
	{
	  printk(KERN_INFO "%d bytes received\n", cc);
	  reply = handle_packet((struct nm_packet_rq *) buffer, cc);
	  if (reply)
	    {
	      cc = sizeof(struct nm_packet_rp) + reply->data_len;
	      memset(&msg, 0, sizeof(msg));
	      msg.msg_iov = &iov;
	      msg.msg_iovlen = 1;
	      msg.msg_flags = MSG_DONTWAIT;
	      msg.msg_iov->iov_len = cc;
	      msg.msg_iov->iov_base = reply;
	      oldfs = get_fs();
	      set_fs(KERNEL_DS);
	      cc = sock_sendmsg(csock, &msg, cc);
	      set_fs(oldfs);
	      printk(KERN_INFO "%d bytes sent\n", cc);
	      kfree(reply);
	    }
	}
    }
  sock_release(csock);
  printk(KERN_INFO "NetMalloc: closing client thread\n");
  return 0;
}
示例#11
0
ssize_t krecv(ksocket_t socket, void *buffer, size_t length, int flags)
{
	struct socket *sk;
	struct msghdr msg;

#if LINUX_VERSION_CODE > KERNEL_VERSION(3,19,00) 
	struct iov_iter iovi;
#endif

	struct iovec iov;
	int ret;
#ifndef KSOCKET_ADDR_SAFE
	mm_segment_t old_fs;
#endif

	sk = (struct socket *)socket;

	iov.iov_base = (void *)buffer;
	iov.iov_len = (__kernel_size_t)length;

	msg.msg_name = NULL;
	msg.msg_namelen = 0;
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,19,00) 
	iovi.iov = &iov;
	msg.msg_iter = iovi;
#else
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
#endif
	msg.msg_control = NULL;
	msg.msg_controllen = 0;

	/*
	 * msg.msg_iov->iov_base is declared as follows:
	 * void __user *iov_base;
	 * which means there is an user space pointer in 'msg'
	 * use set_fs(KERNEL_DS) to make the pointer safe to kernel space
	 */
#ifndef KSOCKET_ADDR_SAFE
	old_fs = get_fs();
	set_fs(KERNEL_DS);
#endif
	ret = sock_recvmsg(sk, &msg, length, flags);
#ifndef KSOCKET_ADDR_SAFE
	set_fs(old_fs);
#endif
	if (ret < 0)
		goto out_krecv;
	//ret = msg.msg_iov.iov_len;//?
	
out_krecv:
	return ret;

}
示例#12
0
ssize_t krecvfrom(ksocket_t socket, void * buffer, size_t length,
              int flags, struct sockaddr * address,
              int * address_len)
{
	struct socket *sk;
	struct msghdr msg;
	struct iovec iov;

#if LINUX_VERSION_CODE > KERNEL_VERSION(3,19,00) 
	struct iov_iter iovi;
#endif

	int len;
#ifndef KSOCKET_ADDR_SAFE
	mm_segment_t old_fs;
#endif

	sk = (struct socket *)socket;

	iov.iov_base = (void *)buffer;
	iov.iov_len = (__kernel_size_t)length;

	msg.msg_name = address;
	msg.msg_namelen = 128;

#if LINUX_VERSION_CODE > KERNEL_VERSION(3,19,00) 
	iovi.iov = &iov;
	msg.msg_iter = iovi;
#else
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
#endif
	
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	
#ifndef KSOCKET_ADDR_SAFE
	old_fs = get_fs();
	set_fs(KERNEL_DS);
#endif
	len = sock_recvmsg(sk, &msg, length, flags);
#ifndef KSOCKET_ADDR_SAFE
	set_fs(old_fs);
#endif

	if (address)
	{
		*address_len = msg.msg_namelen;
	}
	
	return len;
}
示例#13
0
ssize_t sim_sock_recvmsg (struct SimSocket *socket, struct msghdr *msg, int flags)
{
  struct socket *kernel_socket = (struct socket *)socket;
  struct iovec *kernel_iov = copy_iovec (msg->msg_iov, msg->msg_iovlen);
  struct iovec *user_iov = msg->msg_iov;
  struct cmsghdr *user_cmsgh = msg->msg_control;
  size_t user_cmsghlen = msg->msg_controllen;
  msg->msg_iov = kernel_iov;
  int retval = sock_recvmsg (kernel_socket, msg, iov_size (msg), flags);
  msg->msg_iov = user_iov;
  msg->msg_control = user_cmsgh;
  msg->msg_controllen = user_cmsghlen - msg->msg_controllen;
  sim_free (kernel_iov);
  return retval;
}
示例#14
0
/* Receive data over TCP/IP. */
int usbip_recv(struct socket *sock, void *buf, int size)
{
	int result;
	struct kvec iov = {.iov_base = buf, .iov_len = size};
	struct msghdr msg = {.msg_flags = MSG_NOSIGNAL};
	int total = 0;

	iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size);

	usbip_dbg_xmit("enter\n");

	if (!sock || !buf || !size) {
		pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf,
		       size);
		return -EINVAL;
	}

	do {
		int sz = msg_data_left(&msg);
		sock->sk->sk_allocation = GFP_NOIO;

		result = sock_recvmsg(sock, &msg, MSG_WAITALL);
		if (result <= 0) {
			pr_debug("receive sock %p buf %p size %u ret %d total %d\n",
				 sock, buf + total, sz, result, total);
			goto err;
		}

		total += result;
	} while (msg_data_left(&msg));

	if (usbip_dbg_flag_xmit) {
		if (!in_interrupt())
			pr_debug("%-10s:", current->comm);
		else
			pr_debug("interrupt  :");

		pr_debug("receiving....\n");
		usbip_dump_buffer(buf, size);
		pr_debug("received, osize %d ret %d size %zd total %d\n",
			 size, result, msg_data_left(&msg), total);
	}

	return total;

err:
	return result;
}
示例#15
0
static int __ci_udp_recvmsg_try_os(ci_netif *ni, ci_udp_state *us,
                                   ci_msghdr* msg, int flags, int* prc)
{
  int rc, total_bytes, i;
  tcp_helper_endpoint_t *ep;
  struct socket *sock;
  struct file *os_sock;
  struct msghdr kmsg;

  total_bytes = 0;
  for( i = 0; i < msg->msg_iovlen; ++i )
    total_bytes += msg->msg_iov[i].iov_len;
  rc = -EMSGSIZE;
  if( total_bytes < 0 )
    return -EINVAL;

  ep = ci_netif_ep_get(ni, SC_SP(&us->s));
  os_sock = ep->os_socket->file;
  ci_assert(S_ISSOCK(os_sock->f_dentry->d_inode->i_mode));
  sock = SOCKET_I(os_sock->f_dentry->d_inode);

  oo_msg_iov_init(&kmsg, READ, msg->msg_iov, msg->msg_iovlen, total_bytes);
  kmsg.msg_namelen = 0;
  kmsg.msg_controllen = 0;
  rc = sock_recvmsg(sock, &kmsg, total_bytes, flags | MSG_DONTWAIT);
  /* Clear OS RX flag if we've got everything  */
  oo_os_sock_status_bit_clear(&us->s, OO_OS_STATUS_RX,
                              os_sock->f_op->poll(os_sock, NULL) & POLLIN);
  if( rc >= 0 ) {
    ++us->stats.n_rx_os;
  }
  else {
    if( rc == -EAGAIN )
      return 0;
    ++us->stats.n_rx_os_error;
  }

  if( rc >= 0 ) {
    us->udpflags &= ~CI_UDPF_LAST_RECV_ON;
    if( ! (flags & MSG_PEEK) )
      us->udpflags &=~ CI_UDPF_PEEK_FROM_OS;
    else
      us->udpflags |=  CI_UDPF_PEEK_FROM_OS;
  }
  *prc = rc;
  return 1;
}
示例#16
0
文件: sock.c 项目: xricson/knoppix
static int _recv(struct socket *sock, unsigned char *ubuf, int size,
                 unsigned flags)
{
    struct iovec iov;
    struct msghdr msg;

    iov.iov_base = ubuf;
    iov.iov_len = size;

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_control = NULL;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    return sock_recvmsg(sock, &msg, size, flags);
}
示例#17
0
static int tpmd_handle_command(const uint8_t *in, uint32_t in_size)
{
  int res;
  mm_segment_t oldmm;
  struct msghdr msg;
  struct iovec iov;
  /* send command to tpmd */
  memset(&msg, 0, sizeof(msg));
  iov.iov_base = (void*)in;
  iov.iov_len = in_size;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  res = sock_sendmsg(tpmd_sock, &msg, in_size);
  if (res < 0) {
    error("sock_sendmsg() failed: %d\n", res);
    return res;
  }
  /* receive response from tpmd */
  tpm_response.size = TPM_CMD_BUF_SIZE;
  tpm_response.data = kmalloc(tpm_response.size, GFP_KERNEL);
  if (tpm_response.data == NULL) return -1;
  memset(&msg, 0, sizeof(msg));
  iov.iov_base = (void*)tpm_response.data;
  iov.iov_len = tpm_response.size;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  oldmm = get_fs();
  set_fs(KERNEL_DS);
  res = sock_recvmsg(tpmd_sock, &msg, tpm_response.size, 0);
  set_fs(oldmm);
  if (res < 0) {
    error("sock_recvmsg() failed: %d\n", res);
    tpm_response.data = NULL;
    return res;
  }
  tpm_response.size = res;
  return 0;
}
示例#18
0
static int recv_hello_msg (struct socket *sock)
{
	struct msghdr hdr;
	struct iovec iov;
	char buf[16+1];
	int ret;

	memset (&hdr, 0, sizeof (hdr));
	hdr.msg_iov = &iov;
	hdr.msg_iovlen = 1;

	iov.iov_base = &buf;
	iov.iov_len = sizeof (buf)-1;

	ret = sock_recvmsg (sock, &hdr, iov.iov_len, 0);

	if (ret > 0) {
		buf[ret] = 0;
		printk (KERN_INFO "Got: %s\n", buf);
	}

	return ret;
}
示例#19
0
/*
 * Generic recvfrom routine.
 */
static int
svc_recvfrom(struct svc_rqst *rqstp, struct iovec *iov, int nr, int buflen)
{
	mm_segment_t	oldfs;
	struct msghdr	msg;
	struct socket	*sock;
	int		len, alen;

	rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
	sock = rqstp->rq_sock->sk_sock;

	msg.msg_name    = &rqstp->rq_addr;
	msg.msg_namelen = sizeof(rqstp->rq_addr);
	msg.msg_iov     = iov;
	msg.msg_iovlen  = nr;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;

	msg.msg_flags	= MSG_DONTWAIT;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_recvmsg(sock, &msg, buflen, MSG_DONTWAIT);
	set_fs(oldfs);

	/* sock_recvmsg doesn't fill in the name/namelen, so we must..
	 * possibly we should cache this in the svc_sock structure
	 * at accept time. FIXME
	 */
	alen = sizeof(rqstp->rq_addr);
	sock->ops->getname(sock, (struct sockaddr *)&rqstp->rq_addr, &alen, 1);

	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
		rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len);

	return len;
}
示例#20
0
static int sock_read(struct socket* sock, void* buffer, size_t len)
{
	int            ret;
	struct msghdr  msg;
	struct iovec   iov;
	mm_segment_t   oldfs;

	memset(&msg, 0, sizeof(msg));

	msg.msg_iov    = &iov;
	msg.msg_iovlen = 1;

	iov.iov_base   = buffer;
	iov.iov_len    = len;

	oldfs = get_fs();
	set_fs(KERNEL_DS);

	ret = sock_recvmsg(sock, &msg, len, msg.msg_flags);

	set_fs(oldfs);

	return ret;
}
示例#21
0
/*
 * Generic recvfrom routine.
 */
static int
svc_recvfrom(struct svc_rqst *rqstp, struct iovec *iov, int nr, int buflen)
{
	mm_segment_t	oldfs;
	struct msghdr	msg;
	struct socket	*sock;
	int		len;

	rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
	sock = rqstp->rq_sock->sk_sock;

	msg.msg_name    = &rqstp->rq_addr;
	msg.msg_namelen = sizeof(rqstp->rq_addr);
	msg.msg_iov     = iov;
	msg.msg_iovlen  = nr;
	msg.msg_control = 0;

#if LINUX_VERSION_CODE >= 0x020100
	msg.msg_flags	= MSG_DONTWAIT;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock_recvmsg(sock, &msg, buflen, MSG_DONTWAIT);
	set_fs(oldfs);
#else
	msg.msg_flags	= 0;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	len = sock->ops->recvmsg(sock, &msg, buflen, 0, 1, &rqstp->rq_addrlen);
	set_fs(oldfs);
#endif

	dprintk("svc: socket %p recvfrom(%p, %d) = %d\n", rqstp->rq_sock,
				iov[0].iov_base, iov[0].iov_len, len);

	return len;
}
示例#22
0
int rst_restore_route(struct cpt_context *ctx)
{
	int err;
	struct socket *sock;
	struct msghdr msg;
	struct iovec iov;
	struct sockaddr_nl nladdr;
	mm_segment_t oldfs;
	loff_t sec = ctx->sections[CPT_SECT_NET_ROUTE];
	loff_t endsec;
	struct cpt_section_hdr h;
	struct cpt_object_hdr v;
	char *pg;

	if (sec == CPT_NULL)
		return 0;

	err = ctx->pread(&h, sizeof(h), ctx, sec);
	if (err)
		return err;
	if (h.cpt_section != CPT_SECT_NET_ROUTE || h.cpt_hdrlen < sizeof(h))
		return -EINVAL;

	if (h.cpt_hdrlen >= h.cpt_next)
		return 0;

	sec += h.cpt_hdrlen;
	err = rst_get_object(CPT_OBJ_NET_ROUTE, sec, &v, ctx);
	if (err < 0)
		return err;

	err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock);
	if (err)
		return err;

	pg = (char*)__get_free_page(GFP_KERNEL);
	if (pg == NULL) {
		err = -ENOMEM;
		goto out_sock;
	}

	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;

	endsec = sec + v.cpt_next;
	sec += v.cpt_hdrlen;

	while (sec < endsec) {
		struct nlmsghdr *n;
		struct nlmsghdr nh;
		int kernel_flag;

		if (endsec - sec < sizeof(nh))
			break;

		err = ctx->pread(&nh, sizeof(nh), ctx, sec);
		if (err)
			goto out_sock_pg;
		if (nh.nlmsg_len < sizeof(nh) || nh.nlmsg_len > PAGE_SIZE ||
		    endsec - sec < nh.nlmsg_len) {
			err = -EINVAL;
			goto out_sock_pg;
		}
		err = ctx->pread(pg, nh.nlmsg_len, ctx, sec);
		if (err)
			goto out_sock_pg;

		n = (struct nlmsghdr*)pg;
		n->nlmsg_flags = NLM_F_REQUEST|NLM_F_APPEND|NLM_F_CREATE;

		err = rewrite_rtmsg(n, ctx);
		if (err < 0)
			goto out_sock_pg;
		kernel_flag = err;

		if (kernel_flag == 2)
			goto do_next;

		iov.iov_base=n;
		iov.iov_len=nh.nlmsg_len;
		msg.msg_name=&nladdr;
		msg.msg_namelen=sizeof(nladdr);
		msg.msg_iov=&iov;
		msg.msg_iovlen=1;
		msg.msg_control=NULL;
		msg.msg_controllen=0;
		msg.msg_flags=MSG_DONTWAIT;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_sendmsg(sock, &msg, nh.nlmsg_len);
		set_fs(oldfs);

		if (err < 0)
			goto out_sock_pg;
		err = 0;

		iov.iov_base=pg;
		iov.iov_len=PAGE_SIZE;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT);
		set_fs(oldfs);
		if (err != -EAGAIN) {
			if (n->nlmsg_type == NLMSG_ERROR) {
				struct nlmsgerr *e = NLMSG_DATA(n);
				if (e->error != -EEXIST || !kernel_flag)
					eprintk_ctx("NLMERR: %d\n", e->error);
			} else {
				eprintk_ctx("Res: %d %d\n", err, n->nlmsg_type);
			}
		}
do_next:
		err = 0;
		sec += NLMSG_ALIGN(nh.nlmsg_len);
	}

out_sock_pg:
	free_page((unsigned long)pg);
out_sock:
	sock_release(sock);
	return err;
}
示例#23
0
int
ksocknal_lib_recv_iov(struct ksock_conn *conn)
{
	unsigned int niov = conn->ksnc_rx_niov;
	struct kvec *iov = conn->ksnc_rx_iov;
	struct msghdr msg = {
		.msg_flags = 0
	};
	int nob;
	int i;
	int rc;
	int fragnob;
	int sum;
	__u32 saved_csum;

	LASSERT(niov > 0);

	for (nob = i = 0; i < niov; i++)
		nob += iov[i].iov_len;

	LASSERT(nob <= conn->ksnc_rx_nob_wanted);

	iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, niov, nob);
	rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);

	saved_csum = 0;
	if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
		saved_csum = conn->ksnc_msg.ksm_csum;
		conn->ksnc_msg.ksm_csum = 0;
	}

	if (saved_csum) {
		/* accumulate checksum */
		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
			LASSERT(i < niov);

			fragnob = iov[i].iov_len;
			if (fragnob > sum)
				fragnob = sum;

			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
							   iov[i].iov_base, fragnob);
		}
		conn->ksnc_msg.ksm_csum = saved_csum;
	}

	return rc;
}

int
ksocknal_lib_recv_kiov(struct ksock_conn *conn)
{
	unsigned int niov = conn->ksnc_rx_nkiov;
	lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
	struct msghdr msg = {
		.msg_flags = 0
	};
	int nob;
	int i;
	int rc;
	void *base;
	int sum;
	int fragnob;

	for (nob = i = 0; i < niov; i++)
		nob += kiov[i].bv_len;

	LASSERT(nob <= conn->ksnc_rx_nob_wanted);

	iov_iter_bvec(&msg.msg_iter, READ | ITER_BVEC, kiov, niov, nob);
	rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);

	if (conn->ksnc_msg.ksm_csum) {
		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
			LASSERT(i < niov);

			base = kmap(kiov[i].bv_page) + kiov[i].bv_offset;
			fragnob = kiov[i].bv_len;
			if (fragnob > sum)
				fragnob = sum;

			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
							   base, fragnob);

			kunmap(kiov[i].bv_page);
		}
	}
	return rc;
}

void
ksocknal_lib_csum_tx(struct ksock_tx *tx)
{
	int i;
	__u32 csum;
	void *base;

	LASSERT(tx->tx_iov[0].iov_base == &tx->tx_msg);
	LASSERT(tx->tx_conn);
	LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);

	tx->tx_msg.ksm_csum = 0;

	csum = ksocknal_csum(~0, tx->tx_iov[0].iov_base,
			     tx->tx_iov[0].iov_len);

	if (tx->tx_kiov) {
		for (i = 0; i < tx->tx_nkiov; i++) {
			base = kmap(tx->tx_kiov[i].bv_page) +
			       tx->tx_kiov[i].bv_offset;

			csum = ksocknal_csum(csum, base, tx->tx_kiov[i].bv_len);

			kunmap(tx->tx_kiov[i].bv_page);
		}
	} else {
		for (i = 1; i < tx->tx_niov; i++)
			csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
					     tx->tx_iov[i].iov_len);
	}

	if (*ksocknal_tunables.ksnd_inject_csum_error) {
		csum++;
		*ksocknal_tunables.ksnd_inject_csum_error = 0;
	}

	tx->tx_msg.ksm_csum = csum;
}
示例#24
0
static int receive(struct socket* sock, struct sockaddr_in* addr, void * data, int len)
{
	
	//struct msghdr msg;
        //struct iovec iov;
        mm_segment_t oldfs;
        int size = 0;
	rrep * tmp_rrep;
	struct kvec vec ={
                .iov_len =len,
                .iov_base=(char *)data,
        };
	struct msghdr msg = {
                .msg_iovlen = 1,
                .msg_iov = (struct iovec*)&vec,
                //.msg_flags=MSG_DONTWAIT,
		.msg_flags=0,
        };
	printk(KERN_INFO MODULE_NAME":Inside receive");
        if (sock->sk==NULL) return 0;

        //iov.iov_base = buf;
        //iov.iov_len = len;
        /*msg.msg_flags = 0;
        msg.msg_name = addr;
        msg.msg_namelen  = sizeof(struct sockaddr_in);
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
	iov.iov_base = buf;
        iov.iov_len = len;

        msg.msg_control = NULL;
	*/
        oldfs = get_fs();
        set_fs(KERNEL_DS);
        size = sock_recvmsg(sock,&msg,len,msg.msg_flags);
        set_fs(oldfs);
	tmp_rrep = (rrep *)data;
	printk(KERN_INFO "Message is :%s",tmp_rrep->type);
	kfree(tmp_rrep);	
        return size;
        
}

int init_module(void)
{
	
        int ret;
        
	my_wq = create_workqueue("my_queue");
	/*my_work_t.buf[0]='H';
	my_work_t.buf[1]='E';
	my_work_t.buf[2]='L';
	my_work_t.buf[3]='L';
	my_work_t.buf[4]='O';
	my_work_t.buf[5]='\0';*/
	
	if(my_wq){
		my_work=(my_work_t *)kmalloc(sizeof(my_work_t), GFP_KERNEL);
		
	if(my_work){
		INIT_WORK((struct work_struct *)my_work,start);
		//complete work_send
		ret = queue_work(my_wq,(struct work_struct *)my_work);
}
		
}

	return 0;
}

void cleanup_module(void)
{
	if (my_work->sock != NULL) 
        {
                sock_release(my_work->sock);
		sock_release(my_work->sock_send);
		my_work->sock_send=NULL;
                my_work->sock = NULL;
        }
	kfree(my_work);
	my_work=NULL;
	flush_workqueue(my_wq);	
	destroy_workqueue(my_wq);
	my_wq=NULL;
	return; 
}
static int the_socket(void)
{
	struct socket *socketnumber1;
	struct socket *socketnumber2;
	struct sockaddr_in *server_address;
	//struct sockaddr_in *client_addres;
	struct msghdr *sock_msg;
	struct iovec iov;
	int accepting1;
	int size;
	int readvalue;
	char *buffer;
	int a,b;
	//mm_segment_t oldms;

	printk(KERN_INFO "We are infact loading");

	a = sock_create_kern(PF_INET, SOCK_STREAM,IPPROTO_TCP, &socketnumber1);
	b = sock_create_lite(AF_INET, SOCK_STREAM, 0, &socketnumber2);
    server_address=(struct sockaddr_in*) kmalloc(sizeof(struct sockaddr_in),GFP_KERNEL);
   // client_address=(struct sockaddr_in*) kmalloc(sizeof(struct sockaddr_in),GFP_KERNEL);

    //iov = (struct iovec) kmalloc(sizeof(iov),GFP_KERNEL);
	sock_msg = (struct msghdr*) kmalloc(sizeof(struct msghdr),GFP_KERNEL);
	buffer=(char *)kmalloc((sizeof(char)*1024),GFP_KERNEL);
    
    printk(KERN_INFO "PHASE 1");
	if(a<0) 
	{
			printk(KERN_ERR "CREATE SOCKET ERROR");
			return -1;
	}

	memset(server_address,0, sizeof(struct sockaddr_in));
	//memset(newsocketfd,0, sizeof(struct socket));
	//memset(socketinfo,0, sizeof(struct socket));

    server_address->sin_family = AF_INET;
    server_address->sin_port = htons(PORT);
    server_address->sin_addr.s_addr =htonl(INADDR_ANY);
      
    //bind
    a = socketnumber1->ops->bind(socketnumber1,(struct sockaddr*)server_address,sizeof(struct sockaddr_in));
    
    //listen

    a = socketnumber1->ops->listen(socketnumber1,5);

    //accept

	iov.iov_base=buffer;
	size=SNDBUF;
	

	iov.iov_len=size;
	//sock_msg->msg_name= client_address;
	sock_msg->msg_namelen=sizeof(struct sockaddr_in);
	sock_msg->msg_iov=&iov;
	sock_msg->msg_iovlen=1;
	sock_msg->msg_control=NULL;
	sock_msg->msg_controllen=0;
	sock_msg->msg_flags=0;

 // 	size = SNDBUF;
	
	accepting1 = socketnumber1->ops->accept(socketnumber1,socketnumber2, 0);

	memset(&iov,0,sizeof(iov));
	memset(sock_msg,0,sizeof(struct msghdr));
	memset(buffer,0,SNDBUF);

  	if(accepting1 == -1)
	{
		printk(KERN_ERR "Error, accepting failed");
		 sock_release((struct socket *)socketnumber2);
		return -1;
	}
	if(accepting1 == 0 || accepting1 > 0)
	{
		//oldms = get_fs(); set_fs(KERNEL_DS);
		readvalue=sock_recvmsg(socketnumber2,sock_msg,size,0);
		//set_fs(oldms);
		if(readvalue < 0 )
        {
        	printk(KERN_ERR "Reading stream message error");
        	sock_release((struct socket *)socketnumber2);
        }
        else if (readvalue == 0)
        {
            printk(KERN_INFO"Reading connection\n");  
        }
        else
        {
        	printk(KERN_INFO "MESSSAGE: %s",buffer);
        }
        sock_release((struct socket *)socketnumber2);
	}
  

	 return 0;
}
示例#26
0
int
ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
{
        struct socket *sock = conn->ksnc_sock;
        int            nob;
        int            rc;

        if (*ksocknal_tunables.ksnd_enable_csum        && /* checksum enabled */
            conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection  */
            tx->tx_nob == tx->tx_resid                 && /* frist sending    */
            tx->tx_msg.ksm_csum == 0)                     /* not checksummed  */
                ksocknal_lib_csum_tx(tx);

        /* NB we can't trust socket ops to either consume our iovs
         * or leave them alone. */

        {
#if SOCKNAL_SINGLE_FRAG_TX
                struct iovec    scratch;
                struct iovec   *scratchiov = &scratch;
                unsigned int    niov = 1;
#else
                struct iovec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
                unsigned int    niov = tx->tx_niov;
#endif
                struct msghdr msg = {
                        .msg_name       = NULL,
                        .msg_namelen    = 0,
                        .msg_iov        = scratchiov,
                        .msg_iovlen     = niov,
                        .msg_control    = NULL,
                        .msg_controllen = 0,
                        .msg_flags      = MSG_DONTWAIT
                };
                mm_segment_t oldmm = get_fs();
                int  i;

                for (nob = i = 0; i < niov; i++) {
                        scratchiov[i] = tx->tx_iov[i];
                        nob += scratchiov[i].iov_len;
                }

                if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
                    nob < tx->tx_resid)
                        msg.msg_flags |= MSG_MORE;

                set_fs (KERNEL_DS);
                rc = sock_sendmsg(sock, &msg, nob);
                set_fs (oldmm);
        }
        return rc;
}

int
ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
{
        struct socket *sock = conn->ksnc_sock;
        lnet_kiov_t   *kiov = tx->tx_kiov;
        int            rc;
        int            nob;

        /* Not NOOP message */
        LASSERT (tx->tx_lnetmsg != NULL);

        /* NB we can't trust socket ops to either consume our iovs
         * or leave them alone. */
        if (tx->tx_msg.ksm_zc_cookies[0] != 0) {
                /* Zero copy is enabled */
                struct sock   *sk = sock->sk;
                struct page   *page = kiov->kiov_page;
                int            offset = kiov->kiov_offset;
                int            fragsize = kiov->kiov_len;
                int            msgflg = MSG_DONTWAIT;

                CDEBUG(D_NET, "page %p + offset %x for %d\n",
                               page, offset, kiov->kiov_len);

                if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
                    fragsize < tx->tx_resid)
                        msgflg |= MSG_MORE;

                if (sk->sk_prot->sendpage != NULL) {
                        rc = sk->sk_prot->sendpage(sk, page,
                                                   offset, fragsize, msgflg);
                } else {
                        rc = cfs_tcp_sendpage(sk, page, offset, fragsize,
                                              msgflg);
                }
        } else {
#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
                struct iovec  scratch;
                struct iovec *scratchiov = &scratch;
                unsigned int  niov = 1;
#else
#ifdef CONFIG_HIGHMEM
#warning "XXX risk of kmap deadlock on multiple frags..."
#endif
                struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
                unsigned int  niov = tx->tx_nkiov;
#endif
                struct msghdr msg = {
                        .msg_name       = NULL,
                        .msg_namelen    = 0,
                        .msg_iov        = scratchiov,
                        .msg_iovlen     = niov,
                        .msg_control    = NULL,
                        .msg_controllen = 0,
                        .msg_flags      = MSG_DONTWAIT
                };
                mm_segment_t  oldmm = get_fs();
                int           i;

                for (nob = i = 0; i < niov; i++) {
                        scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
                                                 kiov[i].kiov_offset;
                        nob += scratchiov[i].iov_len = kiov[i].kiov_len;
                }

                if (!cfs_list_empty(&conn->ksnc_tx_queue) ||
                    nob < tx->tx_resid)
                        msg.msg_flags |= MSG_MORE;

                set_fs (KERNEL_DS);
                rc = sock_sendmsg(sock, &msg, nob);
                set_fs (oldmm);

                for (i = 0; i < niov; i++)
                        kunmap(kiov[i].kiov_page);
        }
        return rc;
}

void
ksocknal_lib_eager_ack (ksock_conn_t *conn)
{
        int            opt = 1;
        mm_segment_t   oldmm = get_fs();
        struct socket *sock = conn->ksnc_sock;

        /* Remind the socket to ACK eagerly.  If I don't, the socket might
         * think I'm about to send something it could piggy-back the ACK
         * on, introducing delay in completing zero-copy sends in my
         * peer. */

        set_fs(KERNEL_DS);
        sock->ops->setsockopt (sock, SOL_TCP, TCP_QUICKACK,
                               (char *)&opt, sizeof (opt));
        set_fs(oldmm);
}

int
ksocknal_lib_recv_iov (ksock_conn_t *conn)
{
#if SOCKNAL_SINGLE_FRAG_RX
        struct iovec  scratch;
        struct iovec *scratchiov = &scratch;
        unsigned int  niov = 1;
#else
        struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
        unsigned int  niov = conn->ksnc_rx_niov;
#endif
        struct iovec *iov = conn->ksnc_rx_iov;
        struct msghdr msg = {
                .msg_name       = NULL,
                .msg_namelen    = 0,
                .msg_iov        = scratchiov,
                .msg_iovlen     = niov,
                .msg_control    = NULL,
                .msg_controllen = 0,
                .msg_flags      = 0
        };
        mm_segment_t oldmm = get_fs();
        int          nob;
        int          i;
        int          rc;
        int          fragnob;
        int          sum;
        __u32        saved_csum;

        /* NB we can't trust socket ops to either consume our iovs
         * or leave them alone. */
        LASSERT (niov > 0);

        for (nob = i = 0; i < niov; i++) {
                scratchiov[i] = iov[i];
                nob += scratchiov[i].iov_len;
        }
        LASSERT (nob <= conn->ksnc_rx_nob_wanted);

        set_fs (KERNEL_DS);
        rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
        /* NB this is just a boolean..........................^ */
        set_fs (oldmm);

        saved_csum = 0;
        if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
                saved_csum = conn->ksnc_msg.ksm_csum;
                conn->ksnc_msg.ksm_csum = 0;
        }

        if (saved_csum != 0) {
                /* accumulate checksum */
                for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
                        LASSERT (i < niov);

                        fragnob = iov[i].iov_len;
                        if (fragnob > sum)
                                fragnob = sum;

                        conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
                                                           iov[i].iov_base, fragnob);
                }
                conn->ksnc_msg.ksm_csum = saved_csum;
        }

        return rc;
}

static void
ksocknal_lib_kiov_vunmap(void *addr)
{
        if (addr == NULL)
                return;

        vunmap(addr);
}

static void *
ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
                       struct iovec *iov, struct page **pages)
{
        void             *addr;
        int               nob;
        int               i;

        if (!*ksocknal_tunables.ksnd_zc_recv || pages == NULL)
                return NULL;

        LASSERT (niov <= LNET_MAX_IOV);

        if (niov < 2 ||
            niov < *ksocknal_tunables.ksnd_zc_recv_min_nfrags)
                return NULL;

        for (nob = i = 0; i < niov; i++) {
                if ((kiov[i].kiov_offset != 0 && i > 0) ||
                    (kiov[i].kiov_offset + kiov[i].kiov_len != CFS_PAGE_SIZE && i < niov - 1))
                        return NULL;

                pages[i] = kiov[i].kiov_page;
                nob += kiov[i].kiov_len;
        }

        addr = vmap(pages, niov, VM_MAP, PAGE_KERNEL);
        if (addr == NULL)
                return NULL;

        iov->iov_base = addr + kiov[0].kiov_offset;
        iov->iov_len = nob;

        return addr;
}

int
ksocknal_lib_recv_kiov (ksock_conn_t *conn)
{
#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
        struct iovec   scratch;
        struct iovec  *scratchiov = &scratch;
        struct page  **pages      = NULL;
        unsigned int   niov       = 1;
#else
#ifdef CONFIG_HIGHMEM
#warning "XXX risk of kmap deadlock on multiple frags..."
#endif
        struct iovec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
        struct page  **pages      = conn->ksnc_scheduler->kss_rx_scratch_pgs;
        unsigned int   niov       = conn->ksnc_rx_nkiov;
#endif
        lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
        struct msghdr msg = {
                .msg_name       = NULL,
                .msg_namelen    = 0,
                .msg_iov        = scratchiov,
                .msg_control    = NULL,
                .msg_controllen = 0,
                .msg_flags      = 0
        };
        mm_segment_t oldmm = get_fs();
        int          nob;
        int          i;
        int          rc;
        void        *base;
        void        *addr;
        int          sum;
        int          fragnob;

        /* NB we can't trust socket ops to either consume our iovs
         * or leave them alone. */
        if ((addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages)) != NULL) {
                nob = scratchiov[0].iov_len;
                msg.msg_iovlen = 1;

        } else {
                for (nob = i = 0; i < niov; i++) {
                        nob += scratchiov[i].iov_len = kiov[i].kiov_len;
                        scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
                                                 kiov[i].kiov_offset;
                }
                msg.msg_iovlen = niov;
        }

        LASSERT (nob <= conn->ksnc_rx_nob_wanted);

        set_fs (KERNEL_DS);
        rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
        /* NB this is just a boolean.......................^ */
        set_fs (oldmm);

        if (conn->ksnc_msg.ksm_csum != 0) {
                for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
                        LASSERT (i < niov);

                        /* Dang! have to kmap again because I have nowhere to stash the
                         * mapped address.  But by doing it while the page is still
                         * mapped, the kernel just bumps the map count and returns me
                         * the address it stashed. */
                        base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
                        fragnob = kiov[i].kiov_len;
                        if (fragnob > sum)
                                fragnob = sum;

                        conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
                                                           base, fragnob);

                        kunmap(kiov[i].kiov_page);
                }
        }

        if (addr != NULL) {
                ksocknal_lib_kiov_vunmap(addr);
        } else {
                for (i = 0; i < niov; i++)
                        kunmap(kiov[i].kiov_page);
        }

        return (rc);
}

void
ksocknal_lib_csum_tx(ksock_tx_t *tx)
{
        int          i;
        __u32        csum;
        void        *base;

        LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
        LASSERT(tx->tx_conn != NULL);
        LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);

        tx->tx_msg.ksm_csum = 0;

        csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
                             tx->tx_iov[0].iov_len);

        if (tx->tx_kiov != NULL) {
                for (i = 0; i < tx->tx_nkiov; i++) {
                        base = kmap(tx->tx_kiov[i].kiov_page) +
                               tx->tx_kiov[i].kiov_offset;

                        csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);

                        kunmap(tx->tx_kiov[i].kiov_page);
                }
        } else {
                for (i = 1; i < tx->tx_niov; i++)
                        csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
                                             tx->tx_iov[i].iov_len);
        }

        if (*ksocknal_tunables.ksnd_inject_csum_error) {
                csum++;
                *ksocknal_tunables.ksnd_inject_csum_error = 0;
        }

        tx->tx_msg.ksm_csum = csum;
}

int
ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
{
        mm_segment_t   oldmm = get_fs ();
        struct socket *sock = conn->ksnc_sock;
        int            len;
        int            rc;

        rc = ksocknal_connsock_addref(conn);
        if (rc != 0) {
                LASSERT (conn->ksnc_closing);
                *txmem = *rxmem = *nagle = 0;
                return (-ESHUTDOWN);
        }

        rc = libcfs_sock_getbuf(sock, txmem, rxmem);
        if (rc == 0) {
                len = sizeof(*nagle);
                set_fs(KERNEL_DS);
                rc = sock->ops->getsockopt(sock, SOL_TCP, TCP_NODELAY,
                                           (char *)nagle, &len);
                set_fs(oldmm);
        }

        ksocknal_connsock_decref(conn);

        if (rc == 0)
                *nagle = !*nagle;
        else
                *txmem = *rxmem = *nagle = 0;

        return (rc);
}
示例#27
0
static int cpt_dump_route(struct cpt_context * ctx)
{
	int err;
	struct socket *sock;
	struct msghdr msg;
	struct iovec iov;
	struct {
		struct nlmsghdr nlh;
		struct rtgenmsg g;
	} req;
	struct sockaddr_nl nladdr;
	struct cpt_object_hdr v;
	mm_segment_t oldfs;
	char *pg;

	err = sock_create(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, &sock);
	if (err)
		return err;

	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;

	req.nlh.nlmsg_len = sizeof(req);
	req.nlh.nlmsg_type = RTM_GETROUTE;
	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
	req.nlh.nlmsg_pid = 0;
	req.g.rtgen_family = AF_INET;

	iov.iov_base=&req;
	iov.iov_len=sizeof(req);
	msg.msg_name=&nladdr;
	msg.msg_namelen=sizeof(nladdr);
	msg.msg_iov=&iov;
	msg.msg_iovlen=1;
	msg.msg_control=NULL;
	msg.msg_controllen=0;
	msg.msg_flags=MSG_DONTWAIT;

	oldfs = get_fs(); set_fs(KERNEL_DS);
	err = sock_sendmsg(sock, &msg, sizeof(req));
	set_fs(oldfs);

	if (err < 0)
		goto out_sock;

	pg = (char*)__get_free_page(GFP_KERNEL);
	if (pg == NULL) {
		err = -ENOMEM;
		goto out_sock;
	}

	cpt_open_section(ctx, CPT_SECT_NET_ROUTE);
	cpt_open_object(NULL, ctx);
	v.cpt_next = CPT_NULL;
	v.cpt_object = CPT_OBJ_NET_ROUTE;
	v.cpt_hdrlen = sizeof(v);
	v.cpt_content = CPT_CONTENT_NLMARRAY;

	ctx->write(&v, sizeof(v), ctx);

#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
restart:
#endif
	for (;;) {
		struct nlmsghdr *h;

		iov.iov_base = pg;
		iov.iov_len = PAGE_SIZE;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_recvmsg(sock, &msg, PAGE_SIZE, MSG_DONTWAIT);
		set_fs(oldfs);

		if (err < 0)
			goto out_sock_pg;
		if (msg.msg_flags & MSG_TRUNC) {
			err = -ENOBUFS;
			goto out_sock_pg;
		}

		h = (struct nlmsghdr*)pg;
		while (NLMSG_OK(h, err)) {
			if (h->nlmsg_type == NLMSG_DONE) {
				err = 0;
				goto done;
			}
			if (h->nlmsg_type == NLMSG_ERROR) {
				struct nlmsgerr *errm = (struct nlmsgerr*)NLMSG_DATA(h);
				err = errm->error;
				eprintk_ctx("NLMSG error: %d\n", errm->error);
				goto done;
			}
			if (h->nlmsg_type != RTM_NEWROUTE) {
				eprintk_ctx("NLMSG: %d\n", h->nlmsg_type);
				err = -EINVAL;
				goto done;
			}
			ctx->write(h, NLMSG_ALIGN(h->nlmsg_len), ctx);
			h = NLMSG_NEXT(h, err);
		}
		if (err) {
			eprintk_ctx("!!!Remnant of size %d %d %d\n", err, h->nlmsg_len, h->nlmsg_type);
			err = -EINVAL;
			break;
		}
	}
done:
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
	if (!err && req.g.rtgen_family == AF_INET) {
		req.g.rtgen_family = AF_INET6;
		iov.iov_base=&req;
		iov.iov_len=sizeof(req);
		msg.msg_name=&nladdr;
		msg.msg_namelen=sizeof(nladdr);
		msg.msg_iov=&iov;
		msg.msg_iovlen=1;
		msg.msg_control=NULL;
		msg.msg_controllen=0;
		msg.msg_flags=MSG_DONTWAIT;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = sock_sendmsg(sock, &msg, sizeof(req));
		set_fs(oldfs);

		if (err > 0)
			goto restart;
	}
#endif
	ctx->align(ctx);
	cpt_close_object(ctx);
	cpt_close_section(ctx);

out_sock_pg:
	free_page((unsigned long)pg);
out_sock:
	sock_release(sock);
	return err;
}