Commit f6e27114a60a0afdec40db1bf7f6da37b565745a
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
include/net/xfrm.h
... | ... | @@ -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) |
net/core/dev.c
... | ... | @@ -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 | { |