aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c69
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
31static struct sock *xfrm_nl; 31static 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
951static int xfrm_done(struct netlink_callback *cb)
952{
953 return 0;
954}
955
956static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 951static 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
1035static 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
1062static void xfrm_netlink_rcv(struct sock *sk, int len) 1025static 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);