2 * NETLINK Netlink attributes
4 * Authors: Thomas Graf <tgraf@suug.ch>
5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/jiffies.h>
12 #include <linux/netdevice.h>
13 #include <linux/skbuff.h>
14 #include <linux/string.h>
15 #include <linux/types.h>
16 #include <net/netlink.h>
20 * netlink_queue_skip - Skip netlink message while processing queue.
21 * @nlh: Netlink message to be skipped
22 * @skb: Socket buffer containing the netlink messages.
24 * Pulls the given netlink message off the socket buffer so the next
25 * call to netlink_queue_run() will not reconsider the message.
27 static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
29 int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
31 if (msglen > skb->len)
34 skb_pull(skb, msglen);
37 static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
43 while (skb->len >= nlmsg_total_size(0)) {
47 if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
50 /* Only requests are handled by the kernel */
51 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
54 /* Skip control messages */
55 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
60 /* Not an error, but we interrupt processing */
61 netlink_queue_skip(nlh, skb);
65 if (nlh->nlmsg_flags & NLM_F_ACK || err)
66 netlink_ack(skb, nlh, err);
68 netlink_queue_skip(nlh, skb);
75 * netlink_run_queue - Process netlink receive queue.
76 * @sk: Netlink socket containing the queue
77 * @qlen: Place to store queue length upon entry
78 * @cb: Callback function invoked for each netlink message found
80 * Processes as much as there was in the queue upon entry and invokes
81 * a callback function for each netlink message found. The callback
82 * function may refuse a message by returning a negative error code
83 * but setting the error pointer to 0 in which case this function
84 * returns with a qlen != 0.
86 * qlen must be initialized to 0 before the initial entry, afterwards
87 * the function may be called repeatedly until qlen reaches 0.
89 * The callback function may return -EINTR to signal that processing
90 * of netlink messages shall be interrupted. In this case the message
91 * currently being processed will NOT be requeued onto the receive
94 void netlink_run_queue(struct sock *sk, unsigned int *qlen,
95 int (*cb)(struct sk_buff *, struct nlmsghdr *))
99 if (!*qlen || *qlen > skb_queue_len(&sk->receive_queue))
100 *qlen = skb_queue_len(&sk->receive_queue);
102 for (; *qlen; (*qlen)--) {
103 skb = skb_dequeue(&sk->receive_queue);
104 if (netlink_rcv_skb(skb, cb)) {
106 skb_queue_head(&sk->receive_queue, skb);