diff options
| author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
| commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
| tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /net/xfrm | |
| parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
| parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) | |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'net/xfrm')
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 101 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 19 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 26 |
3 files changed, 104 insertions, 42 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2a7861661f14..7736b23c3f03 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -883,30 +883,32 @@ out: | |||
| 883 | } | 883 | } |
| 884 | EXPORT_SYMBOL(xfrm_policy_walk); | 884 | EXPORT_SYMBOL(xfrm_policy_walk); |
| 885 | 885 | ||
| 886 | /* Find policy to apply to this flow. */ | 886 | /* |
| 887 | 887 | * Find policy to apply to this flow. | |
| 888 | * | ||
| 889 | * Returns 0 if policy found, else an -errno. | ||
| 890 | */ | ||
| 888 | static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, | 891 | static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, |
| 889 | u8 type, u16 family, int dir) | 892 | u8 type, u16 family, int dir) |
| 890 | { | 893 | { |
| 891 | struct xfrm_selector *sel = &pol->selector; | 894 | struct xfrm_selector *sel = &pol->selector; |
| 892 | int match; | 895 | int match, ret = -ESRCH; |
| 893 | 896 | ||
| 894 | if (pol->family != family || | 897 | if (pol->family != family || |
| 895 | pol->type != type) | 898 | pol->type != type) |
| 896 | return 0; | 899 | return ret; |
| 897 | 900 | ||
| 898 | match = xfrm_selector_match(sel, fl, family); | 901 | match = xfrm_selector_match(sel, fl, family); |
| 899 | if (match) { | 902 | if (match) |
| 900 | if (!security_xfrm_policy_lookup(pol, fl->secid, dir)) | 903 | ret = security_xfrm_policy_lookup(pol, fl->secid, dir); |
| 901 | return 1; | ||
| 902 | } | ||
| 903 | 904 | ||
| 904 | return 0; | 905 | return ret; |
| 905 | } | 906 | } |
| 906 | 907 | ||
| 907 | static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | 908 | static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, |
| 908 | u16 family, u8 dir) | 909 | u16 family, u8 dir) |
| 909 | { | 910 | { |
| 911 | int err; | ||
| 910 | struct xfrm_policy *pol, *ret; | 912 | struct xfrm_policy *pol, *ret; |
| 911 | xfrm_address_t *daddr, *saddr; | 913 | xfrm_address_t *daddr, *saddr; |
| 912 | struct hlist_node *entry; | 914 | struct hlist_node *entry; |
| @@ -922,7 +924,15 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | |||
| 922 | chain = policy_hash_direct(daddr, saddr, family, dir); | 924 | chain = policy_hash_direct(daddr, saddr, family, dir); |
| 923 | ret = NULL; | 925 | ret = NULL; |
| 924 | hlist_for_each_entry(pol, entry, chain, bydst) { | 926 | hlist_for_each_entry(pol, entry, chain, bydst) { |
| 925 | if (xfrm_policy_match(pol, fl, type, family, dir)) { | 927 | err = xfrm_policy_match(pol, fl, type, family, dir); |
| 928 | if (err) { | ||
| 929 | if (err == -ESRCH) | ||
| 930 | continue; | ||
| 931 | else { | ||
| 932 | ret = ERR_PTR(err); | ||
| 933 | goto fail; | ||
| 934 | } | ||
| 935 | } else { | ||
| 926 | ret = pol; | 936 | ret = pol; |
| 927 | priority = ret->priority; | 937 | priority = ret->priority; |
| 928 | break; | 938 | break; |
| @@ -930,36 +940,53 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | |||
| 930 | } | 940 | } |
| 931 | chain = &xfrm_policy_inexact[dir]; | 941 | chain = &xfrm_policy_inexact[dir]; |
| 932 | hlist_for_each_entry(pol, entry, chain, bydst) { | 942 | hlist_for_each_entry(pol, entry, chain, bydst) { |
| 933 | if (xfrm_policy_match(pol, fl, type, family, dir) && | 943 | err = xfrm_policy_match(pol, fl, type, family, dir); |
| 934 | pol->priority < priority) { | 944 | if (err) { |
| 945 | if (err == -ESRCH) | ||
| 946 | continue; | ||
| 947 | else { | ||
| 948 | ret = ERR_PTR(err); | ||
| 949 | goto fail; | ||
| 950 | } | ||
| 951 | } else if (pol->priority < priority) { | ||
| 935 | ret = pol; | 952 | ret = pol; |
| 936 | break; | 953 | break; |
| 937 | } | 954 | } |
| 938 | } | 955 | } |
| 939 | if (ret) | 956 | if (ret) |
| 940 | xfrm_pol_hold(ret); | 957 | xfrm_pol_hold(ret); |
| 958 | fail: | ||
| 941 | read_unlock_bh(&xfrm_policy_lock); | 959 | read_unlock_bh(&xfrm_policy_lock); |
| 942 | 960 | ||
| 943 | return ret; | 961 | return ret; |
| 944 | } | 962 | } |
| 945 | 963 | ||
| 946 | static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | 964 | static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, |
| 947 | void **objp, atomic_t **obj_refp) | 965 | void **objp, atomic_t **obj_refp) |
| 948 | { | 966 | { |
| 949 | struct xfrm_policy *pol; | 967 | struct xfrm_policy *pol; |
| 968 | int err = 0; | ||
| 950 | 969 | ||
| 951 | #ifdef CONFIG_XFRM_SUB_POLICY | 970 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 952 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); | 971 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); |
| 953 | if (pol) | 972 | if (IS_ERR(pol)) { |
| 973 | err = PTR_ERR(pol); | ||
| 974 | pol = NULL; | ||
| 975 | } | ||
| 976 | if (pol || err) | ||
| 954 | goto end; | 977 | goto end; |
| 955 | #endif | 978 | #endif |
| 956 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); | 979 | pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); |
| 957 | 980 | if (IS_ERR(pol)) { | |
| 981 | err = PTR_ERR(pol); | ||
| 982 | pol = NULL; | ||
| 983 | } | ||
| 958 | #ifdef CONFIG_XFRM_SUB_POLICY | 984 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 959 | end: | 985 | end: |
| 960 | #endif | 986 | #endif |
| 961 | if ((*objp = (void *) pol) != NULL) | 987 | if ((*objp = (void *) pol) != NULL) |
| 962 | *obj_refp = &pol->refcnt; | 988 | *obj_refp = &pol->refcnt; |
| 989 | return err; | ||
| 963 | } | 990 | } |
| 964 | 991 | ||
| 965 | static inline int policy_to_flow_dir(int dir) | 992 | static inline int policy_to_flow_dir(int dir) |
| @@ -989,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
| 989 | sk->sk_family); | 1016 | sk->sk_family); |
| 990 | int err = 0; | 1017 | int err = 0; |
| 991 | 1018 | ||
| 992 | if (match) | 1019 | if (match) { |
| 993 | err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); | 1020 | err = security_xfrm_policy_lookup(pol, fl->secid, |
| 994 | 1021 | policy_to_flow_dir(dir)); | |
| 995 | if (match && !err) | 1022 | if (!err) |
| 996 | xfrm_pol_hold(pol); | 1023 | xfrm_pol_hold(pol); |
| 997 | else | 1024 | else if (err == -ESRCH) |
| 1025 | pol = NULL; | ||
| 1026 | else | ||
| 1027 | pol = ERR_PTR(err); | ||
| 1028 | } else | ||
| 998 | pol = NULL; | 1029 | pol = NULL; |
| 999 | } | 1030 | } |
| 1000 | read_unlock_bh(&xfrm_policy_lock); | 1031 | read_unlock_bh(&xfrm_policy_lock); |
| @@ -1286,8 +1317,11 @@ restart: | |||
| 1286 | pol_dead = 0; | 1317 | pol_dead = 0; |
| 1287 | xfrm_nr = 0; | 1318 | xfrm_nr = 0; |
| 1288 | 1319 | ||
| 1289 | if (sk && sk->sk_policy[1]) | 1320 | if (sk && sk->sk_policy[1]) { |
| 1290 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | 1321 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); |
| 1322 | if (IS_ERR(policy)) | ||
| 1323 | return PTR_ERR(policy); | ||
| 1324 | } | ||
| 1291 | 1325 | ||
| 1292 | if (!policy) { | 1326 | if (!policy) { |
| 1293 | /* To accelerate a bit... */ | 1327 | /* To accelerate a bit... */ |
| @@ -1297,6 +1331,8 @@ restart: | |||
| 1297 | 1331 | ||
| 1298 | policy = flow_cache_lookup(fl, dst_orig->ops->family, | 1332 | policy = flow_cache_lookup(fl, dst_orig->ops->family, |
| 1299 | dir, xfrm_policy_lookup); | 1333 | dir, xfrm_policy_lookup); |
| 1334 | if (IS_ERR(policy)) | ||
| 1335 | return PTR_ERR(policy); | ||
| 1300 | } | 1336 | } |
| 1301 | 1337 | ||
| 1302 | if (!policy) | 1338 | if (!policy) |
| @@ -1343,6 +1379,10 @@ restart: | |||
| 1343 | fl, family, | 1379 | fl, family, |
| 1344 | XFRM_POLICY_OUT); | 1380 | XFRM_POLICY_OUT); |
| 1345 | if (pols[1]) { | 1381 | if (pols[1]) { |
| 1382 | if (IS_ERR(pols[1])) { | ||
| 1383 | err = PTR_ERR(pols[1]); | ||
| 1384 | goto error; | ||
| 1385 | } | ||
| 1346 | if (pols[1]->action == XFRM_POLICY_BLOCK) { | 1386 | if (pols[1]->action == XFRM_POLICY_BLOCK) { |
| 1347 | err = -EPERM; | 1387 | err = -EPERM; |
| 1348 | goto error; | 1388 | goto error; |
| @@ -1574,13 +1614,19 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1574 | } | 1614 | } |
| 1575 | 1615 | ||
| 1576 | pol = NULL; | 1616 | pol = NULL; |
| 1577 | if (sk && sk->sk_policy[dir]) | 1617 | if (sk && sk->sk_policy[dir]) { |
| 1578 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); | 1618 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); |
| 1619 | if (IS_ERR(pol)) | ||
| 1620 | return 0; | ||
| 1621 | } | ||
| 1579 | 1622 | ||
| 1580 | if (!pol) | 1623 | if (!pol) |
| 1581 | pol = flow_cache_lookup(&fl, family, fl_dir, | 1624 | pol = flow_cache_lookup(&fl, family, fl_dir, |
| 1582 | xfrm_policy_lookup); | 1625 | xfrm_policy_lookup); |
| 1583 | 1626 | ||
| 1627 | if (IS_ERR(pol)) | ||
| 1628 | return 0; | ||
| 1629 | |||
| 1584 | if (!pol) { | 1630 | if (!pol) { |
| 1585 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { | 1631 | if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { |
| 1586 | xfrm_secpath_reject(xerr_idx, skb, &fl); | 1632 | xfrm_secpath_reject(xerr_idx, skb, &fl); |
| @@ -1599,6 +1645,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 1599 | &fl, family, | 1645 | &fl, family, |
| 1600 | XFRM_POLICY_IN); | 1646 | XFRM_POLICY_IN); |
| 1601 | if (pols[1]) { | 1647 | if (pols[1]) { |
| 1648 | if (IS_ERR(pols[1])) | ||
| 1649 | return 0; | ||
| 1602 | pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; | 1650 | pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; |
| 1603 | npols ++; | 1651 | npols ++; |
| 1604 | } | 1652 | } |
| @@ -1706,7 +1754,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | |||
| 1706 | 1754 | ||
| 1707 | static int stale_bundle(struct dst_entry *dst) | 1755 | static int stale_bundle(struct dst_entry *dst) |
| 1708 | { | 1756 | { |
| 1709 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); | 1757 | return !xfrm_bundle_ok(NULL, (struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); |
| 1710 | } | 1758 | } |
| 1711 | 1759 | ||
| 1712 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) | 1760 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
| @@ -1828,7 +1876,8 @@ EXPORT_SYMBOL(xfrm_init_pmtu); | |||
| 1828 | * still valid. | 1876 | * still valid. |
| 1829 | */ | 1877 | */ |
| 1830 | 1878 | ||
| 1831 | int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict) | 1879 | int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, |
| 1880 | struct flowi *fl, int family, int strict) | ||
| 1832 | { | 1881 | { |
| 1833 | struct dst_entry *dst = &first->u.dst; | 1882 | struct dst_entry *dst = &first->u.dst; |
| 1834 | struct xfrm_dst *last; | 1883 | struct xfrm_dst *last; |
| @@ -1845,7 +1894,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int str | |||
| 1845 | 1894 | ||
| 1846 | if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) | 1895 | if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) |
| 1847 | return 0; | 1896 | return 0; |
| 1848 | if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm)) | 1897 | if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) |
| 1849 | return 0; | 1898 | return 0; |
| 1850 | if (dst->xfrm->km.state != XFRM_STATE_VALID) | 1899 | if (dst->xfrm->km.state != XFRM_STATE_VALID) |
| 1851 | return 0; | 1900 | return 0; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 39b8bf3a9ded..899de9ed22a6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
| 505 | x->id.proto, family); | 505 | x->id.proto, family); |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
| 509 | { | ||
| 510 | if (have_hash_collision && | ||
| 511 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
| 512 | xfrm_state_num > xfrm_state_hmask) | ||
| 513 | schedule_work(&xfrm_hash_work); | ||
| 514 | } | ||
| 515 | |||
| 508 | struct xfrm_state * | 516 | struct xfrm_state * |
| 509 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 517 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, |
| 510 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 518 | struct flowi *fl, struct xfrm_tmpl *tmpl, |
| @@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
| 598 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 606 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; |
| 599 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 607 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; |
| 600 | add_timer(&x->timer); | 608 | add_timer(&x->timer); |
| 609 | xfrm_state_num++; | ||
| 610 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
| 601 | } else { | 611 | } else { |
| 602 | x->km.state = XFRM_STATE_DEAD; | 612 | x->km.state = XFRM_STATE_DEAD; |
| 603 | xfrm_state_put(x); | 613 | xfrm_state_put(x); |
| @@ -642,10 +652,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
| 642 | 652 | ||
| 643 | xfrm_state_num++; | 653 | xfrm_state_num++; |
| 644 | 654 | ||
| 645 | if (x->bydst.next != NULL && | 655 | xfrm_hash_grow_check(x->bydst.next != NULL); |
| 646 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
| 647 | xfrm_state_num > xfrm_state_hmask) | ||
| 648 | schedule_work(&xfrm_hash_work); | ||
| 649 | } | 656 | } |
| 650 | 657 | ||
| 651 | /* xfrm_state_lock is held */ | 658 | /* xfrm_state_lock is held */ |
| @@ -753,6 +760,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
| 753 | h = xfrm_src_hash(daddr, saddr, family); | 760 | h = xfrm_src_hash(daddr, saddr, family); |
| 754 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 761 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
| 755 | wake_up(&km_waitq); | 762 | wake_up(&km_waitq); |
| 763 | |||
| 764 | xfrm_state_num++; | ||
| 765 | |||
| 766 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
| 756 | } | 767 | } |
| 757 | 768 | ||
| 758 | return x; | 769 | return x; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d54b3a70d5df..c4cde57d9216 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -323,7 +323,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
| 323 | x->props.replay_window = p->replay_window; | 323 | x->props.replay_window = p->replay_window; |
| 324 | x->props.reqid = p->reqid; | 324 | x->props.reqid = p->reqid; |
| 325 | x->props.family = p->family; | 325 | x->props.family = p->family; |
| 326 | x->props.saddr = p->saddr; | 326 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); |
| 327 | x->props.flags = p->flags; | 327 | x->props.flags = p->flags; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| @@ -545,7 +545,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) | |||
| 545 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); | 545 | memcpy(&p->lft, &x->lft, sizeof(p->lft)); |
| 546 | memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); | 546 | memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); |
| 547 | memcpy(&p->stats, &x->stats, sizeof(p->stats)); | 547 | memcpy(&p->stats, &x->stats, sizeof(p->stats)); |
| 548 | p->saddr = x->props.saddr; | 548 | memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr)); |
| 549 | p->mode = x->props.mode; | 549 | p->mode = x->props.mode; |
| 550 | p->replay_window = x->props.replay_window; | 550 | p->replay_window = x->props.replay_window; |
| 551 | p->reqid = x->props.reqid; | 551 | p->reqid = x->props.reqid; |
| @@ -1927,6 +1927,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
| 1927 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 1927 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
| 1928 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); | 1928 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); |
| 1929 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 1929 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
| 1930 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1931 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
| 1932 | #endif | ||
| 1930 | skb = alloc_skb(len, GFP_ATOMIC); | 1933 | skb = alloc_skb(len, GFP_ATOMIC); |
| 1931 | if (skb == NULL) | 1934 | if (skb == NULL) |
| 1932 | return -ENOMEM; | 1935 | return -ENOMEM; |
| @@ -1992,15 +1995,6 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt, | |||
| 1992 | xp->type = XFRM_POLICY_TYPE_MAIN; | 1995 | xp->type = XFRM_POLICY_TYPE_MAIN; |
| 1993 | copy_templates(xp, ut, nr); | 1996 | copy_templates(xp, ut, nr); |
| 1994 | 1997 | ||
| 1995 | if (!xp->security) { | ||
| 1996 | int err = security_xfrm_sock_policy_alloc(xp, sk); | ||
| 1997 | if (err) { | ||
| 1998 | kfree(xp); | ||
| 1999 | *dir = err; | ||
| 2000 | return NULL; | ||
| 2001 | } | ||
| 2002 | } | ||
| 2003 | |||
| 2004 | *dir = p->dir; | 1998 | *dir = p->dir; |
| 2005 | 1999 | ||
| 2006 | return xp; | 2000 | return xp; |
| @@ -2043,6 +2037,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
| 2043 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 2037 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
| 2044 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); | 2038 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); |
| 2045 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 2039 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
| 2040 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 2041 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
| 2042 | #endif | ||
| 2046 | skb = alloc_skb(len, GFP_ATOMIC); | 2043 | skb = alloc_skb(len, GFP_ATOMIC); |
| 2047 | if (skb == NULL) | 2044 | if (skb == NULL) |
| 2048 | return -ENOMEM; | 2045 | return -ENOMEM; |
| @@ -2069,6 +2066,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
| 2069 | len += RTA_SPACE(headlen); | 2066 | len += RTA_SPACE(headlen); |
| 2070 | headlen = sizeof(*id); | 2067 | headlen = sizeof(*id); |
| 2071 | } | 2068 | } |
| 2069 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 2070 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
| 2071 | #endif | ||
| 2072 | len += NLMSG_SPACE(headlen); | 2072 | len += NLMSG_SPACE(headlen); |
| 2073 | 2073 | ||
| 2074 | skb = alloc_skb(len, GFP_ATOMIC); | 2074 | skb = alloc_skb(len, GFP_ATOMIC); |
| @@ -2115,10 +2115,12 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
| 2115 | struct nlmsghdr *nlh; | 2115 | struct nlmsghdr *nlh; |
| 2116 | struct sk_buff *skb; | 2116 | struct sk_buff *skb; |
| 2117 | unsigned char *b; | 2117 | unsigned char *b; |
| 2118 | int len = 0; | ||
| 2118 | #ifdef CONFIG_XFRM_SUB_POLICY | 2119 | #ifdef CONFIG_XFRM_SUB_POLICY |
| 2119 | struct xfrm_userpolicy_type upt; | 2120 | struct xfrm_userpolicy_type upt; |
| 2121 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
| 2120 | #endif | 2122 | #endif |
| 2121 | int len = NLMSG_LENGTH(0); | 2123 | len += NLMSG_LENGTH(0); |
| 2122 | 2124 | ||
| 2123 | skb = alloc_skb(len, GFP_ATOMIC); | 2125 | skb = alloc_skb(len, GFP_ATOMIC); |
| 2124 | if (skb == NULL) | 2126 | if (skb == NULL) |
