提交 ead592ba 编写于 作者: T Thomas Graf 提交者: David S. Miller

[IPv4] diag: Use netlink_run_queue() to process the receive queue

Makes use of netlink_run_queue() to process the receive queue and
converts inet_diag_rcv_msg() to use the type safe netlink interface.
Signed-off-by: NThomas Graf <tgraf@suug.ch>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 1d00a4eb
...@@ -806,68 +806,48 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -806,68 +806,48 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len; return skb->len;
} }
static inline int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{ {
if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) int hdrlen = sizeof(struct inet_diag_req);
return 0;
if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX) if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX ||
goto err_inval; nlmsg_len(nlh) < hdrlen)
return -EINVAL;
if (inet_diag_table[nlh->nlmsg_type] == NULL) if (inet_diag_table[nlh->nlmsg_type] == NULL)
return -ENOENT; return -ENOENT;
if (NLMSG_LENGTH(sizeof(struct inet_diag_req)) > skb->len) if (nlh->nlmsg_flags & NLM_F_DUMP) {
goto err_inval; int err;
if (nlh->nlmsg_flags&NLM_F_DUMP) {
if (nlh->nlmsg_len >
(4 + NLMSG_SPACE(sizeof(struct inet_diag_req)))) {
struct rtattr *rta = (void *)(NLMSG_DATA(nlh) +
sizeof(struct inet_diag_req));
if (rta->rta_type != INET_DIAG_REQ_BYTECODE ||
rta->rta_len < 8 ||
rta->rta_len >
(nlh->nlmsg_len -
NLMSG_SPACE(sizeof(struct inet_diag_req))))
goto err_inval;
if (inet_diag_bc_audit(RTA_DATA(rta), RTA_PAYLOAD(rta)))
goto err_inval;
}
return netlink_dump_start(idiagnl, skb, nlh,
inet_diag_dump, NULL);
} else
return inet_diag_get_exact(skb, nlh);
err_inval: if (nlmsg_attrlen(nlh, hdrlen)) {
return -EINVAL; struct nlattr *attr;
}
attr = nlmsg_find_attr(nlh, hdrlen,
INET_DIAG_REQ_BYTECODE);
if (attr == NULL ||
nla_len(attr) < sizeof(struct inet_diag_bc_op) ||
inet_diag_bc_audit(nla_data(attr), nla_len(attr)))
return -EINVAL;
}
static inline void inet_diag_rcv_skb(struct sk_buff *skb) err = netlink_dump_start(idiagnl, skb, nlh,
{ inet_diag_dump, NULL);
if (skb->len >= NLMSG_SPACE(0)) { if (err == 0)
int err; err = -EINTR;
struct nlmsghdr *nlh = nlmsg_hdr(skb); return err;
if (nlh->nlmsg_len < sizeof(*nlh) ||
skb->len < nlh->nlmsg_len)
return;
err = inet_diag_rcv_msg(skb, nlh);
if (err || nlh->nlmsg_flags & NLM_F_ACK)
netlink_ack(skb, nlh, err);
} }
return inet_diag_get_exact(skb, nlh);
} }
static void inet_diag_rcv(struct sock *sk, int len) static void inet_diag_rcv(struct sock *sk, int len)
{ {
struct sk_buff *skb; unsigned int qlen = 0;
unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) { do {
inet_diag_rcv_skb(skb); netlink_run_queue(sk, &qlen, &inet_diag_rcv_msg);
kfree_skb(skb); } while (qlen);
}
} }
static DEFINE_SPINLOCK(inet_diag_register_lock); static DEFINE_SPINLOCK(inet_diag_register_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册