diff options
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 25 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 87 |
2 files changed, 49 insertions, 63 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 80828078733d..55ed979db144 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst) | |||
1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); | 1028 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); |
1029 | } | 1029 | } |
1030 | 1030 | ||
1031 | static void xfrm_dst_destroy(struct dst_entry *dst) | 1031 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
1032 | { | 1032 | { |
1033 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
1034 | |||
1035 | dst_release(xdst->route); | ||
1036 | |||
1037 | if (!dst->xfrm) | ||
1038 | return; | ||
1039 | xfrm_state_put(dst->xfrm); | ||
1040 | dst->xfrm = NULL; | ||
1041 | } | ||
1042 | |||
1043 | static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
1044 | int unregister) | ||
1045 | { | ||
1046 | if (!unregister) | ||
1047 | return; | ||
1048 | |||
1049 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { | 1033 | while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { |
1050 | dst->dev = &loopback_dev; | 1034 | dst->dev = &loopback_dev; |
1051 | dev_hold(&loopback_dev); | 1035 | dev_hold(&loopback_dev); |
1052 | dev_put(dev); | 1036 | dev_put(dev); |
1053 | } | 1037 | } |
1054 | } | 1038 | } |
1039 | EXPORT_SYMBOL(xfrm_dst_ifdown); | ||
1055 | 1040 | ||
1056 | static void xfrm_link_failure(struct sk_buff *skb) | 1041 | static void xfrm_link_failure(struct sk_buff *skb) |
1057 | { | 1042 | { |
@@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1262 | dst_ops->kmem_cachep = xfrm_dst_cache; | 1247 | dst_ops->kmem_cachep = xfrm_dst_cache; |
1263 | if (likely(dst_ops->check == NULL)) | 1248 | if (likely(dst_ops->check == NULL)) |
1264 | dst_ops->check = xfrm_dst_check; | 1249 | dst_ops->check = xfrm_dst_check; |
1265 | if (likely(dst_ops->destroy == NULL)) | ||
1266 | dst_ops->destroy = xfrm_dst_destroy; | ||
1267 | if (likely(dst_ops->ifdown == NULL)) | ||
1268 | dst_ops->ifdown = xfrm_dst_ifdown; | ||
1269 | if (likely(dst_ops->negative_advice == NULL)) | 1250 | if (likely(dst_ops->negative_advice == NULL)) |
1270 | dst_ops->negative_advice = xfrm_negative_advice; | 1251 | dst_ops->negative_advice = xfrm_negative_advice; |
1271 | if (likely(dst_ops->link_failure == NULL)) | 1252 | if (likely(dst_ops->link_failure == NULL)) |
@@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
1297 | xfrm_policy_afinfo[afinfo->family] = NULL; | 1278 | xfrm_policy_afinfo[afinfo->family] = NULL; |
1298 | dst_ops->kmem_cachep = NULL; | 1279 | dst_ops->kmem_cachep = NULL; |
1299 | dst_ops->check = NULL; | 1280 | dst_ops->check = NULL; |
1300 | dst_ops->destroy = NULL; | ||
1301 | dst_ops->ifdown = NULL; | ||
1302 | dst_ops->negative_advice = NULL; | 1281 | dst_ops->negative_advice = NULL; |
1303 | dst_ops->link_failure = NULL; | 1282 | dst_ops->link_failure = NULL; |
1304 | dst_ops->get_mss = NULL; | 1283 | dst_ops->get_mss = NULL; |
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) |