本文整理汇总了C++中skb_free_datagram函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_free_datagram函数的具体用法?C++ skb_free_datagram怎么用?C++ skb_free_datagram使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了skb_free_datagram函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: raw_recvmsg
static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
struct sk_buff *skb;
int rxmtu;
int err = 0;
int noblock;
noblock = flags & MSG_DONTWAIT;
flags &= ~MSG_DONTWAIT;
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
return err;
/*
* when serving a legacy socket the DLC <= 8 is already checked inside
* raw_rcv(). Now check if we need to pass a canfd_frame to a legacy
* socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU
*/
if (!ro->fd_frames)
rxmtu = CAN_MTU;
else
rxmtu = skb->len;
if (size < rxmtu)
msg->msg_flags |= MSG_TRUNC;
else
size = rxmtu;
err = memcpy_toiovec(msg->msg_iov, skb->data, size);
if (err < 0) {
skb_free_datagram(sk, skb);
return err;
}
sock_recv_ts_and_drops(msg, sk, skb);
if (msg->msg_name) {
msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
/* assign the flags that have been recorded in raw_rcv() */
msg->msg_flags |= *(raw_flags(skb));
skb_free_datagram(sk, skb);
return size;
}
开发者ID:AiWinters,项目名称:linux,代码行数:52,代码来源:raw.c
示例2: rawsock_recvmsg
static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
{
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
struct sk_buff *skb;
int copied;
int rc;
nfc_dbg("sock=%p sk=%p len=%zu flags=%d", sock, sk, len, flags);
skb = skb_recv_datagram(sk, flags, noblock, &rc);
if (!skb)
return rc;
msg->msg_namelen = 0;
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
skb_free_datagram(sk, skb);
return rc ? : copied;
}
开发者ID:Andrew-Gazizov,项目名称:linux-3.2.1-kpp,代码行数:29,代码来源:rawsock.c
示例3: raw_recvmsg
int raw_recvmsg(struct sock *sk, struct msghdr *msg, int len,
int noblock, int flags,int *addr_len)
{
int copied=0;
struct sk_buff *skb;
int err;
struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
if (flags & MSG_OOB)
return -EOPNOTSUPP;
if (sk->shutdown & RCV_SHUTDOWN)
return(0);
if (addr_len)
*addr_len=sizeof(*sin);
skb=skb_recv_datagram(sk,flags,noblock,&err);
if(skb==NULL)
return err;
copied = min(len, skb->len);
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
sk->stamp=skb->stamp;
/* Copy the address. */
if (sin)
{
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = skb->daddr;
}
skb_free_datagram(sk, skb);
return (copied);
}
开发者ID:liexusong,项目名称:linux2.0-comment,代码行数:35,代码来源:raw.c
示例4: hci_sock_recvmsg
static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
{
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
struct sk_buff *skb;
int copied, err;
BT_DBG("sock %p, sk %p", sock, sk);
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
if (sk->state == BT_CLOSED)
return 0;
if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
return err;
msg->msg_namelen = 0;
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
skb->h.raw = skb->data;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
hci_sock_cmsg(sk, msg, skb);
skb_free_datagram(sk, skb);
return err ? : copied;
}
开发者ID:ProjectZeroSlackr,项目名称:linux-2.4.32-ipod,代码行数:35,代码来源:hci_sock.c
示例5: raw_recvmsg
static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len)
{
struct inet_sock *inet = inet_sk(sk);
size_t copied = 0;
int err = -EOPNOTSUPP;
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
struct sk_buff *skb;
if (flags & MSG_OOB)
goto out;
if (addr_len)
*addr_len = sizeof(*sin);
if (flags & MSG_ERRQUEUE) {
err = ip_recv_error(sk, msg, len);
goto out;
}
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
goto out;
if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) {
err = -EAGAIN; /* Hope less harmful than -EPERM. */
goto out;
}
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err)
goto done;
sock_recv_ts_and_drops(msg, sk, skb);
/* Copy the address. */
if (sin) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
sin->sin_port = 0;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
}
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
if (flags & MSG_TRUNC)
copied = skb->len;
done:
skb_free_datagram(sk, skb);
out:
if (err)
return err;
return copied;
}
开发者ID:Fechinator,项目名称:FechdaKernel_V500,代码行数:58,代码来源:raw.c
示例6: pep_recvmsg
static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len)
{
struct sk_buff *skb;
int err;
if (flags & ~(MSG_OOB|MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_WAITALL|
MSG_NOSIGNAL|MSG_CMSG_COMPAT))
return -EOPNOTSUPP;
if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE)))
return -ENOTCONN;
if ((flags & MSG_OOB) || sock_flag(sk, SOCK_URGINLINE)) {
/* Dequeue and acknowledge control request */
struct pep_sock *pn = pep_sk(sk);
if (flags & MSG_PEEK)
return -EOPNOTSUPP;
skb = skb_dequeue(&pn->ctrlreq_queue);
if (skb) {
pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR,
GFP_KERNEL);
msg->msg_flags |= MSG_OOB;
goto copy;
}
if (flags & MSG_OOB)
return -EINVAL;
}
skb = skb_recv_datagram(sk, flags, noblock, &err);
lock_sock(sk);
if (skb == NULL) {
if (err == -ENOTCONN && sk->sk_state == TCP_CLOSE_WAIT)
err = -ECONNRESET;
release_sock(sk);
return err;
}
if (sk->sk_state == TCP_ESTABLISHED)
pipe_grant_credits(sk);
release_sock(sk);
copy:
msg->msg_flags |= MSG_EOR;
if (skb->len > len)
msg->msg_flags |= MSG_TRUNC;
else
len = skb->len;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
if (!err)
err = (flags & MSG_TRUNC) ? skb->len : len;
skb_free_datagram(sk, skb);
return err;
}
开发者ID:flwh,项目名称:Alcatel_OT_985_kernel,代码行数:57,代码来源:pep.c
示例7: raw_recvmsg
static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
int error = 0;
int noblock;
DBG("socket %p, sk %p\n", sock, sk);
noblock = flags & MSG_DONTWAIT;
flags &= ~MSG_DONTWAIT;
skb = skb_recv_datagram(sk, flags, noblock, &error);
if (!skb)
return error;
DBG("delivering skbuff %p\n", skb);
DBG_SKB(skb);
if (size < skb->len)
msg->msg_flags |= MSG_TRUNC;
else
size = skb->len;
error = memcpy_toiovec(msg->msg_iov, skb->data, size);
if (error < 0) {
skb_free_datagram(sk, skb);
return error;
}
sock_recv_timestamp(msg, sk, skb);
if (msg->msg_name) {
msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
DBG("freeing sock %p, skbuff %p\n", sk, skb);
skb_free_datagram(sk, skb);
return size;
}
开发者ID:BackupTheBerlios,项目名称:socketcan-svn,代码行数:43,代码来源:raw.c
示例8: svc_udp_recvfrom
/*
* Receive a datagram from a UDP socket.
*/
static int
svc_udp_recvfrom(struct svc_rqst *rqstp)
{
struct svc_sock *svsk = rqstp->rq_sock;
struct svc_serv *serv = svsk->sk_server;
struct sk_buff *skb;
u32 *data;
int err, len;
svsk->sk_data = 0;
while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
svc_sock_received(svsk, 0);
if (err == -EAGAIN)
return err;
/* possibly an icmp error */
dprintk("svc: recvfrom returned error %d\n", -err);
}
if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
unsigned int csum = skb->csum;
csum = csum_partial(skb->h.raw, skb->len, csum);
if ((unsigned short)csum_fold(csum)) {
skb_free_datagram(svsk->sk_sk, skb);
svc_sock_received(svsk, 0);
return 0;
}
}
/* There may be more data */
svsk->sk_data = 1;
len = skb->len - sizeof(struct udphdr);
data = (u32 *) (skb->h.raw + sizeof(struct udphdr));
rqstp->rq_skbuff = skb;
rqstp->rq_argbuf.base = data;
rqstp->rq_argbuf.buf = data;
rqstp->rq_argbuf.len = (len >> 2);
/* rqstp->rq_resbuf = rqstp->rq_defbuf; */
rqstp->rq_prot = IPPROTO_UDP;
/* Get sender address */
rqstp->rq_addr.sin_family = AF_INET;
rqstp->rq_addr.sin_port = skb->h.uh->source;
rqstp->rq_addr.sin_addr.s_addr = skb->nh.iph->saddr;
if (serv->sv_stats)
serv->sv_stats->netudpcnt++;
/* One down, maybe more to go... */
svsk->sk_sk->stamp = skb->stamp;
svc_sock_received(svsk, 0);
return len;
}
开发者ID:dmgerman,项目名称:original,代码行数:58,代码来源:svcsock.c
示例9: netlink_recvmsg
static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, int len,
int flags, struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
int noblock = flags&MSG_DONTWAIT;
int copied;
struct sk_buff *skb;
int err;
if (flags&MSG_OOB)
return -EOPNOTSUPP;
copied = 0;
skb = skb_recv_datagram(sk,flags,noblock,&err);
if (skb==NULL)
goto out;
msg->msg_namelen = 0;
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
skb->h.raw = skb->data;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (msg->msg_name) {
struct sockaddr_nl *addr = (struct sockaddr_nl*)msg->msg_name;
addr->nl_family = AF_NETLINK;
addr->nl_pid = NETLINK_CB(skb).pid;
addr->nl_groups = NETLINK_CB(skb).dst_groups;
msg->msg_namelen = sizeof(*addr);
}
scm->creds = *NETLINK_CREDS(skb);
skb_free_datagram(sk, skb);
if (sk->protinfo.af_netlink->cb
&& atomic_read(&sk->rmem_alloc) <= sk->rcvbuf/2)
netlink_dump(sk);
out:
if (skb_queue_len(&sk->receive_queue) <= sk->rcvbuf/2) {
if (skb_queue_len(&sk->receive_queue) == 0)
clear_bit(0, &sk->protinfo.af_netlink->state);
if (!test_bit(0, &sk->protinfo.af_netlink->state))
wake_up_interruptible(&sk->protinfo.af_netlink->wait);
}
return err ? : copied;
}
开发者ID:liexusong,项目名称:Linux-2.4.16,代码行数:53,代码来源:af_netlink.c
示例10: svc_release_skb
/*
* Release an skbuff after use
*/
static inline void
svc_release_skb(struct svc_rqst *rqstp)
{
struct sk_buff *skb = rqstp->rq_skbuff;
if (!skb)
return;
rqstp->rq_skbuff = NULL;
dprintk("svc: service %p, releasing skb %p\n", rqstp, skb);
skb_free_datagram(rqstp->rq_sock->sk_sk, skb);
}
开发者ID:muromec,项目名称:linux-ezxdev,代码行数:15,代码来源:svcsock.c
示例11: raw_recvmsg
static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
int err = 0;
int noblock;
noblock = flags & MSG_DONTWAIT;
flags &= ~MSG_DONTWAIT;
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
return err;
if (size < skb->len)
msg->msg_flags |= MSG_TRUNC;
else
size = skb->len;
err = memcpy_toiovec(msg->msg_iov, skb->data, size);
if (err < 0) {
skb_free_datagram(sk, skb);
return err;
}
sock_recv_ts_and_drops(msg, sk, skb);
if (msg->msg_name) {
msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
/* assign the flags that have been recorded in raw_rcv() */
msg->msg_flags |= *(raw_flags(skb));
skb_free_datagram(sk, skb);
return size;
}
开发者ID:33d,项目名称:linux-2.6.21-hh20,代码行数:40,代码来源:raw.c
示例12: pn_recvmsg
static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len)
{
struct sk_buff *skb = NULL;
struct sockaddr_pn sa;
int rval = -EOPNOTSUPP;
int copylen;
if (flags & ~(MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_NOSIGNAL|
MSG_CMSG_COMPAT))
goto out_nofree;
if (addr_len)
*addr_len = sizeof(sa);
skb = skb_recv_datagram(sk, flags, noblock, &rval);
if (skb == NULL)
goto out_nofree;
pn_skb_get_src_sockaddr(skb, &sa);
copylen = skb->len;
if (len < copylen) {
msg->msg_flags |= MSG_TRUNC;
copylen = len;
}
rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
if (rval) {
rval = -EFAULT;
goto out;
}
rval = (flags & MSG_TRUNC) ? skb->len : copylen;
if (msg->msg_name != NULL)
memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
#ifdef CONFIG_SAMSUNG_PHONE_SVNET
/* svent RX debugging */
if (sk->sk_receive_queue.qlen > 30)
// printk(KERN_DEBUG "svn %s, sk = %p, qlen = %d\n", __func__, sk,
;
#endif
out:
skb_free_datagram(sk, skb);
out_nofree:
return rval;
}
开发者ID:nos1609,项目名称:Chrono_Kernel-1,代码行数:52,代码来源:datagram.c
示例13: rawv6_recvmsg
int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
int noblock, int flags, int *addr_len)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)msg->msg_name;
struct sk_buff *skb;
int copied, err;
if (flags & MSG_OOB)
return -EOPNOTSUPP;
if (addr_len)
*addr_len=sizeof(*sin6);
if (flags & MSG_ERRQUEUE)
return ipv6_recv_error(sk, msg, len);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
goto out;
copied = skb->tail - skb->h.raw;
if (copied > len) {
copied = len;
msg->msg_flags |= MSG_TRUNC;
}
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
sk->stamp=skb->stamp;
if (err)
goto out_free;
/* Copy the address. */
if (sin6) {
sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
sizeof(struct in6_addr));
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
sin6->sin6_scope_id =
((struct inet6_skb_parm *) skb->cb)->iif;
}
if (sk->net_pinfo.af_inet6.rxopt.all)
datagram_recv_ctl(sk, msg, skb);
err = copied;
out_free:
skb_free_datagram(sk, skb);
out:
return err;
}
开发者ID:GNUHurdTR,项目名称:hurd,代码行数:52,代码来源:raw_ipv6.c
示例14: svc_release_skb
/*
* Release an skbuff after use
*/
static void svc_release_skb(struct svc_rqst *rqstp)
{
struct sk_buff *skb = rqstp->rq_xprt_ctxt;
if (skb) {
struct svc_sock *svsk =
container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
rqstp->rq_xprt_ctxt = NULL;
dprintk("svc: service %p, releasing skb %p\n", rqstp, skb);
skb_free_datagram(svsk->sk_sk, skb);
}
}
开发者ID:458941968,项目名称:mini2440-kernel-2.6.29,代码行数:16,代码来源:svcsock.c
示例15: raw_recvmsg
static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len)
{
struct inet_sock *inet = inet_sk(sk);
size_t copied = 0;
int err = -EOPNOTSUPP;
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
struct sk_buff *skb;
if (flags & MSG_OOB)
goto out;
if (addr_len)
*addr_len = sizeof(*sin);
if (flags & MSG_ERRQUEUE) {
err = ip_recv_error(sk, msg, len);
goto out;
}
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
goto out;
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
copied = len;
}
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err)
goto done;
sock_recv_timestamp(msg, sk, skb);
/* Copy the address. */
if (sin) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = skb->nh.iph->saddr;
memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
}
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
if (flags & MSG_TRUNC)
copied = skb->len;
done:
skb_free_datagram(sk, skb);
out: return err ? err : copied;
}
开发者ID:OpenHMR,项目名称:Open-HMR600,代码行数:50,代码来源:raw.c
示例16: raw_recvmsg
static int raw_recvmsg(struct socket *sock, struct msghdr *msg, int size,
int flags, struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
int err = 0;
int noblock;
noblock = flags & MSG_DONTWAIT;
flags &= ~MSG_DONTWAIT;
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
return err;
if (size < skb->len)
msg->msg_flags |= MSG_TRUNC;
else
size = skb->len;
err = memcpy_toiovec(msg->msg_iov, skb->data, size);
if (err < 0) {
skb_free_datagram(sk, skb);
return err;
}
sock_recv_timestamp(msg, sk, skb);
if (msg->msg_name) {
msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
}
skb_free_datagram(sk, skb);
return size;
}
开发者ID:hermixy,项目名称:SocketCAN,代码行数:37,代码来源:raw.c
示例17: pn_recvmsg
static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len, int noblock,
int flags, int *addr_len)
{
struct sk_buff *skb = NULL;
struct sockaddr_pn sa;
int rval = -EOPNOTSUPP;
int copylen;
if (flags & ~(MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT|MSG_NOSIGNAL|
MSG_CMSG_COMPAT))
goto out_nofree;
skb = skb_recv_datagram(sk, flags, noblock, &rval);
if (skb == NULL)
goto out_nofree;
pn_skb_get_src_sockaddr(skb, &sa);
copylen = skb->len;
if (len < copylen) {
msg->msg_flags |= MSG_TRUNC;
copylen = len;
}
rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
if (rval) {
rval = -EFAULT;
goto out;
}
rval = (flags & MSG_TRUNC) ? skb->len : copylen;
if (msg->msg_name != NULL) {
__sockaddr_check_size(sizeof(sa));
memcpy(msg->msg_name, &sa, sizeof(sa));
*addr_len = sizeof(sa);
}
out:
skb_free_datagram(sk, skb);
out_nofree:
return rval;
}
开发者ID:3null,项目名称:linux,代码行数:45,代码来源:datagram.c
示例18: skb_kill_datagram
int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
{
int err = 0;
if (flags & MSG_PEEK) {
err = -ENOENT;
spin_lock_bh(&sk->sk_receive_queue.lock);
if (skb == skb_peek(&sk->sk_receive_queue)) {
__skb_unlink(skb, &sk->sk_receive_queue);
atomic_dec(&skb->users);
err = 0;
}
spin_unlock_bh(&sk->sk_receive_queue.lock);
}
skb_free_datagram(sk, skb);
return err;
}
开发者ID:johnny,项目名称:CobraDroidBeta,代码行数:18,代码来源:datagram.c
示例19: udpv6_recvmsg
int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
int noblock, int flags, int *addr_len)
{
struct sk_buff *skb;
int copied, err;
if (addr_len)
*addr_len=sizeof(struct sockaddr_in6);
if (flags & MSG_ERRQUEUE)
return ipv6_recv_error(sk, msg, len);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
goto out;
copied = skb->len - sizeof(struct udphdr);
if (copied > len) {
copied = len;
msg->msg_flags |= MSG_TRUNC;
}
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else if (msg->msg_flags&MSG_TRUNC) {
if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
goto csum_copy_err;
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else {
err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
if (err == -EINVAL)
goto csum_copy_err;
}
if (err)
goto out_free;
sock_recv_timestamp(msg, sk, skb);
/* Copy the address. */
if (msg->msg_name) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *) msg->msg_name;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = skb->h.uh->source;
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
if (skb->protocol == __constant_htons(ETH_P_IP)) {
ipv6_addr_set(&sin6->sin6_addr, 0, 0,
__constant_htonl(0xffff), skb->nh.iph->saddr);
if (sk->protinfo.af_inet.cmsg_flags)
ip_cmsg_recv(msg, skb);
} else {
memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr,
sizeof(struct in6_addr));
if (sk->net_pinfo.af_inet6.rxopt.all)
datagram_recv_ctl(sk, msg, skb);
if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
sin6->sin6_scope_id = opt->iif;
}
}
}
err = copied;
out_free:
skb_free_datagram(sk, skb);
out:
return err;
csum_copy_err:
/* Clear queue. */
if (flags&MSG_PEEK) {
int clear = 0;
spin_lock_irq(&sk->receive_queue.lock);
if (skb == skb_peek(&sk->receive_queue)) {
__skb_unlink(skb, &sk->receive_queue);
clear = 1;
}
spin_unlock_irq(&sk->receive_queue.lock);
if (clear)
kfree_skb(skb);
}
/* Error for blocking case is chosen to masquerade
as some normal condition.
*/
err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
UDP6_INC_STATS_USER(UdpInErrors);
goto out_free;
}
开发者ID:kevin-longkai,项目名称:edimax-br-6528n,代码行数:95,代码来源:udp.c
示例20: mptp_recvmsg
static int
mptp_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
{
struct sk_buff *skb;
struct sockaddr_mptp *mptp_addr;
struct sock *sk = sock->sk;
int err, copied;
int i;
struct sockaddr_mptp *ret_addr = (struct sockaddr_mptp *)msg->msg_name;
ret_addr->count = 0;
log_debug("Trying to receive sock=%p sk=%p flags=%d\n", sock, sk,
flags);
skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
if (unlikely(!skb)) {
log_error("skb_recv_datagram failed with %d\n", err);
goto out;
}
for (i = 0; i < msg->msg_iovlen; i++) {
log_debug("Received skb %p\n", skb);
mptp_addr = (struct sockaddr_mptp *)skb->cb;
copied = skb->len;
if (copied > msg->msg_iov[i].iov_len) {
copied = msg->msg_iov[i].iov_len;
msg->msg_flags |= MSG_TRUNC;
}
err = skb_copy_datagram_iovec(skb, 0, &msg->msg_iov[i], copied);
if (unlikely(err)) {
log_error("skb_copy_datagram_iovec\n");
goto out_free;
}
log_debug("Received %d bytes\n", copied);
sock_recv_ts_and_drops(msg, sk, skb);
if (ret_addr) {
memcpy(&ret_addr->dests[i], &mptp_addr->dests[0],
sizeof(ret_addr->dests[i]));
ret_addr->dests[i].bytes = copied;
}
err = copied;
out_free:
skb_free_datagram(sk, skb);
if (i == msg->msg_iovlen - 1)
break;
skb = skb_recv_datagram(sk, flags, 1, &err);
if (likely(err == -EAGAIN)) {
log_debug("No more skbs in the queue, returning...\n");
err = copied;
break;
}
}
ret_addr->count = i + 1;
msg->msg_namelen =
sizeof(struct sockaddr_mptp) + (i + 1) * sizeof(struct mptp_dest);
out:
return err;
}
开发者ID:paulvlase,项目名称:mptp,代码行数:70,代码来源:mptp.c
注:本文中的skb_free_datagram函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论