xfrm: Add an IPsec hardware offloading API
This patch adds all the bits that are needed to do IPsec hardware offload for IPsec states and ESP packets. We add xfrmdev_ops to the net_device. xfrmdev_ops has function pointers that are needed to manage the xfrm states in the hardware and to do a per packet offloading decision. Joint work with: Ilan Tayari <ilant@mellanox.com> Guy Shapiro <guysh@mellanox.com> Yossi Kuperman <yossiku@mellanox.com> Signed-off-by: Guy Shapiro <guysh@mellanox.com> Signed-off-by: Ilan Tayari <ilant@mellanox.com> Signed-off-by: Yossi Kuperman <yossiku@mellanox.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
@@ -99,12 +99,13 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
|
||||
|
||||
skb_dst_force(skb);
|
||||
|
||||
/* Inner headers are invalid now. */
|
||||
skb->encapsulation = 0;
|
||||
|
||||
err = x->type->output(x, skb);
|
||||
if (err == -EINPROGRESS)
|
||||
goto out;
|
||||
if (xfrm_offload(skb)) {
|
||||
x->type_offload->encap(x, skb);
|
||||
} else {
|
||||
err = x->type->output(x, skb);
|
||||
if (err == -EINPROGRESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
resume:
|
||||
if (err) {
|
||||
@@ -200,8 +201,38 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
|
||||
int xfrm_output(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
struct xfrm_state *x = skb_dst(skb)->xfrm;
|
||||
int err;
|
||||
|
||||
secpath_reset(skb);
|
||||
|
||||
if (xfrm_dev_offload_ok(skb, x)) {
|
||||
struct sec_path *sp;
|
||||
|
||||
sp = secpath_dup(skb->sp);
|
||||
if (!sp) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
|
||||
kfree_skb(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (skb->sp)
|
||||
secpath_put(skb->sp);
|
||||
skb->sp = sp;
|
||||
|
||||
sp->olen++;
|
||||
sp->xvec[skb->sp->len++] = x;
|
||||
xfrm_state_hold(x);
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
skb_shinfo(skb)->gso_type |= SKB_GSO_ESP;
|
||||
|
||||
return xfrm_output2(net, sk, skb);
|
||||
}
|
||||
|
||||
if (x->xso.dev && x->xso.dev->features & NETIF_F_HW_ESP_TX_CSUM)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (skb_is_gso(skb))
|
||||
return xfrm_output_gso(net, sk, skb);
|
||||
|
||||
@@ -214,6 +245,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return xfrm_output2(net, sk, skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_output);
|
||||
|
Reference in New Issue
Block a user