diff options
Diffstat (limited to 'net/ipv4/xfrm_policy.c')
| -rw-r--r-- | net/ipv4/xfrm_policy.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/net/ipv4/xfrm_policy.c b/net/ipv4/xfrm_policy.c index 9d015cbbab..02d7ce7797 100644 --- a/net/ipv4/xfrm_policy.c +++ b/net/ipv4/xfrm_policy.c @@ -1,3 +1,4 @@ +#include <linux/config.h> #include <net/xfrm.h> #include <net/ip.h> @@ -198,6 +199,49 @@ struct xfrm_type *xfrm_get_type(u8 proto) return type; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static struct xfrm_type *xfrm6_type_map[256]; +static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED; + +int xfrm6_register_type(struct xfrm_type *type) +{ + int err = 0; + + write_lock(&xfrm6_type_lock); + if (xfrm6_type_map[type->proto] == NULL) + xfrm6_type_map[type->proto] = type; + else + err = -EEXIST; + write_unlock(&xfrm6_type_lock); + return err; +} + +int xfrm6_unregister_type(struct xfrm_type *type) +{ + int err = 0; + + write_lock(&xfrm6_type_lock); + if (xfrm6_type_map[type->proto] != type) + err = -ENOENT; + else + xfrm6_type_map[type->proto] = NULL; + write_unlock(&xfrm6_type_lock); + return err; +} + +struct xfrm_type *xfrm6_get_type(u8 proto) +{ + struct xfrm_type *type; + + read_lock(&xfrm6_type_lock); + type = xfrm6_type_map[proto]; + if (type && !try_module_get(type->owner)) + type = NULL; + read_unlock(&xfrm6_type_lock); + return type; +} +#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */ + void xfrm_put_type(struct xfrm_type *type) { module_put(type->owner); |
