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) |
