2 * xfrm_device.c - IPsec device offloading code.
4 * Copyright (c) 2015 secunet Security Networks AG
7 * Steffen Klassert <steffen.klassert@secunet.com>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
15 #include <linux/errno.h>
16 #include <linux/module.h>
17 #include <linux/netdevice.h>
18 #include <linux/skbuff.h>
19 #include <linux/slab.h>
20 #include <linux/spinlock.h>
23 #include <linux/notifier.h>
25 #ifdef CONFIG_XFRM_OFFLOAD
26 int validate_xmit_xfrm(struct sk_buff
*skb
, netdev_features_t features
)
30 struct xfrm_offload
*xo
= xfrm_offload(skb
);
36 x
= skb
->sp
->xvec
[skb
->sp
->len
- 1];
37 if (xo
->flags
& XFRM_GRO
|| x
->xso
.flags
& XFRM_OFFLOAD_INBOUND
)
40 x
->outer_mode
->xmit(x
, skb
);
42 err
= x
->type_offload
->xmit(x
, skb
, features
);
44 XFRM_INC_STATS(xs_net(x
), LINUX_MIB_XFRMOUTSTATEPROTOERROR
);
48 skb_push(skb
, skb
->data
- skb_mac_header(skb
));
53 EXPORT_SYMBOL_GPL(validate_xmit_xfrm
);
55 int xfrm_dev_state_add(struct net
*net
, struct xfrm_state
*x
,
56 struct xfrm_user_offload
*xuo
)
59 struct dst_entry
*dst
;
60 struct net_device
*dev
;
61 struct xfrm_state_offload
*xso
= &x
->xso
;
62 xfrm_address_t
*saddr
;
63 xfrm_address_t
*daddr
;
68 /* We don't yet support UDP encapsulation, TFC padding and ESN. */
69 if (x
->encap
|| x
->tfcpad
|| (x
->props
.flags
& XFRM_STATE_ESN
))
72 dev
= dev_get_by_index(net
, xuo
->ifindex
);
74 if (!(xuo
->flags
& XFRM_OFFLOAD_INBOUND
)) {
75 saddr
= &x
->props
.saddr
;
79 daddr
= &x
->props
.saddr
;
82 dst
= __xfrm_dst_lookup(net
, 0, 0, saddr
, daddr
,
83 x
->props
.family
, x
->props
.output_mark
);
93 if (!dev
->xfrmdev_ops
|| !dev
->xfrmdev_ops
->xdo_dev_state_add
) {
100 xso
->num_exthdrs
= 1;
101 xso
->flags
= xuo
->flags
;
103 err
= dev
->xfrmdev_ops
->xdo_dev_state_add(x
);
111 EXPORT_SYMBOL_GPL(xfrm_dev_state_add
);
113 bool xfrm_dev_offload_ok(struct sk_buff
*skb
, struct xfrm_state
*x
)
116 struct dst_entry
*dst
= skb_dst(skb
);
117 struct xfrm_dst
*xdst
= (struct xfrm_dst
*)dst
;
118 struct net_device
*dev
= x
->xso
.dev
;
120 if (!x
->type_offload
|| x
->encap
)
123 if ((x
->xso
.offload_handle
&& (dev
== dst
->path
->dev
)) &&
124 !dst
->child
->xfrm
&& x
->type
->get_mtu
) {
125 mtu
= x
->type
->get_mtu(x
, xdst
->child_mtu_cached
);
130 if (skb_is_gso(skb
) && skb_gso_validate_mtu(skb
, mtu
))
137 if (dev
&& dev
->xfrmdev_ops
&& dev
->xfrmdev_ops
->xdo_dev_offload_ok
)
138 return x
->xso
.dev
->xfrmdev_ops
->xdo_dev_offload_ok(skb
, x
);
142 EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok
);
145 static int xfrm_dev_register(struct net_device
*dev
)
147 if ((dev
->features
& NETIF_F_HW_ESP
) && !dev
->xfrmdev_ops
)
149 if ((dev
->features
& NETIF_F_HW_ESP_TX_CSUM
) &&
150 !(dev
->features
& NETIF_F_HW_ESP
))
156 static int xfrm_dev_unregister(struct net_device
*dev
)
158 xfrm_policy_cache_flush();
162 static int xfrm_dev_feat_change(struct net_device
*dev
)
164 if ((dev
->features
& NETIF_F_HW_ESP
) && !dev
->xfrmdev_ops
)
166 else if (!(dev
->features
& NETIF_F_HW_ESP
))
167 dev
->xfrmdev_ops
= NULL
;
169 if ((dev
->features
& NETIF_F_HW_ESP_TX_CSUM
) &&
170 !(dev
->features
& NETIF_F_HW_ESP
))
176 static int xfrm_dev_down(struct net_device
*dev
)
178 if (dev
->features
& NETIF_F_HW_ESP
)
179 xfrm_dev_state_flush(dev_net(dev
), dev
, true);
181 xfrm_policy_cache_flush();
185 static int xfrm_dev_event(struct notifier_block
*this, unsigned long event
, void *ptr
)
187 struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
190 case NETDEV_REGISTER
:
191 return xfrm_dev_register(dev
);
193 case NETDEV_UNREGISTER
:
194 return xfrm_dev_unregister(dev
);
196 case NETDEV_FEAT_CHANGE
:
197 return xfrm_dev_feat_change(dev
);
200 return xfrm_dev_down(dev
);
205 static struct notifier_block xfrm_dev_notifier
= {
206 .notifier_call
= xfrm_dev_event
,
209 void __net_init
xfrm_dev_init(void)
211 register_netdevice_notifier(&xfrm_dev_notifier
);