aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-01-26 10:22:53 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-26 10:22:53 -0500
commita81e4affe1789a3d1010f219ad53382a760aa2ea (patch)
tree73ea99e882beec7435f49b370ef5d8527ac361ef
parent5b09179e7fa2849a0c95d14bb69416693e0ed0c3 (diff)
parent50bd870a9e5cca9fcf5fb4c130c373643d7d9906 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2018-01-26 One last patch for this development cycle: 1) Add ESN support for IPSec HW offload. From Yossef Efraim. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/xfrm_device.txt3
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/net/xfrm.h12
-rw-r--r--net/xfrm/xfrm_device.c11
-rw-r--r--net/xfrm/xfrm_replay.c2
5 files changed, 27 insertions, 2 deletions
diff --git a/Documentation/networking/xfrm_device.txt b/Documentation/networking/xfrm_device.txt
index 2d9d588cd34b..50c34ca65efe 100644
--- a/Documentation/networking/xfrm_device.txt
+++ b/Documentation/networking/xfrm_device.txt
@@ -41,6 +41,7 @@ struct xfrmdev_ops {
41 void (*xdo_dev_state_free) (struct xfrm_state *x); 41 void (*xdo_dev_state_free) (struct xfrm_state *x);
42 bool (*xdo_dev_offload_ok) (struct sk_buff *skb, 42 bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
43 struct xfrm_state *x); 43 struct xfrm_state *x);
44 void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
44}; 45};
45 46
46The NIC driver offering ipsec offload will need to implement these 47The NIC driver offering ipsec offload will need to implement these
@@ -117,6 +118,8 @@ the stack in xfrm_input().
117 118
118 hand the packet to napi_gro_receive() as usual 119 hand the packet to napi_gro_receive() as usual
119 120
121In ESN mode, xdo_dev_state_advance_esn() is called from xfrm_replay_advance_esn().
122Driver will check packet seq number and update HW ESN state machine if needed.
120 123
121When the SA is removed by the user, the driver's xdo_dev_state_delete() 124When the SA is removed by the user, the driver's xdo_dev_state_delete()
122is asked to disable the offload. Later, xdo_dev_state_free() is called 125is asked to disable the offload. Later, xdo_dev_state_free() is called
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 24a62d590350..cd46d3d63aa0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -851,6 +851,7 @@ struct xfrmdev_ops {
851 void (*xdo_dev_state_free) (struct xfrm_state *x); 851 void (*xdo_dev_state_free) (struct xfrm_state *x);
852 bool (*xdo_dev_offload_ok) (struct sk_buff *skb, 852 bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
853 struct xfrm_state *x); 853 struct xfrm_state *x);
854 void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
854}; 855};
855#endif 856#endif
856 857
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2e6d4fe6b0ba..7d2077665c0b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1904,6 +1904,14 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
1904 struct xfrm_user_offload *xuo); 1904 struct xfrm_user_offload *xuo);
1905bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); 1905bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
1906 1906
1907static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1908{
1909 struct xfrm_state_offload *xso = &x->xso;
1910
1911 if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn)
1912 xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x);
1913}
1914
1907static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) 1915static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1908{ 1916{
1909 struct xfrm_state *x = dst->xfrm; 1917 struct xfrm_state *x = dst->xfrm;
@@ -1974,6 +1982,10 @@ static inline bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x
1974 return false; 1982 return false;
1975} 1983}
1976 1984
1985static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
1986{
1987}
1988
1977static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) 1989static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
1978{ 1990{
1979 return false; 1991 return false;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 92b4648e75ca..8e70291e586a 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -147,8 +147,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
147 if (!x->type_offload) 147 if (!x->type_offload)
148 return -EINVAL; 148 return -EINVAL;
149 149
150 /* We don't yet support UDP encapsulation, TFC padding and ESN. */ 150 /* We don't yet support UDP encapsulation and TFC padding. */
151 if (x->encap || x->tfcpad || (x->props.flags & XFRM_STATE_ESN)) 151 if (x->encap || x->tfcpad)
152 return -EINVAL; 152 return -EINVAL;
153 153
154 dev = dev_get_by_index(net, xuo->ifindex); 154 dev = dev_get_by_index(net, xuo->ifindex);
@@ -178,6 +178,13 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
178 return 0; 178 return 0;
179 } 179 }
180 180
181 if (x->props.flags & XFRM_STATE_ESN &&
182 !dev->xfrmdev_ops->xdo_dev_state_advance_esn) {
183 xso->dev = NULL;
184 dev_put(dev);
185 return -EINVAL;
186 }
187
181 xso->dev = dev; 188 xso->dev = dev;
182 xso->num_exthdrs = 1; 189 xso->num_exthdrs = 1;
183 xso->flags = xuo->flags; 190 xso->flags = xuo->flags;
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 02501817227b..1d38c6acf8af 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -551,6 +551,8 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
551 bitnr = replay_esn->replay_window - (diff - pos); 551 bitnr = replay_esn->replay_window - (diff - pos);
552 } 552 }
553 553
554 xfrm_dev_state_advance_esn(x);
555
554 nr = bitnr >> 5; 556 nr = bitnr >> 5;
555 bitnr = bitnr & 0x1F; 557 bitnr = bitnr & 0x1F;
556 replay_esn->bmp[nr] |= (1U << bitnr); 558 replay_esn->bmp[nr] |= (1U << bitnr);