@@ -251,6 +251,75 @@ static void xfrm_put_type(const struct xfrm_type *type)
251251 module_put (type -> owner );
252252}
253253
254+ static DEFINE_SPINLOCK (xfrm_type_offload_lock );
255+ int xfrm_register_type_offload (const struct xfrm_type_offload * type ,
256+ unsigned short family )
257+ {
258+ struct xfrm_state_afinfo * afinfo = xfrm_state_get_afinfo (family );
259+ const struct xfrm_type_offload * * typemap ;
260+ int err = 0 ;
261+
262+ if (unlikely (afinfo == NULL ))
263+ return - EAFNOSUPPORT ;
264+ typemap = afinfo -> type_offload_map ;
265+ spin_lock_bh (& xfrm_type_offload_lock );
266+
267+ if (likely (typemap [type -> proto ] == NULL ))
268+ typemap [type -> proto ] = type ;
269+ else
270+ err = - EEXIST ;
271+ spin_unlock_bh (& xfrm_type_offload_lock );
272+ rcu_read_unlock ();
273+ return err ;
274+ }
275+ EXPORT_SYMBOL (xfrm_register_type_offload );
276+
277+ int xfrm_unregister_type_offload (const struct xfrm_type_offload * type ,
278+ unsigned short family )
279+ {
280+ struct xfrm_state_afinfo * afinfo = xfrm_state_get_afinfo (family );
281+ const struct xfrm_type_offload * * typemap ;
282+ int err = 0 ;
283+
284+ if (unlikely (afinfo == NULL ))
285+ return - EAFNOSUPPORT ;
286+ typemap = afinfo -> type_offload_map ;
287+ spin_lock_bh (& xfrm_type_offload_lock );
288+
289+ if (unlikely (typemap [type -> proto ] != type ))
290+ err = - ENOENT ;
291+ else
292+ typemap [type -> proto ] = NULL ;
293+ spin_unlock_bh (& xfrm_type_offload_lock );
294+ rcu_read_unlock ();
295+ return err ;
296+ }
297+ EXPORT_SYMBOL (xfrm_unregister_type_offload );
298+
299+ static const struct xfrm_type_offload * xfrm_get_type_offload (u8 proto , unsigned short family )
300+ {
301+ struct xfrm_state_afinfo * afinfo ;
302+ const struct xfrm_type_offload * * typemap ;
303+ const struct xfrm_type_offload * type ;
304+
305+ afinfo = xfrm_state_get_afinfo (family );
306+ if (unlikely (afinfo == NULL ))
307+ return NULL ;
308+ typemap = afinfo -> type_offload_map ;
309+
310+ type = typemap [proto ];
311+ if ((type && !try_module_get (type -> owner )))
312+ type = NULL ;
313+
314+ rcu_read_unlock ();
315+ return type ;
316+ }
317+
318+ static void xfrm_put_type_offload (const struct xfrm_type_offload * type )
319+ {
320+ module_put (type -> owner );
321+ }
322+
254323static DEFINE_SPINLOCK (xfrm_mode_lock );
255324int xfrm_register_mode (struct xfrm_mode * mode , int family )
256325{
@@ -365,6 +434,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
365434 xfrm_put_mode (x -> inner_mode_iaf );
366435 if (x -> outer_mode )
367436 xfrm_put_mode (x -> outer_mode );
437+ if (x -> type_offload )
438+ xfrm_put_type_offload (x -> type_offload );
368439 if (x -> type ) {
369440 x -> type -> destructor (x );
370441 xfrm_put_type (x -> type );
@@ -2077,6 +2148,8 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay)
20772148 if (x -> type == NULL )
20782149 goto error ;
20792150
2151+ x -> type_offload = xfrm_get_type_offload (x -> id .proto , family );
2152+
20802153 err = x -> type -> init_state (x );
20812154 if (err )
20822155 goto error ;
0 commit comments