diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
| -rw-r--r-- | net/xfrm/xfrm_user.c | 87 |
1 files changed, 47 insertions, 40 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 63661b0fd736..5ddda2c98af9 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -855,47 +855,44 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x | |||
| 855 | return 0; | 855 | return 0; |
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { | 858 | #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) |
| 859 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */ | 859 | |
| 860 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */ | 860 | static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { |
| 861 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */ | 861 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
| 862 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */ | 862 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
| 863 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */ | 863 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), |
| 864 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */ | 864 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
| 865 | NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ | 865 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
| 866 | NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ | 866 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
| 867 | NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ | 867 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), |
| 868 | NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ | 868 | [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), |
| 869 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ | 869 | [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), |
| 870 | NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */ | 870 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
| 871 | NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */ | 871 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
| 872 | NLMSG_LENGTH(0), /* FLUSH POLICY */ | 872 | [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), |
| 873 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), | ||
| 874 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), | ||
| 873 | }; | 875 | }; |
| 874 | 876 | ||
| 877 | #undef XMSGSIZE | ||
| 878 | |||
| 875 | static struct xfrm_link { | 879 | static struct xfrm_link { |
| 876 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); | 880 | int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); |
| 877 | int (*dump)(struct sk_buff *, struct netlink_callback *); | 881 | int (*dump)(struct sk_buff *, struct netlink_callback *); |
| 878 | } xfrm_dispatch[] = { | 882 | } xfrm_dispatch[XFRM_NR_MSGTYPES] = { |
| 879 | { .doit = xfrm_add_sa, }, | 883 | [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
| 880 | { .doit = xfrm_del_sa, }, | 884 | [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, |
| 881 | { | 885 | [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, |
| 882 | .doit = xfrm_get_sa, | 886 | .dump = xfrm_dump_sa }, |
| 883 | .dump = xfrm_dump_sa, | 887 | [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
| 884 | }, | 888 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, |
| 885 | { .doit = xfrm_add_policy }, | 889 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, |
| 886 | { .doit = xfrm_get_policy }, | 890 | .dump = xfrm_dump_policy }, |
| 887 | { | 891 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, |
| 888 | .doit = xfrm_get_policy, | 892 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
| 889 | .dump = xfrm_dump_policy, | 893 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
| 890 | }, | 894 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, |
| 891 | { .doit = xfrm_alloc_userspi }, | 895 | [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, |
| 892 | {}, | ||
| 893 | {}, | ||
| 894 | { .doit = xfrm_add_policy }, | ||
| 895 | { .doit = xfrm_add_sa, }, | ||
| 896 | {}, | ||
| 897 | { .doit = xfrm_flush_sa }, | ||
| 898 | { .doit = xfrm_flush_policy }, | ||
| 899 | }; | 896 | }; |
| 900 | 897 | ||
| 901 | static int xfrm_done(struct netlink_callback *cb) | 898 | static int xfrm_done(struct netlink_callback *cb) |
| @@ -931,7 +928,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
| 931 | return -1; | 928 | return -1; |
| 932 | } | 929 | } |
| 933 | 930 | ||
| 934 | if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { | 931 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
| 932 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | ||
| 933 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | ||
| 935 | u32 rlen; | 934 | u32 rlen; |
| 936 | 935 | ||
| 937 | if (link->dump == NULL) | 936 | if (link->dump == NULL) |
| @@ -1009,18 +1008,26 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb) | |||
| 1009 | 1008 | ||
| 1010 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1009 | static void xfrm_netlink_rcv(struct sock *sk, int len) |
| 1011 | { | 1010 | { |
| 1011 | unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); | ||
| 1012 | |||
| 1012 | do { | 1013 | do { |
| 1013 | struct sk_buff *skb; | 1014 | struct sk_buff *skb; |
| 1014 | 1015 | ||
| 1015 | down(&xfrm_cfg_sem); | 1016 | down(&xfrm_cfg_sem); |
| 1016 | 1017 | ||
| 1017 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 1018 | if (qlen > skb_queue_len(&sk->sk_receive_queue)) |
| 1019 | qlen = skb_queue_len(&sk->sk_receive_queue); | ||
| 1020 | |||
| 1021 | for (; qlen; qlen--) { | ||
| 1022 | skb = skb_dequeue(&sk->sk_receive_queue); | ||
| 1018 | if (xfrm_user_rcv_skb(skb)) { | 1023 | if (xfrm_user_rcv_skb(skb)) { |
| 1019 | if (skb->len) | 1024 | if (skb->len) |
| 1020 | skb_queue_head(&sk->sk_receive_queue, | 1025 | skb_queue_head(&sk->sk_receive_queue, |
| 1021 | skb); | 1026 | skb); |
| 1022 | else | 1027 | else { |
| 1023 | kfree_skb(skb); | 1028 | kfree_skb(skb); |
| 1029 | qlen--; | ||
| 1030 | } | ||
| 1024 | break; | 1031 | break; |
| 1025 | } | 1032 | } |
| 1026 | kfree_skb(skb); | 1033 | kfree_skb(skb); |
| @@ -1028,7 +1035,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len) | |||
| 1028 | 1035 | ||
| 1029 | up(&xfrm_cfg_sem); | 1036 | up(&xfrm_cfg_sem); |
| 1030 | 1037 | ||
| 1031 | } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen); | 1038 | } while (qlen); |
| 1032 | } | 1039 | } |
| 1033 | 1040 | ||
| 1034 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) | 1041 | static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) |
