1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * xfrm_device.c - IPsec device offloading code.
5 * Copyright (c) 2015 secunet Security Networks AG
8 * Steffen Klassert <steffen.klassert@secunet.com>
11 #include <linux/errno.h>
12 #include <linux/module.h>
13 #include <linux/netdevice.h>
14 #include <linux/skbuff.h>
15 #include <linux/slab.h>
16 #include <linux/spinlock.h>
20 #include <linux/notifier.h>
22 #ifdef CONFIG_XFRM_OFFLOAD
23 static void __xfrm_transport_prep(struct xfrm_state
*x
, struct sk_buff
*skb
,
26 struct xfrm_offload
*xo
= xfrm_offload(skb
);
28 skb_reset_mac_len(skb
);
29 if (xo
->flags
& XFRM_GSO_SEGMENT
)
30 skb
->transport_header
-= x
->props
.header_len
;
32 pskb_pull(skb
, skb_transport_offset(skb
) + x
->props
.header_len
);
35 static void __xfrm_mode_tunnel_prep(struct xfrm_state
*x
, struct sk_buff
*skb
,
39 struct xfrm_offload
*xo
= xfrm_offload(skb
);
41 if (xo
->flags
& XFRM_GSO_SEGMENT
)
42 skb
->transport_header
= skb
->network_header
+ hsize
;
44 skb_reset_mac_len(skb
);
45 pskb_pull(skb
, skb
->mac_len
+ x
->props
.header_len
);
48 static void __xfrm_mode_beet_prep(struct xfrm_state
*x
, struct sk_buff
*skb
,
51 struct xfrm_offload
*xo
= xfrm_offload(skb
);
54 if (xo
->flags
& XFRM_GSO_SEGMENT
)
55 skb
->transport_header
= skb
->network_header
+ hsize
;
57 skb_reset_mac_len(skb
);
58 if (x
->sel
.family
!= AF_INET6
) {
59 phlen
= IPV4_BEET_PHMAXLEN
;
60 if (x
->outer_mode
.family
== AF_INET6
)
61 phlen
+= sizeof(struct ipv6hdr
) - sizeof(struct iphdr
);
64 pskb_pull(skb
, skb
->mac_len
+ hsize
+ (x
->props
.header_len
- phlen
));
67 /* Adjust pointers into the packet when IPsec is done at layer2 */
68 static void xfrm_outer_mode_prep(struct xfrm_state
*x
, struct sk_buff
*skb
)
70 switch (x
->outer_mode
.encap
) {
71 case XFRM_MODE_TUNNEL
:
72 if (x
->outer_mode
.family
== AF_INET
)
73 return __xfrm_mode_tunnel_prep(x
, skb
,
74 sizeof(struct iphdr
));
75 if (x
->outer_mode
.family
== AF_INET6
)
76 return __xfrm_mode_tunnel_prep(x
, skb
,
77 sizeof(struct ipv6hdr
));
79 case XFRM_MODE_TRANSPORT
:
80 if (x
->outer_mode
.family
== AF_INET
)
81 return __xfrm_transport_prep(x
, skb
,
82 sizeof(struct iphdr
));
83 if (x
->outer_mode
.family
== AF_INET6
)
84 return __xfrm_transport_prep(x
, skb
,
85 sizeof(struct ipv6hdr
));
88 if (x
->outer_mode
.family
== AF_INET
)
89 return __xfrm_mode_beet_prep(x
, skb
,
90 sizeof(struct iphdr
));
91 if (x
->outer_mode
.family
== AF_INET6
)
92 return __xfrm_mode_beet_prep(x
, skb
,
93 sizeof(struct ipv6hdr
));
95 case XFRM_MODE_ROUTEOPTIMIZATION
:
96 case XFRM_MODE_IN_TRIGGER
:
101 static inline bool xmit_xfrm_check_overflow(struct sk_buff
*skb
)
103 struct xfrm_offload
*xo
= xfrm_offload(skb
);
104 __u32 seq
= xo
->seq
.low
;
106 seq
+= skb_shinfo(skb
)->gso_segs
;
107 if (unlikely(seq
< xo
->seq
.low
))
113 struct sk_buff
*validate_xmit_xfrm(struct sk_buff
*skb
, netdev_features_t features
, bool *again
)
117 struct xfrm_state
*x
;
118 struct softnet_data
*sd
;
119 struct sk_buff
*skb2
, *nskb
, *pskb
= NULL
;
120 netdev_features_t esp_features
= features
;
121 struct xfrm_offload
*xo
= xfrm_offload(skb
);
122 struct net_device
*dev
= skb
->dev
;
125 if (!xo
|| (xo
->flags
& XFRM_XMIT
))
128 if (!(features
& NETIF_F_HW_ESP
))
129 esp_features
= features
& ~(NETIF_F_SG
| NETIF_F_CSUM_MASK
);
131 sp
= skb_sec_path(skb
);
132 x
= sp
->xvec
[sp
->len
- 1];
133 if (xo
->flags
& XFRM_GRO
|| x
->xso
.dir
== XFRM_DEV_OFFLOAD_IN
)
136 /* The packet was sent to HW IPsec packet offload engine,
137 * but to wrong device. Drop the packet, so it won't skip
140 if (x
->xso
.type
== XFRM_DEV_OFFLOAD_PACKET
&& x
->xso
.dev
!= dev
) {
142 dev_core_stats_tx_dropped_inc(dev
);
146 /* This skb was already validated on the upper/virtual dev */
147 if ((x
->xso
.dev
!= dev
) && (x
->xso
.real_dev
== dev
))
150 local_irq_save(flags
);
151 sd
= this_cpu_ptr(&softnet_data
);
152 err
= !skb_queue_empty(&sd
->xfrm_backlog
);
153 local_irq_restore(flags
);
160 if (skb_is_gso(skb
) && (unlikely(x
->xso
.dev
!= dev
) ||
161 unlikely(xmit_xfrm_check_overflow(skb
)))) {
162 struct sk_buff
*segs
;
164 /* Packet got rerouted, fixup features and segment it. */
165 esp_features
= esp_features
& ~(NETIF_F_HW_ESP
| NETIF_F_GSO_ESP
);
167 segs
= skb_gso_segment(skb
, esp_features
);
170 dev_core_stats_tx_dropped_inc(dev
);
179 esp_features
|= skb
->dev
->gso_partial_features
;
180 xfrm_outer_mode_prep(x
, skb
);
182 xo
->flags
|= XFRM_DEV_RESUME
;
184 err
= x
->type_offload
->xmit(x
, skb
, esp_features
);
186 if (err
== -EINPROGRESS
)
189 XFRM_INC_STATS(xs_net(x
), LINUX_MIB_XFRMOUTSTATEPROTOERROR
);
194 skb_push(skb
, skb
->data
- skb_mac_header(skb
));
199 skb_list_walk_safe(skb
, skb2
, nskb
) {
200 esp_features
|= skb
->dev
->gso_partial_features
;
201 skb_mark_not_on_list(skb2
);
203 xo
= xfrm_offload(skb2
);
204 xo
->flags
|= XFRM_DEV_RESUME
;
206 xfrm_outer_mode_prep(x
, skb2
);
208 err
= x
->type_offload
->xmit(x
, skb2
, esp_features
);
211 } else if (err
!= -EINPROGRESS
) {
212 XFRM_INC_STATS(xs_net(x
), LINUX_MIB_XFRMOUTSTATEPROTOERROR
);
214 kfree_skb_list(skb2
);
225 skb_push(skb2
, skb2
->data
- skb_mac_header(skb2
));
231 EXPORT_SYMBOL_GPL(validate_xmit_xfrm
);
233 int xfrm_dev_state_add(struct net
*net
, struct xfrm_state
*x
,
234 struct xfrm_user_offload
*xuo
,
235 struct netlink_ext_ack
*extack
)
238 struct dst_entry
*dst
;
239 struct net_device
*dev
;
240 struct xfrm_dev_offload
*xso
= &x
->xso
;
241 xfrm_address_t
*saddr
;
242 xfrm_address_t
*daddr
;
243 bool is_packet_offload
;
245 if (!x
->type_offload
) {
246 NL_SET_ERR_MSG(extack
, "Type doesn't support offload");
251 ~(XFRM_OFFLOAD_IPV6
| XFRM_OFFLOAD_INBOUND
| XFRM_OFFLOAD_PACKET
)) {
252 NL_SET_ERR_MSG(extack
, "Unrecognized flags in offload request");
256 if ((xuo
->flags
& XFRM_OFFLOAD_INBOUND
&& x
->dir
== XFRM_SA_DIR_OUT
) ||
257 (!(xuo
->flags
& XFRM_OFFLOAD_INBOUND
) && x
->dir
== XFRM_SA_DIR_IN
)) {
258 NL_SET_ERR_MSG(extack
, "Mismatched SA and offload direction");
262 is_packet_offload
= xuo
->flags
& XFRM_OFFLOAD_PACKET
;
264 /* We don't yet support TFC padding. */
266 NL_SET_ERR_MSG(extack
, "TFC padding can't be offloaded");
270 dev
= dev_get_by_index(net
, xuo
->ifindex
);
272 if (!(xuo
->flags
& XFRM_OFFLOAD_INBOUND
)) {
273 saddr
= &x
->props
.saddr
;
274 daddr
= &x
->id
.daddr
;
276 saddr
= &x
->id
.daddr
;
277 daddr
= &x
->props
.saddr
;
280 dst
= __xfrm_dst_lookup(net
, 0, 0, saddr
, daddr
,
282 xfrm_smark_get(0, x
));
284 return (is_packet_offload
) ? -EINVAL
: 0;
292 if (!dev
->xfrmdev_ops
|| !dev
->xfrmdev_ops
->xdo_dev_state_add
) {
295 return (is_packet_offload
) ? -EINVAL
: 0;
298 if (!is_packet_offload
&& x
->props
.flags
& XFRM_STATE_ESN
&&
299 !dev
->xfrmdev_ops
->xdo_dev_state_advance_esn
) {
300 NL_SET_ERR_MSG(extack
, "Device doesn't support offload with ESN");
307 netdev_tracker_alloc(dev
, &xso
->dev_tracker
, GFP_ATOMIC
);
310 if (xuo
->flags
& XFRM_OFFLOAD_INBOUND
)
311 xso
->dir
= XFRM_DEV_OFFLOAD_IN
;
313 xso
->dir
= XFRM_DEV_OFFLOAD_OUT
;
315 if (is_packet_offload
)
316 xso
->type
= XFRM_DEV_OFFLOAD_PACKET
;
318 xso
->type
= XFRM_DEV_OFFLOAD_CRYPTO
;
320 err
= dev
->xfrmdev_ops
->xdo_dev_state_add(x
, extack
);
324 xso
->real_dev
= NULL
;
325 netdev_put(dev
, &xso
->dev_tracker
);
326 xso
->type
= XFRM_DEV_OFFLOAD_UNSPECIFIED
;
328 /* User explicitly requested packet offload mode and configured
329 * policy in addition to the XFRM state. So be civil to users,
330 * and return an error instead of taking fallback path.
332 if ((err
!= -EOPNOTSUPP
&& !is_packet_offload
) || is_packet_offload
) {
333 NL_SET_ERR_MSG_WEAK(extack
, "Device failed to offload this state");
340 EXPORT_SYMBOL_GPL(xfrm_dev_state_add
);
342 int xfrm_dev_policy_add(struct net
*net
, struct xfrm_policy
*xp
,
343 struct xfrm_user_offload
*xuo
, u8 dir
,
344 struct netlink_ext_ack
*extack
)
346 struct xfrm_dev_offload
*xdo
= &xp
->xdo
;
347 struct net_device
*dev
;
350 if (!xuo
->flags
|| xuo
->flags
& ~XFRM_OFFLOAD_PACKET
) {
351 /* We support only packet offload mode and it means
352 * that user must set XFRM_OFFLOAD_PACKET bit.
354 NL_SET_ERR_MSG(extack
, "Unrecognized flags in offload request");
358 dev
= dev_get_by_index(net
, xuo
->ifindex
);
362 if (!dev
->xfrmdev_ops
|| !dev
->xfrmdev_ops
->xdo_dev_policy_add
) {
365 NL_SET_ERR_MSG(extack
, "Policy offload is not supported");
370 netdev_tracker_alloc(dev
, &xdo
->dev_tracker
, GFP_ATOMIC
);
372 xdo
->type
= XFRM_DEV_OFFLOAD_PACKET
;
375 xdo
->dir
= XFRM_DEV_OFFLOAD_IN
;
377 case XFRM_POLICY_OUT
:
378 xdo
->dir
= XFRM_DEV_OFFLOAD_OUT
;
380 case XFRM_POLICY_FWD
:
381 xdo
->dir
= XFRM_DEV_OFFLOAD_FWD
;
385 netdev_put(dev
, &xdo
->dev_tracker
);
386 NL_SET_ERR_MSG(extack
, "Unrecognized offload direction");
390 err
= dev
->xfrmdev_ops
->xdo_dev_policy_add(xp
, extack
);
393 xdo
->real_dev
= NULL
;
394 xdo
->type
= XFRM_DEV_OFFLOAD_UNSPECIFIED
;
396 netdev_put(dev
, &xdo
->dev_tracker
);
397 NL_SET_ERR_MSG_WEAK(extack
, "Device failed to offload this policy");
403 EXPORT_SYMBOL_GPL(xfrm_dev_policy_add
);
405 bool xfrm_dev_offload_ok(struct sk_buff
*skb
, struct xfrm_state
*x
)
408 struct dst_entry
*dst
= skb_dst(skb
);
409 struct xfrm_dst
*xdst
= (struct xfrm_dst
*)dst
;
410 struct net_device
*dev
= x
->xso
.dev
;
412 if (!x
->type_offload
||
413 (x
->xso
.type
== XFRM_DEV_OFFLOAD_UNSPECIFIED
&& x
->encap
))
416 if (x
->xso
.type
== XFRM_DEV_OFFLOAD_PACKET
||
417 ((!dev
|| (dev
== xfrm_dst_path(dst
)->dev
)) &&
418 !xdst
->child
->xfrm
)) {
419 mtu
= xfrm_state_mtu(x
, xdst
->child_mtu_cached
);
423 if (skb_is_gso(skb
) && skb_gso_validate_network_len(skb
, mtu
))
430 if (dev
&& dev
->xfrmdev_ops
&& dev
->xfrmdev_ops
->xdo_dev_offload_ok
)
431 return x
->xso
.dev
->xfrmdev_ops
->xdo_dev_offload_ok(skb
, x
);
435 EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok
);
437 void xfrm_dev_resume(struct sk_buff
*skb
)
439 struct net_device
*dev
= skb
->dev
;
440 int ret
= NETDEV_TX_BUSY
;
441 struct netdev_queue
*txq
;
442 struct softnet_data
*sd
;
446 txq
= netdev_core_pick_tx(dev
, skb
, NULL
);
448 HARD_TX_LOCK(dev
, txq
, smp_processor_id());
449 if (!netif_xmit_frozen_or_stopped(txq
))
450 skb
= dev_hard_start_xmit(skb
, dev
, txq
, &ret
);
451 HARD_TX_UNLOCK(dev
, txq
);
453 if (!dev_xmit_complete(ret
)) {
454 local_irq_save(flags
);
455 sd
= this_cpu_ptr(&softnet_data
);
456 skb_queue_tail(&sd
->xfrm_backlog
, skb
);
457 raise_softirq_irqoff(NET_TX_SOFTIRQ
);
458 local_irq_restore(flags
);
462 EXPORT_SYMBOL_GPL(xfrm_dev_resume
);
464 void xfrm_dev_backlog(struct softnet_data
*sd
)
466 struct sk_buff_head
*xfrm_backlog
= &sd
->xfrm_backlog
;
467 struct sk_buff_head list
;
470 if (skb_queue_empty(xfrm_backlog
))
473 __skb_queue_head_init(&list
);
475 spin_lock(&xfrm_backlog
->lock
);
476 skb_queue_splice_init(xfrm_backlog
, &list
);
477 spin_unlock(&xfrm_backlog
->lock
);
479 while (!skb_queue_empty(&list
)) {
480 skb
= __skb_dequeue(&list
);
481 xfrm_dev_resume(skb
);
487 static int xfrm_api_check(struct net_device
*dev
)
489 #ifdef CONFIG_XFRM_OFFLOAD
490 if ((dev
->features
& NETIF_F_HW_ESP_TX_CSUM
) &&
491 !(dev
->features
& NETIF_F_HW_ESP
))
494 if ((dev
->features
& NETIF_F_HW_ESP
) &&
495 (!(dev
->xfrmdev_ops
&&
496 dev
->xfrmdev_ops
->xdo_dev_state_add
&&
497 dev
->xfrmdev_ops
->xdo_dev_state_delete
)))
500 if (dev
->features
& (NETIF_F_HW_ESP
| NETIF_F_HW_ESP_TX_CSUM
))
507 static int xfrm_dev_down(struct net_device
*dev
)
509 if (dev
->features
& NETIF_F_HW_ESP
) {
510 xfrm_dev_state_flush(dev_net(dev
), dev
, true);
511 xfrm_dev_policy_flush(dev_net(dev
), dev
, true);
517 static int xfrm_dev_event(struct notifier_block
*this, unsigned long event
, void *ptr
)
519 struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
522 case NETDEV_REGISTER
:
523 return xfrm_api_check(dev
);
525 case NETDEV_FEAT_CHANGE
:
526 return xfrm_api_check(dev
);
529 case NETDEV_UNREGISTER
:
530 return xfrm_dev_down(dev
);
535 static struct notifier_block xfrm_dev_notifier
= {
536 .notifier_call
= xfrm_dev_event
,
539 void __init
xfrm_dev_init(void)
541 register_netdevice_notifier(&xfrm_dev_notifier
);