static void netlink_data_ready(struct sock *sk, int len) { struct netlink_opt *nlk = nlk_sk(sk); if (nlk->data_ready) nlk->data_ready(sk, len); netlink_rcv_wake(sk); }
static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) { struct sock_iocb *siocb = kiocb_to_siocb(kiocb); struct scm_cookie scm; struct sock *sk = sock->sk; struct netlink_opt *nlk = nlk_sk(sk); int noblock = flags&MSG_DONTWAIT; size_t 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_pad = 0; addr->nl_pid = NETLINK_CB(skb).pid; addr->nl_groups = NETLINK_CB(skb).dst_groups; msg->msg_namelen = sizeof(*addr); } if (NULL == siocb->scm) { memset(&scm, 0, sizeof(scm)); siocb->scm = &scm; } siocb->scm->creds = *NETLINK_CREDS(skb); skb_free_datagram(sk, skb); if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) netlink_dump(sk); scm_recv(sock, msg, siocb->scm, flags); out: netlink_rcv_wake(sk); return err ? : copied; }
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: netlink_rcv_wake(sk); return err ? : copied; }
void netlink_data_ready(struct sock *sk, int len) { if (sk->protinfo.af_netlink->data_ready) sk->protinfo.af_netlink->data_ready(sk, len); netlink_rcv_wake(sk); }