Skip to content

Commit 9f30e5c

Browse files
committed
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 2017-12-22 1) Separate ESP handling from segmentation for GRO packets. This unifies the IPsec GSO and non GSO codepath. 2) Add asynchronous callbacks for xfrm on layer 2. This adds the necessary infrastructure to core networking. 3) Allow to use the layer2 IPsec GSO codepath for software crypto, all infrastructure is there now. 4) Also allow IPsec GSO with software crypto for local sockets. 5) Don't require synchronous crypto fallback on IPsec offloading, it is not needed anymore. 6) Check for xdo_dev_state_free and only call it if implemented. From Shannon Nelson. 7) Check for the required add and delete functions when a driver registers xdo_dev_ops. From Shannon Nelson. 8) Define xfrmdev_ops only with offload config. From Shannon Nelson. 9) Update the xfrm stats documentation. From Shannon Nelson. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 04f629f + 1a4bb1d commit 9f30e5c

File tree

13 files changed

+326
-190
lines changed

13 files changed

+326
-190
lines changed

Documentation/networking/xfrm_proc.txt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ Masahide NAKAMURA <[email protected]>
55

66
Transformation Statistics
77
-------------------------
8-
xfrm_proc is a statistics shown factor dropped by transformation
9-
for developer.
10-
It is a counter designed from current transformation source code
11-
and defined like linux private MIB.
128

13-
Inbound statistics
14-
~~~~~~~~~~~~~~~~~~
9+
The xfrm_proc code is a set of statistics showing numbers of packets
10+
dropped by the transformation code and why. These counters are defined
11+
as part of the linux private MIB. These counters can be viewed in
12+
/proc/net/xfrm_stat.
13+
14+
15+
Inbound errors
16+
~~~~~~~~~~~~~~
1517
XfrmInError:
1618
All errors which is not matched others
1719
XfrmInBufferError:
@@ -46,6 +48,10 @@ XfrmInPolBlock:
4648
Policy discards
4749
XfrmInPolError:
4850
Policy error
51+
XfrmAcquireError:
52+
State hasn't been fully acquired before use
53+
XfrmFwdHdrError:
54+
Forward routing of a packet is not allowed
4955

5056
Outbound errors
5157
~~~~~~~~~~~~~~~
@@ -72,3 +78,5 @@ XfrmOutPolDead:
7278
Policy is dead
7379
XfrmOutPolError:
7480
Policy error
81+
XfrmOutStateInvalid:
82+
State is invalid, perhaps expired

include/linux/netdevice.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,7 +1726,7 @@ struct net_device {
17261726
const struct ndisc_ops *ndisc_ops;
17271727
#endif
17281728

1729-
#ifdef CONFIG_XFRM
1729+
#ifdef CONFIG_XFRM_OFFLOAD
17301730
const struct xfrmdev_ops *xfrmdev_ops;
17311731
#endif
17321732

@@ -2793,7 +2793,9 @@ struct softnet_data {
27932793
struct Qdisc *output_queue;
27942794
struct Qdisc **output_queue_tailp;
27952795
struct sk_buff *completion_queue;
2796-
2796+
#ifdef CONFIG_XFRM_OFFLOAD
2797+
struct sk_buff_head xfrm_backlog;
2798+
#endif
27972799
#ifdef CONFIG_RPS
27982800
/* input_queue_head should be written by cpu owning this struct,
27992801
* and only read by other cpus. Worth using a cache line.
@@ -3325,7 +3327,7 @@ int dev_get_phys_port_id(struct net_device *dev,
33253327
int dev_get_phys_port_name(struct net_device *dev,
33263328
char *name, size_t len);
33273329
int dev_change_proto_down(struct net_device *dev, bool proto_down);
3328-
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
3330+
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again);
33293331
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
33303332
struct netdev_queue *txq, int *ret);
33313333

include/net/xfrm.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ struct xfrm_offload {
10511051
#define XFRM_GSO_SEGMENT 16
10521052
#define XFRM_GRO 32
10531053
#define XFRM_ESP_NO_TRAILER 64
1054+
#define XFRM_DEV_RESUME 128
10541055

10551056
__u32 status;
10561057
#define CRYPTO_SUCCESS 1
@@ -1874,21 +1875,28 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
18741875
{
18751876
return skb->sp->xvec[skb->sp->len - 1];
18761877
}
1878+
#endif
1879+
18771880
static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
18781881
{
1882+
#ifdef CONFIG_XFRM
18791883
struct sec_path *sp = skb->sp;
18801884

18811885
if (!sp || !sp->olen || sp->len != sp->olen)
18821886
return NULL;
18831887

18841888
return &sp->ovec[sp->olen - 1];
1885-
}
1889+
#else
1890+
return NULL;
18861891
#endif
1892+
}
18871893

18881894
void __net_init xfrm_dev_init(void);
18891895

18901896
#ifdef CONFIG_XFRM_OFFLOAD
1891-
int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features);
1897+
void xfrm_dev_resume(struct sk_buff *skb);
1898+
void xfrm_dev_backlog(struct softnet_data *sd);
1899+
struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
18921900
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
18931901
struct xfrm_user_offload *xuo);
18941902
bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
@@ -1902,6 +1910,8 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst)
19021910
return false;
19031911

19041912
xdst = (struct xfrm_dst *) dst;
1913+
if (!x->xso.offload_handle && !xdst->child->xfrm)
1914+
return true;
19051915
if (x->xso.offload_handle && (x->xso.dev == xfrm_dst_path(dst)->dev) &&
19061916
!xdst->child->xfrm)
19071917
return true;
@@ -1923,15 +1933,24 @@ static inline void xfrm_dev_state_free(struct xfrm_state *x)
19231933
struct net_device *dev = xso->dev;
19241934

19251935
if (dev && dev->xfrmdev_ops) {
1926-
dev->xfrmdev_ops->xdo_dev_state_free(x);
1936+
if (dev->xfrmdev_ops->xdo_dev_state_free)
1937+
dev->xfrmdev_ops->xdo_dev_state_free(x);
19271938
xso->dev = NULL;
19281939
dev_put(dev);
19291940
}
19301941
}
19311942
#else
1932-
static inline int validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features)
1943+
static inline void xfrm_dev_resume(struct sk_buff *skb)
19331944
{
1934-
return 0;
1945+
}
1946+
1947+
static inline void xfrm_dev_backlog(struct softnet_data *sd)
1948+
{
1949+
}
1950+
1951+
static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
1952+
{
1953+
return skb;
19351954
}
19361955

19371956
static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)

net/core/dev.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,7 +3059,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
30593059
}
30603060
EXPORT_SYMBOL(skb_csum_hwoffload_help);
30613061

3062-
static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev)
3062+
static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev, bool *again)
30633063
{
30643064
netdev_features_t features;
30653065

@@ -3083,9 +3083,6 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
30833083
__skb_linearize(skb))
30843084
goto out_kfree_skb;
30853085

3086-
if (validate_xmit_xfrm(skb, features))
3087-
goto out_kfree_skb;
3088-
30893086
/* If packet is not checksummed and device does not
30903087
* support checksumming for this protocol, complete
30913088
* checksumming here.
@@ -3102,6 +3099,8 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
31023099
}
31033100
}
31043101

3102+
skb = validate_xmit_xfrm(skb, features, again);
3103+
31053104
return skb;
31063105

31073106
out_kfree_skb:
@@ -3111,7 +3110,7 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
31113110
return NULL;
31123111
}
31133112

3114-
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev)
3113+
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again)
31153114
{
31163115
struct sk_buff *next, *head = NULL, *tail;
31173116

@@ -3122,7 +3121,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d
31223121
/* in case skb wont be segmented, point to itself */
31233122
skb->prev = skb;
31243123

3125-
skb = validate_xmit_skb(skb, dev);
3124+
skb = validate_xmit_skb(skb, dev, again);
31263125
if (!skb)
31273126
continue;
31283127

@@ -3449,6 +3448,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
34493448
struct netdev_queue *txq;
34503449
struct Qdisc *q;
34513450
int rc = -ENOMEM;
3451+
bool again = false;
34523452

34533453
skb_reset_mac_header(skb);
34543454

@@ -3510,7 +3510,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv)
35103510
XMIT_RECURSION_LIMIT))
35113511
goto recursion_alert;
35123512

3513-
skb = validate_xmit_skb(skb, dev);
3513+
skb = validate_xmit_skb(skb, dev, &again);
35143514
if (!skb)
35153515
goto out;
35163516

@@ -4194,6 +4194,8 @@ static __latent_entropy void net_tx_action(struct softirq_action *h)
41944194
spin_unlock(root_lock);
41954195
}
41964196
}
4197+
4198+
xfrm_dev_backlog(sd);
41974199
}
41984200

41994201
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_ATM_LANE)
@@ -8875,6 +8877,9 @@ static int __init net_dev_init(void)
88758877

88768878
skb_queue_head_init(&sd->input_pkt_queue);
88778879
skb_queue_head_init(&sd->process_queue);
8880+
#ifdef CONFIG_XFRM_OFFLOAD
8881+
skb_queue_head_init(&sd->xfrm_backlog);
8882+
#endif
88788883
INIT_LIST_HEAD(&sd->poll_list);
88798884
sd->output_queue_tailp = &sd->output_queue;
88808885
#ifdef CONFIG_RPS

net/ipv4/esp4.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,32 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
121121
static void esp_output_done(struct crypto_async_request *base, int err)
122122
{
123123
struct sk_buff *skb = base->data;
124+
struct xfrm_offload *xo = xfrm_offload(skb);
124125
void *tmp;
125-
struct dst_entry *dst = skb_dst(skb);
126-
struct xfrm_state *x = dst->xfrm;
126+
struct xfrm_state *x;
127+
128+
if (xo && (xo->flags & XFRM_DEV_RESUME))
129+
x = skb->sp->xvec[skb->sp->len - 1];
130+
else
131+
x = skb_dst(skb)->xfrm;
127132

128133
tmp = ESP_SKB_CB(skb)->tmp;
129134
esp_ssg_unref(x, tmp);
130135
kfree(tmp);
131-
xfrm_output_resume(skb, err);
136+
137+
if (xo && (xo->flags & XFRM_DEV_RESUME)) {
138+
if (err) {
139+
XFRM_INC_STATS(xs_net(x), LINUX_MIB_XFRMOUTSTATEPROTOERROR);
140+
kfree_skb(skb);
141+
return;
142+
}
143+
144+
skb_push(skb, skb->data - skb_mac_header(skb));
145+
secpath_reset(skb);
146+
xfrm_dev_resume(skb);
147+
} else {
148+
xfrm_output_resume(skb, err);
149+
}
132150
}
133151

134152
/* Move ESP header back into place. */
@@ -825,17 +843,13 @@ static int esp_init_aead(struct xfrm_state *x)
825843
char aead_name[CRYPTO_MAX_ALG_NAME];
826844
struct crypto_aead *aead;
827845
int err;
828-
u32 mask = 0;
829846

830847
err = -ENAMETOOLONG;
831848
if (snprintf(aead_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
832849
x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME)
833850
goto error;
834851

835-
if (x->xso.offload_handle)
836-
mask |= CRYPTO_ALG_ASYNC;
837-
838-
aead = crypto_alloc_aead(aead_name, 0, mask);
852+
aead = crypto_alloc_aead(aead_name, 0, 0);
839853
err = PTR_ERR(aead);
840854
if (IS_ERR(aead))
841855
goto error;
@@ -865,7 +879,6 @@ static int esp_init_authenc(struct xfrm_state *x)
865879
char authenc_name[CRYPTO_MAX_ALG_NAME];
866880
unsigned int keylen;
867881
int err;
868-
u32 mask = 0;
869882

870883
err = -EINVAL;
871884
if (!x->ealg)
@@ -891,10 +904,7 @@ static int esp_init_authenc(struct xfrm_state *x)
891904
goto error;
892905
}
893906

894-
if (x->xso.offload_handle)
895-
mask |= CRYPTO_ALG_ASYNC;
896-
897-
aead = crypto_alloc_aead(authenc_name, 0, mask);
907+
aead = crypto_alloc_aead(authenc_name, 0, 0);
898908
err = PTR_ERR(aead);
899909
if (IS_ERR(aead))
900910
goto error;

0 commit comments

Comments
 (0)