#include <linux/bottom_half.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/percpu.h>
#include <net/ip_tunnels.h>
#include <net/ip6_tunnel.h>
struct xfrm_trans_tasklet {
struct tasklet_struct tasklet;
struct sk_buff_head queue;
#if IS_ENABLED(CONFIG_IPV6)
struct inet6_skb_parm h6;
int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb);
#define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0]))
static DEFINE_SPINLOCK(xfrm_input_afinfo_lock);
static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[AF_INET6 + 1];
static struct gro_cells gro_cells;
static struct net_device xfrm_napi_dev;
static DEFINE_PER_CPU(struct xfrm_trans_tasklet, xfrm_trans_tasklet);
int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo)
if (WARN_ON(afinfo->family >= ARRAY_SIZE(xfrm_input_afinfo)))
spin_lock_bh(&xfrm_input_afinfo_lock);
if (unlikely(xfrm_input_afinfo[afinfo->family] != NULL))
rcu_assign_pointer(xfrm_input_afinfo[afinfo->family], afinfo);
spin_unlock_bh(&xfrm_input_afinfo_lock);