aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/linux/netfilter/nfnetlink.h2
-rw-r--r--include/net/netlink.h2
-rw-r--r--net/core/rtnetlink.c46
-rw-r--r--net/netfilter/nf_conntrack_netlink.c46
-rw-r--r--net/netfilter/nfnetlink.c26
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netlink/af_netlink.c21
-rw-r--r--net/netlink/genetlink.c56
-rw-r--r--net/xfrm/xfrm_user.c40
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 {
111struct nfnl_callback 111struct 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
215extern void netlink_run_queue(struct sock *sk, unsigned int *qlen, 215extern 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 *));
218extern void netlink_queue_skip(struct nlmsghdr *nlh, 218extern void netlink_queue_skip(struct nlmsghdr *nlh,
219 struct sk_buff *skb); 219 struct sk_buff *skb);
220extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, 220extern 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
855static __inline__ int 855static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
856rtnetlink_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
936err_inval: 922 return doit(skb, nlh, (void *)&rta_buf[0]);
937 *errp = -EINVAL;
938 return -1;
939} 923}
940 924
941static void rtnetlink_rcv(struct sock *sk, int len) 925static 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
662static int 662static int
663ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 663ctnetlink_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
710static int 710static int
711ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 711ctnetlink_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 }