diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-31 06:57:05 +0200 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-31 06:57:05 +0200 |
commit | 5bc65793cbf8da0d35f19ef025dda22887e79e80 (patch) | |
tree | 8291998abd73055de6f487fafa174ee2a5d3afee /net/xfrm | |
parent | [SCSI] 3w-xxxx: convert to use the data buffer accessors (diff) | |
parent | a bug in ramfs_nommu_resize function, passing old size to vmtruncate (diff) | |
download | linux-5bc65793cbf8da0d35f19ef025dda22887e79e80.tar.xz linux-5bc65793cbf8da0d35f19ef025dda22887e79e80.zip |
[SCSI] Merge up to linux-2.6 head
Conflicts:
drivers/scsi/jazz_esp.c
Same changes made by both SCSI and SPARC trees: problem with UTF-8
conversion in the copyright.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_algo.c | 140 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 28 |
2 files changed, 101 insertions, 67 deletions
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 6249a9405bb8..5ced62c19c63 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -347,67 +347,44 @@ static inline int calg_entries(void) return ARRAY_SIZE(calg_list); } -/* Todo: generic iterators */ -struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) -{ - int i; - - for (i = 0; i < aalg_entries(); i++) { - if (aalg_list[i].desc.sadb_alg_id == alg_id) { - if (aalg_list[i].available) - return &aalg_list[i]; - else - break; - } - } - return NULL; -} -EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); - -struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) -{ - int i; +struct xfrm_algo_list { + struct xfrm_algo_desc *algs; + int entries; + u32 type; + u32 mask; +}; - for (i = 0; i < ealg_entries(); i++) { - if (ealg_list[i].desc.sadb_alg_id == alg_id) { - if (ealg_list[i].available) - return &ealg_list[i]; - else - break; - } - } - return NULL; -} -EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); +static const struct xfrm_algo_list xfrm_aalg_list = { + .algs = aalg_list, + .entries = ARRAY_SIZE(aalg_list), + .type = CRYPTO_ALG_TYPE_HASH, + .mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC, +}; -struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) -{ - int i; +static const struct xfrm_algo_list xfrm_ealg_list = { + .algs = ealg_list, + .entries = ARRAY_SIZE(ealg_list), + .type = CRYPTO_ALG_TYPE_BLKCIPHER, + .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, +}; - for (i = 0; i < calg_entries(); i++) { - if (calg_list[i].desc.sadb_alg_id == alg_id) { - if (calg_list[i].available) - return &calg_list[i]; - else - break; - } - } - return NULL; -} -EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); +static const struct xfrm_algo_list xfrm_calg_list = { + .algs = calg_list, + .entries = ARRAY_SIZE(calg_list), + .type = CRYPTO_ALG_TYPE_COMPRESS, + .mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC, +}; -static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, - int entries, u32 type, u32 mask, - char *name, int probe) +static struct xfrm_algo_desc *xfrm_find_algo( + const struct xfrm_algo_list *algo_list, + int match(const struct xfrm_algo_desc *entry, const void *data), + const void *data, int probe) { + struct xfrm_algo_desc *list = algo_list->algs; int i, status; - if (!name) - return NULL; - - for (i = 0; i < entries; i++) { - if (strcmp(name, list[i].name) && - (!list[i].compat || strcmp(name, list[i].compat))) + for (i = 0; i < algo_list->entries; i++) { + if (!match(list + i, data)) continue; if (list[i].available) @@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, if (!probe) break; - status = crypto_has_alg(list[i].name, type, - mask | CRYPTO_ALG_ASYNC); + status = crypto_has_alg(list[i].name, algo_list->type, + algo_list->mask); if (!status) break; @@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, return NULL; } +static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry, + const void *data) +{ + return entry->desc.sadb_alg_id == (unsigned long)data; +} + +struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) +{ + return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match, + (void *)(unsigned long)alg_id, 1); +} +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); + +struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) +{ + return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match, + (void *)(unsigned long)alg_id, 1); +} +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); + +struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) +{ + return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match, + (void *)(unsigned long)alg_id, 1); +} +EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); + +static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry, + const void *data) +{ + const char *name = data; + + return name && (!strcmp(name, entry->name) || + (entry->compat && !strcmp(name, entry->compat))); +} + struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) { - return xfrm_get_byname(aalg_list, aalg_entries(), - CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, - name, probe); + return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name, + probe); } EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) { - return xfrm_get_byname(ealg_list, ealg_entries(), - CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, - name, probe); + return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name, + probe); } EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) { - return xfrm_get_byname(calg_list, calg_entries(), - CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, - name, probe); + return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name, + probe); } EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d0882e53b6fc..b8bab89616a0 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -29,6 +29,8 @@ #include "xfrm_hash.h" +int sysctl_xfrm_larval_drop; + DEFINE_MUTEX(xfrm_cfg_mutex); EXPORT_SYMBOL(xfrm_cfg_mutex); @@ -1390,8 +1392,8 @@ static int stale_bundle(struct dst_entry *dst); * At the moment we eat a raw IP route. Mostly to speed up lookups * on interfaces with disabled IPsec. */ -int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, - struct sock *sk, int flags) +int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, + struct sock *sk, int flags) { struct xfrm_policy *policy; struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; @@ -1509,6 +1511,13 @@ restart: if (unlikely(nx<0)) { err = nx; + if (err == -EAGAIN && sysctl_xfrm_larval_drop) { + /* EREMOTE tells the caller to generate + * a one-shot blackhole route. + */ + xfrm_pol_put(policy); + return -EREMOTE; + } if (err == -EAGAIN && flags) { DECLARE_WAITQUEUE(wait, current); @@ -1598,6 +1607,21 @@ error: *dst_p = NULL; return err; } +EXPORT_SYMBOL(__xfrm_lookup); + +int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, + struct sock *sk, int flags) +{ + int err = __xfrm_lookup(dst_p, fl, sk, flags); + + if (err == -EREMOTE) { + dst_release(*dst_p); + *dst_p = NULL; + err = -EAGAIN; + } + + return err; +} EXPORT_SYMBOL(xfrm_lookup); static inline int |