diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 69 |
1 files changed, 6 insertions, 63 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index c35336a0f71b..0cdd9a07e043 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/net.h> | 19 | #include <linux/net.h> |
20 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> |
21 | #include <linux/netlink.h> | ||
22 | #include <linux/rtnetlink.h> | 21 | #include <linux/rtnetlink.h> |
23 | #include <linux/pfkeyv2.h> | 22 | #include <linux/pfkeyv2.h> |
24 | #include <linux/ipsec.h> | 23 | #include <linux/ipsec.h> |
@@ -26,6 +25,7 @@ | |||
26 | #include <linux/security.h> | 25 | #include <linux/security.h> |
27 | #include <net/sock.h> | 26 | #include <net/sock.h> |
28 | #include <net/xfrm.h> | 27 | #include <net/xfrm.h> |
28 | #include <net/netlink.h> | ||
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | 30 | ||
31 | static struct sock *xfrm_nl; | 31 | static struct sock *xfrm_nl; |
@@ -948,11 +948,6 @@ static struct xfrm_link { | |||
948 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, | 948 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, |
949 | }; | 949 | }; |
950 | 950 | ||
951 | static int xfrm_done(struct netlink_callback *cb) | ||
952 | { | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | 951 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) |
957 | { | 952 | { |
958 | struct rtattr *xfrma[XFRMA_MAX]; | 953 | struct rtattr *xfrma[XFRMA_MAX]; |
@@ -984,20 +979,15 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
984 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 979 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
985 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | 980 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && |
986 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | 981 | (nlh->nlmsg_flags & NLM_F_DUMP)) { |
987 | u32 rlen; | ||
988 | |||
989 | if (link->dump == NULL) | 982 | if (link->dump == NULL) |
990 | goto err_einval; | 983 | goto err_einval; |
991 | 984 | ||
992 | if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh, | 985 | if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh, |
993 | link->dump, | 986 | link->dump, NULL)) != 0) { |
994 | xfrm_done)) != 0) { | ||
995 | return -1; | 987 | return -1; |
996 | } | 988 | } |
997 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | 989 | |
998 | if (rlen > skb->len) | 990 | netlink_queue_skip(nlh, skb); |
999 | rlen = skb->len; | ||
1000 | skb_pull(skb, rlen); | ||
1001 | return -1; | 991 | return -1; |
1002 | } | 992 | } |
1003 | 993 | ||
@@ -1032,60 +1022,13 @@ err_einval: | |||
1032 | return -1; | 1022 | return -1; |
1033 | } | 1023 | } |
1034 | 1024 | ||
1035 | static int xfrm_user_rcv_skb(struct sk_buff *skb) | ||
1036 | { | ||
1037 | int err; | ||
1038 | struct nlmsghdr *nlh; | ||
1039 | |||
1040 | while (skb->len >= NLMSG_SPACE(0)) { | ||
1041 | u32 rlen; | ||
1042 | |||
1043 | nlh = (struct nlmsghdr *) skb->data; | ||
1044 | if (nlh->nlmsg_len < sizeof(*nlh) || | ||
1045 | skb->len < nlh->nlmsg_len) | ||
1046 | return 0; | ||
1047 | rlen = NLMSG_ALIGN(nlh->nlmsg_len); | ||
1048 | if (rlen > skb->len) | ||
1049 | rlen = skb->len; | ||
1050 | if (xfrm_user_rcv_msg(skb, nlh, &err) < 0) { | ||
1051 | if (err == 0) | ||
1052 | return -1; | ||
1053 | netlink_ack(skb, nlh, err); | ||
1054 | } else if (nlh->nlmsg_flags & NLM_F_ACK) | ||
1055 | netlink_ack(skb, nlh, 0); | ||
1056 | skb_pull(skb, rlen); | ||
1057 | } | ||
1058 | |||
1059 | return 0; | ||
1060 | } | ||
1061 | |||
1062 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1025 | static void xfrm_netlink_rcv(struct sock *sk, int len) |
1063 | { | 1026 | { |
1064 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | 1027 | unsigned int qlen = 0; |
1065 | 1028 | ||
1066 | do { | 1029 | do { |
1067 | struct sk_buff *skb; | ||
1068 | |||
1069 | down(&xfrm_cfg_sem); | 1030 | down(&xfrm_cfg_sem); |
1070 | 1031 | netlink_run_queue(sk, &qlen, &xfrm_user_rcv_msg); | |
1071 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) | ||
1072 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
1073 | |||
1074 | for (; qlen; qlen--) { | ||
1075 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
1076 | if (xfrm_user_rcv_skb(skb)) { | ||
1077 | if (skb->len) | ||
1078 | skb_queue_head(&sk->sk_receive_queue, | ||
1079 | skb); | ||
1080 | else { | ||
1081 | kfree_skb(skb); | ||
1082 | qlen--; | ||
1083 | } | ||
1084 | break; | ||
1085 | } | ||
1086 | kfree_skb(skb); | ||
1087 | } | ||
1088 | |||
1089 | up(&xfrm_cfg_sem); | 1032 | up(&xfrm_cfg_sem); |
1090 | 1033 | ||
1091 | } while (qlen); | 1034 | } while (qlen); |