aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c25
-rw-r--r--net/xfrm/xfrm_user.c87
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
1031static void xfrm_dst_destroy(struct dst_entry *dst) 1031void 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
1043static 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}
1039EXPORT_SYMBOL(xfrm_dst_ifdown);
1055 1040
1056static void xfrm_link_failure(struct sk_buff *skb) 1041static 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
858static 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 */ 860static 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
875static struct xfrm_link { 879static 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
901static int xfrm_done(struct netlink_callback *cb) 898static 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
1010static void xfrm_netlink_rcv(struct sock *sk, int len) 1009static 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
1034static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard) 1041static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard)