diff options
| author | Thomas Graf <tgraf@suug.ch> | 2007-03-23 02:30:12 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:27:30 -0400 |
| commit | 1d00a4eb42bdade33a6ec0961cada93577a66ae6 (patch) | |
| tree | a181b141818f594eb544601386bf09e45e6193bb | |
| parent | 45e7ae7f716086994e4e747226881f901c67b031 (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>
| -rw-r--r-- | include/linux/netfilter/nfnetlink.h | 2 | ||||
| -rw-r--r-- | include/net/netlink.h | 2 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 46 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 46 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink.c | 26 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_log.c | 4 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_queue.c | 6 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 21 | ||||
| -rw-r--r-- | net/netlink/genetlink.c | 56 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 40 |
10 files changed, 93 insertions, 156 deletions
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index e1ea5dfbbb..0f9311df15 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h | |||
| @@ -111,7 +111,7 @@ struct nfgenmsg { | |||
| 111 | struct nfnl_callback | 111 | struct nfnl_callback |
| 112 | { | 112 | { |
| 113 | int (*call)(struct sock *nl, struct sk_buff *skb, | 113 | int (*call)(struct sock *nl, struct sk_buff *skb, |
| 114 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp); | 114 | struct nlmsghdr *nlh, struct nfattr *cda[]); |
| 115 | u_int16_t attr_count; /* number of nfattr's */ | 115 | u_int16_t attr_count; /* number of nfattr's */ |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
diff --git a/include/net/netlink.h b/include/net/netlink.h index 510ca7fabe..1c11518fc8 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
| @@ -214,7 +214,7 @@ struct nl_info { | |||
| 214 | 214 | ||
| 215 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, | 215 | extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, |
| 216 | int (*cb)(struct sk_buff *, | 216 | int (*cb)(struct sk_buff *, |
| 217 | struct nlmsghdr *, int *)); | 217 | struct nlmsghdr *)); |
| 218 | extern void netlink_queue_skip(struct nlmsghdr *nlh, | 218 | extern void netlink_queue_skip(struct nlmsghdr *nlh, |
| 219 | struct sk_buff *skb); | 219 | struct sk_buff *skb); |
| 220 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, | 220 | extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b2136accd2..14241ada41 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -852,8 +852,7 @@ static int rtattr_max; | |||
| 852 | 852 | ||
| 853 | /* Process one rtnetlink message. */ | 853 | /* Process one rtnetlink message. */ |
| 854 | 854 | ||
| 855 | static __inline__ int | 855 | static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 856 | rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | ||
| 857 | { | 856 | { |
| 858 | rtnl_doit_func doit; | 857 | rtnl_doit_func doit; |
| 859 | int sz_idx, kind; | 858 | int sz_idx, kind; |
| @@ -863,10 +862,8 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 863 | int err; | 862 | int err; |
| 864 | 863 | ||
| 865 | type = nlh->nlmsg_type; | 864 | type = nlh->nlmsg_type; |
| 866 | |||
| 867 | /* Unknown message: reply with EINVAL */ | ||
| 868 | if (type > RTM_MAX) | 865 | if (type > RTM_MAX) |
| 869 | goto err_inval; | 866 | return -EINVAL; |
| 870 | 867 | ||
| 871 | type -= RTM_BASE; | 868 | type -= RTM_BASE; |
| 872 | 869 | ||
| @@ -875,40 +872,33 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 875 | return 0; | 872 | return 0; |
| 876 | 873 | ||
| 877 | family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; | 874 | family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; |
| 878 | if (family >= NPROTO) { | 875 | if (family >= NPROTO) |
| 879 | *errp = -EAFNOSUPPORT; | 876 | return -EAFNOSUPPORT; |
| 880 | return -1; | ||
| 881 | } | ||
| 882 | 877 | ||
| 883 | sz_idx = type>>2; | 878 | sz_idx = type>>2; |
| 884 | kind = type&3; | 879 | kind = type&3; |
| 885 | 880 | ||
| 886 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) { | 881 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) |
| 887 | *errp = -EPERM; | 882 | return -EPERM; |
| 888 | return -1; | ||
| 889 | } | ||
| 890 | 883 | ||
| 891 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 884 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
| 892 | rtnl_dumpit_func dumpit; | 885 | rtnl_dumpit_func dumpit; |
| 893 | 886 | ||
| 894 | dumpit = rtnl_get_dumpit(family, type); | 887 | dumpit = rtnl_get_dumpit(family, type); |
| 895 | if (dumpit == NULL) | 888 | if (dumpit == NULL) |
| 896 | goto err_inval; | 889 | return -EINVAL; |
| 897 | |||
| 898 | if ((*errp = netlink_dump_start(rtnl, skb, nlh, | ||
| 899 | dumpit, NULL)) != 0) { | ||
| 900 | return -1; | ||
| 901 | } | ||
| 902 | 890 | ||
| 903 | netlink_queue_skip(nlh, skb); | 891 | err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); |
| 904 | return -1; | 892 | if (err == 0) |
| 893 | err = -EINTR; | ||
| 894 | return err; | ||
| 905 | } | 895 | } |
| 906 | 896 | ||
| 907 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); | 897 | memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); |
| 908 | 898 | ||
| 909 | min_len = rtm_min[sz_idx]; | 899 | min_len = rtm_min[sz_idx]; |
| 910 | if (nlh->nlmsg_len < min_len) | 900 | if (nlh->nlmsg_len < min_len) |
| 911 | goto err_inval; | 901 | return -EINVAL; |
| 912 | 902 | ||
| 913 | if (nlh->nlmsg_len > min_len) { | 903 | if (nlh->nlmsg_len > min_len) { |
| 914 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | 904 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); |
| @@ -918,7 +908,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 918 | unsigned flavor = attr->rta_type; | 908 | unsigned flavor = attr->rta_type; |
| 919 | if (flavor) { | 909 | if (flavor) { |
| 920 | if (flavor > rta_max[sz_idx]) | 910 | if (flavor > rta_max[sz_idx]) |
| 921 | goto err_inval; | 911 | return -EINVAL; |
| 922 | rta_buf[flavor-1] = attr; | 912 | rta_buf[flavor-1] = attr; |
| 923 | } | 913 | } |
| 924 | attr = RTA_NEXT(attr, attrlen); | 914 | attr = RTA_NEXT(attr, attrlen); |
| @@ -927,15 +917,9 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | |||
| 927 | 917 | ||
| 928 | doit = rtnl_get_doit(family, type); | 918 | doit = rtnl_get_doit(family, type); |
| 929 | if (doit == NULL) | 919 | if (doit == NULL) |
| 930 | goto err_inval; | 920 | return -EINVAL; |
| 931 | err = doit(skb, nlh, (void *)&rta_buf[0]); | ||
| 932 | |||
| 933 | *errp = err; | ||
| 934 | return err; | ||
| 935 | 921 | ||
| 936 | err_inval: | 922 | return doit(skb, nlh, (void *)&rta_buf[0]); |
| 937 | *errp = -EINVAL; | ||
| 938 | return -1; | ||
| 939 | } | 923 | } |
| 940 | 924 | ||
| 941 | static void rtnetlink_rcv(struct sock *sk, int len) | 925 | static void rtnetlink_rcv(struct sock *sk, int len) |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 76f11f3259..443ba7753a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -661,7 +661,7 @@ static const size_t cta_min[CTA_MAX] = { | |||
| 661 | 661 | ||
| 662 | static int | 662 | static int |
| 663 | ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | 663 | ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, |
| 664 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) | 664 | struct nlmsghdr *nlh, struct nfattr *cda[]) |
| 665 | { | 665 | { |
| 666 | struct nf_conntrack_tuple_hash *h; | 666 | struct nf_conntrack_tuple_hash *h; |
| 667 | struct nf_conntrack_tuple tuple; | 667 | struct nf_conntrack_tuple tuple; |
| @@ -709,7 +709,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 709 | 709 | ||
| 710 | static int | 710 | static int |
| 711 | ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | 711 | ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, |
| 712 | struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) | 712 | struct nlmsghdr *nlh, struct nfattr *cda[]) |
| 713 | { | 713 | { |
| 714 | struct nf_conntrack_tuple_hash *h; | 714 | struct nf_conntrack_tuple_hash *h; |
| 715 | struct nf_conntrack_tuple tuple; | 715 | struct nf_conntrack_tuple tuple; |
| @@ -720,22 +720,15 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 720 | int err = 0; | 720 | int err = 0; |
| 721 | 721 | ||
| 722 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 722 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
| 723 | u32 rlen; | ||
| 724 | |||
| 725 | #ifndef CONFIG_NF_CT_ACCT | 723 | #ifndef CONFIG_NF_CT_ACCT |
| 726 | if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) | 724 | if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) |
| 727 | return -ENOTSUPP; | 725 | return -ENOTSUPP; |
| 728 | #endif | 726 | #endif |
| 729 | if ((*errp = netlink_dump_start(ctnl, skb, nlh, | 727 | err = netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, |
| 730 | ctnetlink_dump_table, | 728 | ctnetlink_done); |
| 731 | ctnetlink_done)) != 0) | 729 | if (err == 0) |
| 732 | return -EINVAL; | 730 | err = -EINTR; |
| 733 | 731 | return err; | |
| 734 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | ||
| 735 | if (rlen > skb->len) | ||
| 736 | rlen = skb->len; | ||
| 737 | skb_pull(skb, rlen); | ||
| 738 | return 0; | ||
| 739 | } | ||
