aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-04-12 13:50:03 -0400
committerPaul Mackerras <paulus@samba.org>2007-04-12 13:50:03 -0400
commite049d1ca3094f3d1d94617f456a9961202f96e3a (patch)
treea30397ad22f2fbea268bd28fa69c60aad9dfa62a /net/xfrm
parentedfac96a92b88d3b0b53e3f8231b74beee9ecd1d (diff)
parent80584ff3b99c36ead7e130e453b3a48b18072d18 (diff)
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c20
-rw-r--r--net/xfrm/xfrm_state.c9
-rw-r--r--net/xfrm/xfrm_user.c26
3 files changed, 35 insertions, 20 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 946b715db5ec..785c3e39f062 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -735,12 +735,14 @@ EXPORT_SYMBOL(xfrm_policy_insert);
735 735
736struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, 736struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
737 struct xfrm_selector *sel, 737 struct xfrm_selector *sel,
738 struct xfrm_sec_ctx *ctx, int delete) 738 struct xfrm_sec_ctx *ctx, int delete,
739 int *err)
739{ 740{
740 struct xfrm_policy *pol, *ret; 741 struct xfrm_policy *pol, *ret;
741 struct hlist_head *chain; 742 struct hlist_head *chain;
742 struct hlist_node *entry; 743 struct hlist_node *entry;
743 744
745 *err = 0;
744 write_lock_bh(&xfrm_policy_lock); 746 write_lock_bh(&xfrm_policy_lock);
745 chain = policy_hash_bysel(sel, sel->family, dir); 747 chain = policy_hash_bysel(sel, sel->family, dir);
746 ret = NULL; 748 ret = NULL;
@@ -750,6 +752,11 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
750 xfrm_sec_ctx_match(ctx, pol->security)) { 752 xfrm_sec_ctx_match(ctx, pol->security)) {
751 xfrm_pol_hold(pol); 753 xfrm_pol_hold(pol);
752 if (delete) { 754 if (delete) {
755 *err = security_xfrm_policy_delete(pol);
756 if (*err) {
757 write_unlock_bh(&xfrm_policy_lock);
758 return pol;
759 }
753 hlist_del(&pol->bydst); 760 hlist_del(&pol->bydst);
754 hlist_del(&pol->byidx); 761 hlist_del(&pol->byidx);
755 xfrm_policy_count[dir]--; 762 xfrm_policy_count[dir]--;
@@ -768,12 +775,14 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
768} 775}
769EXPORT_SYMBOL(xfrm_policy_bysel_ctx); 776EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
770 777
771struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete) 778struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
779 int *err)
772{ 780{
773 struct xfrm_policy *pol, *ret; 781 struct xfrm_policy *pol, *ret;
774 struct hlist_head *chain; 782 struct hlist_head *chain;
775 struct hlist_node *entry; 783 struct hlist_node *entry;
776 784
785 *err = 0;
777 write_lock_bh(&xfrm_policy_lock); 786 write_lock_bh(&xfrm_policy_lock);
778 chain = xfrm_policy_byidx + idx_hash(id); 787 chain = xfrm_policy_byidx + idx_hash(id);
779 ret = NULL; 788 ret = NULL;
@@ -781,6 +790,11 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
781 if (pol->type == type && pol->index == id) { 790 if (pol->type == type && pol->index == id) {
782 xfrm_pol_hold(pol); 791 xfrm_pol_hold(pol);
783 if (delete) { 792 if (delete) {
793 *err = security_xfrm_policy_delete(pol);
794 if (*err) {
795 write_unlock_bh(&xfrm_policy_lock);
796 return pol;
797 }
784 hlist_del(&pol->bydst); 798 hlist_del(&pol->bydst);
785 hlist_del(&pol->byidx); 799 hlist_del(&pol->byidx);
786 xfrm_policy_count[dir]--; 800 xfrm_policy_count[dir]--;
@@ -2075,7 +2089,7 @@ void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
2075 sizeof(struct in6_addr)); 2089 sizeof(struct in6_addr));
2076 } 2090 }
2077 audit_log_format(audit_buf, 2091 audit_log_format(audit_buf,
2078 " src=" NIP6_FMT "dst=" NIP6_FMT, 2092 " src=" NIP6_FMT " dst=" NIP6_FMT,
2079 NIP6(saddr6), NIP6(daddr6)); 2093 NIP6(saddr6), NIP6(daddr6));
2080 } 2094 }
2081 break; 2095 break;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index a35f9e4ede26..e3a0bcfa5df1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -704,7 +704,8 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
704 x->props.mode != mode || 704 x->props.mode != mode ||
705 x->props.family != family || 705 x->props.family != family ||
706 x->km.state != XFRM_STATE_ACQ || 706 x->km.state != XFRM_STATE_ACQ ||
707 x->id.spi != 0) 707 x->id.spi != 0 ||
708 x->id.proto != proto)
708 continue; 709 continue;
709 710
710 switch (family) { 711 switch (family) {
@@ -801,7 +802,8 @@ int xfrm_state_add(struct xfrm_state *x)
801 802
802 if (use_spi && x->km.seq) { 803 if (use_spi && x->km.seq) {
803 x1 = __xfrm_find_acq_byseq(x->km.seq); 804 x1 = __xfrm_find_acq_byseq(x->km.seq);
804 if (x1 && xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family)) { 805 if (x1 && ((x1->id.proto != x->id.proto) ||
806 xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
805 xfrm_state_put(x1); 807 xfrm_state_put(x1);
806 x1 = NULL; 808 x1 = NULL;
807 } 809 }
@@ -1369,7 +1371,8 @@ int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
1369 return 0; 1371 return 0;
1370 1372
1371 diff = x->replay.seq - seq; 1373 diff = x->replay.seq - seq;
1372 if (diff >= x->props.replay_window) { 1374 if (diff >= min_t(unsigned int, x->props.replay_window,
1375 sizeof(x->replay.bitmap) * 8)) {
1373 x->stats.replay_window++; 1376 x->stats.replay_window++;
1374 return -EINVAL; 1377 return -EINVAL;
1375 } 1378 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 956cfe0ff7f8..e81e2fb3d429 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -530,9 +530,6 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
530 530
531 err = xfrm_state_delete(x); 531 err = xfrm_state_delete(x);
532 532
533 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
534 AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
535
536 if (err < 0) 533 if (err < 0)
537 goto out; 534 goto out;
538 535
@@ -542,6 +539,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
542 km_state_notify(x, &c); 539 km_state_notify(x, &c);
543 540
544out: 541out:
542 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
543 AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
545 xfrm_state_put(x); 544 xfrm_state_put(x);
546 return err; 545 return err;
547} 546}
@@ -1254,7 +1253,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1254 return err; 1253 return err;
1255 1254
1256 if (p->index) 1255 if (p->index)
1257 xp = xfrm_policy_byid(type, p->dir, p->index, delete); 1256 xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
1258 else { 1257 else {
1259 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; 1258 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
1260 struct xfrm_policy tmp; 1259 struct xfrm_policy tmp;
@@ -1270,7 +1269,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1270 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1269 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
1271 return err; 1270 return err;
1272 } 1271 }
1273 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); 1272 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
1273 delete, &err);
1274 security_xfrm_policy_free(&tmp); 1274 security_xfrm_policy_free(&tmp);
1275 } 1275 }
1276 if (xp == NULL) 1276 if (xp == NULL)
@@ -1288,8 +1288,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1288 MSG_DONTWAIT); 1288 MSG_DONTWAIT);
1289 } 1289 }
1290 } else { 1290 } else {
1291 err = security_xfrm_policy_delete(xp);
1292
1293 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, 1291 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1294 AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); 1292 AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
1295 1293
@@ -1303,9 +1301,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1303 km_policy_notify(xp, p->dir, &c); 1301 km_policy_notify(xp, p->dir, &c);
1304 } 1302 }
1305 1303
1306 xfrm_pol_put(xp);
1307
1308out: 1304out:
1305 xfrm_pol_put(xp);
1309 return err; 1306 return err;
1310} 1307}
1311 1308
@@ -1502,7 +1499,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1502 return err; 1499 return err;
1503 1500
1504 if (p->index) 1501 if (p->index)
1505 xp = xfrm_policy_byid(type, p->dir, p->index, 0); 1502 xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
1506 else { 1503 else {
1507 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; 1504 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
1508 struct xfrm_policy tmp; 1505 struct xfrm_policy tmp;
@@ -1518,13 +1515,14 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1518 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1515 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
1519 return err; 1516 return err;
1520 } 1517 }
1521 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0); 1518 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
1519 0, &err);
1522 security_xfrm_policy_free(&tmp); 1520 security_xfrm_policy_free(&tmp);
1523 } 1521 }
1524 1522
1525 if (xp == NULL) 1523 if (xp == NULL)
1526 return err; 1524 return -ENOENT;
1527 read_lock(&xp->lock); 1525 read_lock(&xp->lock);
1528 if (xp->dead) { 1526 if (xp->dead) {
1529 read_unlock(&xp->lock); 1527 read_unlock(&xp->lock);
1530 goto out; 1528 goto out;
@@ -2027,7 +2025,7 @@ nlmsg_failure:
2027 return -1; 2025 return -1;
2028} 2026}
2029 2027
2030static int inline xfrm_sa_len(struct xfrm_state *x) 2028static inline int xfrm_sa_len(struct xfrm_state *x)
2031{ 2029{
2032 int l = 0; 2030 int l = 0;
2033 if (x->aalg) 2031 if (x->aalg)