aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2007-03-23 02:30:12 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:27:30 -0400
commit1d00a4eb42bdade33a6ec0961cada93577a66ae6 (patch)
treea181b141818f594eb544601386bf09e45e6193bb /net/netlink
parent45e7ae7f716086994e4e747226881f901c67b031 (diff)
[NETLINK]: Remove error pointer from netlink message handler
The error pointer argument in netlink message handlers is used to signal the special case where processing has to be interrupted because a dump was started but no error happened. Instead it is simpler and more clear to return -EINTR and have netlink_run_queue() deal with getting the queue right. nfnetlink passed on this error pointer to its subsystem handlers but only uses it to signal the start of a netlink dump. Therefore it can be removed there as well. This patch also cleans up the error handling in the affected message handlers to be consistent since it had to be touched anyway. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c21
-rw-r--r--net/netlink/genetlink.c56
2 files changed, 32 insertions, 45 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 5d1079b1838c..1823b7c63156 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1463,7 +1463,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1463} 1463}
1464 1464
1465static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, 1465static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1466 struct nlmsghdr *, int *)) 1466 struct nlmsghdr *))
1467{ 1467{
1468 struct nlmsghdr *nlh; 1468 struct nlmsghdr *nlh;
1469 int err; 1469 int err;
@@ -1483,13 +1483,11 @@ static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1483 if (nlh->nlmsg_type < NLMSG_MIN_TYPE) 1483 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
1484 goto skip; 1484 goto skip;
1485 1485
1486 if (cb(skb, nlh, &err) < 0) { 1486 err = cb(skb, nlh);
1487 /* Not an error, but we have to interrupt processing 1487 if (err == -EINTR) {
1488 * here. Note: that in this case we do not pull 1488 /* Not an error, but we interrupt processing */
1489 * message from skb, it will be processed later. 1489 netlink_queue_skip(nlh, skb);
1490 */ 1490 return err;
1491 if (err == 0)
1492 return -1;
1493 } 1491 }
1494skip: 1492skip:
1495 if (nlh->nlmsg_flags & NLM_F_ACK || err) 1493 if (nlh->nlmsg_flags & NLM_F_ACK || err)
@@ -1515,9 +1513,14 @@ skip:
1515 * 1513 *
1516 * qlen must be initialized to 0 before the initial entry, afterwards 1514 * qlen must be initialized to 0 before the initial entry, afterwards
1517 * the function may be called repeatedly until qlen reaches 0. 1515 * the function may be called repeatedly until qlen reaches 0.
1516 *
1517 * The callback function may return -EINTR to signal that processing
1518 * of netlink messages shall be interrupted. In this case the message
1519 * currently being processed will NOT be requeued onto the receive
1520 * queue.
1518 */ 1521 */
1519void netlink_run_queue(struct sock *sk, unsigned int *qlen, 1522void netlink_run_queue(struct sock *sk, unsigned int *qlen,
1520 int (*cb)(struct sk_buff *, struct nlmsghdr *, int *)) 1523 int (*cb)(struct sk_buff *, struct nlmsghdr *))
1521{ 1524{
1522 struct sk_buff *skb; 1525 struct sk_buff *skb;
1523 1526
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 95391e609046..1b897bc92e61 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -295,60 +295,49 @@ int genl_unregister_family(struct genl_family *family)
295 return -ENOENT; 295 return -ENOENT;
296} 296}
297 297
298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
299 int *errp)
300{ 299{
301 struct genl_ops *ops; 300 struct genl_ops *ops;
302 struct genl_family *family; 301 struct genl_family *family;
303 struct genl_info info; 302 struct genl_info info;
304 struct genlmsghdr *hdr = nlmsg_data(nlh); 303 struct genlmsghdr *hdr = nlmsg_data(nlh);
305 int hdrlen, err = -EINVAL; 304 int hdrlen, err;
306 305
307 family = genl_family_find_byid(nlh->nlmsg_type); 306 family = genl_family_find_byid(nlh->nlmsg_type);
308 if (family == NULL) { 307 if (family == NULL)
309 err = -ENOENT; 308 return -ENOENT;
310 goto errout;
311 }
312 309
313 hdrlen = GENL_HDRLEN + family->hdrsize; 310 hdrlen = GENL_HDRLEN + family->hdrsize;
314 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 311 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
315 goto errout; 312 return -EINVAL;
316 313
317 ops = genl_get_cmd(hdr->cmd, family); 314 ops = genl_get_cmd(hdr->cmd, family);
318 if (ops == NULL) { 315 if (ops == NULL)
319 err = -EOPNOTSUPP; 316 return -EOPNOTSUPP;
320 goto errout;
321 }
322 317
323 if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb, CAP_NET_ADMIN)) { 318 if ((ops->flags & GENL_ADMIN_PERM) &&
324 err = -EPERM; 319 security_netlink_recv(skb, CAP_NET_ADMIN))
325 goto errout; 320 return -EPERM;
326 }
327 321
328 if (nlh->nlmsg_flags & NLM_F_DUMP) { 322 if (nlh->nlmsg_flags & NLM_F_DUMP) {
329 if (ops->dumpit == NULL) { 323 if (ops->dumpit == NULL)
330 err = -EOPNOTSUPP; 324 return -EOPNOTSUPP;
331 goto errout;
332 }
333 325
334 *errp = err = netlink_dump_start(genl_sock, skb, nlh, 326 err = netlink_dump_start(genl_sock, skb, nlh,
335 ops->dumpit, ops->done); 327 ops->dumpit, ops->done);
336 if (err == 0) 328 if (err == 0)
337 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len), 329 err = -EINTR;
338 skb->len)); 330 return err;
339 return -1;
340 } 331 }
341 332
342 if (ops->doit == NULL) { 333 if (ops->doit == NULL)
343 err = -EOPNOTSUPP; 334 return -EOPNOTSUPP;
344 goto errout;
345 }
346 335
347 if (family->attrbuf) { 336 if (family->attrbuf) {
348 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr, 337 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
349 ops->policy); 338 ops->policy);
350 if (err < 0) 339 if (err < 0)
351 goto errout; 340 return err;
352 } 341 }
353 342
354 info.snd_seq = nlh->nlmsg_seq; 343 info.snd_seq = nlh->nlmsg_seq;
@@ -358,12 +347,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
358 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 347 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
359 info.attrs = family->attrbuf; 348 info.attrs = family->attrbuf;
360 349
361 *errp = err = ops->doit(skb, &info); 350 return ops->doit(skb, &info);
362 return err;
363
364errout:
365 *errp = err;
366 return -1;
367} 351}
368 352
369static void genl_rcv(struct sock *sk, int len) 353static void genl_rcv(struct sock *sk, int len)