diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/esp4_offload.c | 1 | ||||
-rw-r--r-- | net/ipv6/esp6_offload.c | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_device.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 16 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 2 |
5 files changed, 16 insertions, 6 deletions
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 05831dea00f4..aca1c85f0795 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -305,3 +305,4 @@ module_init(esp4_offload_init); module_exit(esp4_offload_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); +MODULE_ALIAS_XFRM_OFFLOAD_TYPE(AF_INET, XFRM_PROTO_ESP); diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index eec3add177fe..8d4e2ba9163d 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -334,3 +334,4 @@ module_init(esp6_offload_init); module_exit(esp6_offload_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); +MODULE_ALIAS_XFRM_OFFLOAD_TYPE(AF_INET6, XFRM_PROTO_ESP); diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 5cd7a244e88d..1904127f5fb8 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -63,7 +63,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, xfrm_address_t *daddr; if (!x->type_offload) - return 0; + return -EINVAL; /* We don't yet support UDP encapsulation, TFC padding and ESN. */ if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN)) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 82cbbce69b79..a41e2ef789c0 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -296,12 +296,14 @@ int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, } EXPORT_SYMBOL(xfrm_unregister_type_offload); -static const struct xfrm_type_offload *xfrm_get_type_offload(u8 proto, unsigned short family) +static const struct xfrm_type_offload * +xfrm_get_type_offload(u8 proto, unsigned short family, bool try_load) { struct xfrm_state_afinfo *afinfo; const struct xfrm_type_offload **typemap; const struct xfrm_type_offload *type; +retry: afinfo = xfrm_state_get_afinfo(family); if (unlikely(afinfo == NULL)) return NULL; @@ -311,6 +313,12 @@ static const struct xfrm_type_offload *xfrm_get_type_offload(u8 proto, unsigned if ((type && !try_module_get(type->owner))) type = NULL; + if (!type && try_load) { + request_module("xfrm-offload-%d-%d", family, proto); + try_load = 0; + goto retry; + } + rcu_read_unlock(); return type; } @@ -2165,7 +2173,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu) return mtu - x->props.header_len; } -int __xfrm_init_state(struct xfrm_state *x, bool init_replay) +int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) { struct xfrm_state_afinfo *afinfo; struct xfrm_mode *inner_mode; @@ -2230,7 +2238,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay) if (x->type == NULL) goto error; - x->type_offload = xfrm_get_type_offload(x->id.proto, family); + x->type_offload = xfrm_get_type_offload(x->id.proto, family, offload); err = x->type->init_state(x); if (err) @@ -2258,7 +2266,7 @@ EXPORT_SYMBOL(__xfrm_init_state); int xfrm_init_state(struct xfrm_state *x) { - return __xfrm_init_state(x, true); + return __xfrm_init_state(x, true, false); } EXPORT_SYMBOL(xfrm_init_state); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 1b539b7dcfab..ffe8d5ef09eb 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -584,7 +584,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, xfrm_mark_get(attrs, &x->mark); - err = __xfrm_init_state(x, false); + err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]); if (err) goto error; |