Commit f6e27114a60a0afdec40db1bf7f6da37b565745a

Authored by Steffen Klassert
1 parent b3859c8ebf

net: Add a xfrm validate function to validate_xmit_skb

When we do IPsec offloading, we need a fallback for
packets that were targeted to be IPsec offloaded but
rerouted to a device that does not support IPsec offload.
For that we add a function that checks the offloading
features of the sending device and and flags the
requirement of a fallback before it calls the IPsec
output function. The IPsec output function adds the IPsec
trailer and does encryption if needed.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

Showing 3 changed files with 38 additions and 0 deletions Side-by-side Diff

... ... @@ -1862,6 +1862,7 @@
1862 1862  
1863 1863 #ifdef CONFIG_XFRM_OFFLOAD
1864 1864 void __net_init xfrm_dev_init(void);
  1865 +int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features);
1865 1866 int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1866 1867 struct xfrm_user_offload *xuo);
1867 1868 bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
... ... @@ -1888,6 +1889,11 @@
1888 1889 #else
1889 1890 static inline void __net_init xfrm_dev_init(void)
1890 1891 {
  1892 +}
  1893 +
  1894 +static inline int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
  1895 +{
  1896 + return 0;
1891 1897 }
1892 1898  
1893 1899 static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
... ... @@ -2972,6 +2972,9 @@
2972 2972 __skb_linearize(skb))
2973 2973 goto out_kfree_skb;
2974 2974  
  2975 + if (validate_xmit_xfrm(skb, features))
  2976 + goto out_kfree_skb;
  2977 +
2975 2978 /* If packet is not checksummed and device does not
2976 2979 * support checksumming for this protocol, complete
2977 2980 * checksumming here.
net/xfrm/xfrm_device.c
... ... @@ -22,6 +22,35 @@
22 22 #include <net/xfrm.h>
23 23 #include <linux/notifier.h>
24 24  
  25 +int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
  26 +{
  27 + int err;
  28 + struct xfrm_state *x;
  29 + struct xfrm_offload *xo = xfrm_offload(skb);
  30 +
  31 + if (skb_is_gso(skb))
  32 + return 0;
  33 +
  34 + if (xo) {
  35 + x = skb->sp->xvec[skb->sp->len - 1];
  36 + if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
  37 + return 0;
  38 +
  39 + x->outer_mode->xmit(x, skb);
  40 +
  41 + err = x->type_offload->xmit(x, skb, features);
  42 + if (err) {
  43 + XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
  44 + return err;
  45 + }
  46 +
  47 + skb_push(skb, skb->data - skb_mac_header(skb));
  48 + }
  49 +
  50 + return 0;
  51 +}
  52 +EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
  53 +
25 54 int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
26 55 struct xfrm_user_offload *xuo)
27 56 {