xfrm: Prepare the GRO codepath for hardware offloading.
On IPsec hardware offloading, we already get a secpath with valid state attached when the packet enters the GRO handlers. So check for hardware offload and skip the state lookup in this case. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
Родитель
f1bd7d659e
Коммит
bcd1f8a45e
|
@ -43,27 +43,31 @@ static struct sk_buff **esp4_gro_receive(struct sk_buff **head,
|
|||
if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0)
|
||||
goto out;
|
||||
|
||||
err = secpath_set(skb);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (skb->sp->len == XFRM_MAX_DEPTH)
|
||||
goto out;
|
||||
|
||||
x = xfrm_state_lookup(dev_net(skb->dev), skb->mark,
|
||||
(xfrm_address_t *)&ip_hdr(skb)->daddr,
|
||||
spi, IPPROTO_ESP, AF_INET);
|
||||
if (!x)
|
||||
goto out;
|
||||
|
||||
skb->sp->xvec[skb->sp->len++] = x;
|
||||
skb->sp->olen++;
|
||||
|
||||
xo = xfrm_offload(skb);
|
||||
if (!xo) {
|
||||
xfrm_state_put(x);
|
||||
goto out;
|
||||
if (!xo || !(xo->flags & CRYPTO_DONE)) {
|
||||
err = secpath_set(skb);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (skb->sp->len == XFRM_MAX_DEPTH)
|
||||
goto out;
|
||||
|
||||
x = xfrm_state_lookup(dev_net(skb->dev), skb->mark,
|
||||
(xfrm_address_t *)&ip_hdr(skb)->daddr,
|
||||
spi, IPPROTO_ESP, AF_INET);
|
||||
if (!x)
|
||||
goto out;
|
||||
|
||||
skb->sp->xvec[skb->sp->len++] = x;
|
||||
skb->sp->olen++;
|
||||
|
||||
xo = xfrm_offload(skb);
|
||||
if (!xo) {
|
||||
xfrm_state_put(x);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
xo->flags |= XFRM_GRO;
|
||||
|
||||
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = NULL;
|
||||
|
|
|
@ -45,27 +45,31 @@ static struct sk_buff **esp6_gro_receive(struct sk_buff **head,
|
|||
if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0)
|
||||
goto out;
|
||||
|
||||
err = secpath_set(skb);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (skb->sp->len == XFRM_MAX_DEPTH)
|
||||
goto out;
|
||||
|
||||
x = xfrm_state_lookup(dev_net(skb->dev), skb->mark,
|
||||
(xfrm_address_t *)&ipv6_hdr(skb)->daddr,
|
||||
spi, IPPROTO_ESP, AF_INET6);
|
||||
if (!x)
|
||||
goto out;
|
||||
|
||||
skb->sp->xvec[skb->sp->len++] = x;
|
||||
skb->sp->olen++;
|
||||
|
||||
xo = xfrm_offload(skb);
|
||||
if (!xo) {
|
||||
xfrm_state_put(x);
|
||||
goto out;
|
||||
if (!xo || !(xo->flags & CRYPTO_DONE)) {
|
||||
err = secpath_set(skb);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (skb->sp->len == XFRM_MAX_DEPTH)
|
||||
goto out;
|
||||
|
||||
x = xfrm_state_lookup(dev_net(skb->dev), skb->mark,
|
||||
(xfrm_address_t *)&ipv6_hdr(skb)->daddr,
|
||||
spi, IPPROTO_ESP, AF_INET6);
|
||||
if (!x)
|
||||
goto out;
|
||||
|
||||
skb->sp->xvec[skb->sp->len++] = x;
|
||||
skb->sp->olen++;
|
||||
|
||||
xo = xfrm_offload(skb);
|
||||
if (!xo) {
|
||||
xfrm_state_put(x);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
xo->flags |= XFRM_GRO;
|
||||
|
||||
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = NULL;
|
||||
|
|
|
@ -223,38 +223,38 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
|||
seq = XFRM_SKB_CB(skb)->seq.input.low;
|
||||
goto resume;
|
||||
}
|
||||
|
||||
/* encap_type < -1 indicates a GRO call. */
|
||||
encap_type = 0;
|
||||
seq = XFRM_SPI_SKB_CB(skb)->seq;
|
||||
goto lock;
|
||||
}
|
||||
|
||||
if (xo && (xo->flags & CRYPTO_DONE)) {
|
||||
crypto_done = true;
|
||||
x = xfrm_input_state(skb);
|
||||
family = XFRM_SPI_SKB_CB(skb)->family;
|
||||
if (xo && (xo->flags & CRYPTO_DONE)) {
|
||||
crypto_done = true;
|
||||
x = xfrm_input_state(skb);
|
||||
family = XFRM_SPI_SKB_CB(skb)->family;
|
||||
|
||||
if (!(xo->status & CRYPTO_SUCCESS)) {
|
||||
if (xo->status &
|
||||
(CRYPTO_TRANSPORT_AH_AUTH_FAILED |
|
||||
CRYPTO_TRANSPORT_ESP_AUTH_FAILED |
|
||||
CRYPTO_TUNNEL_AH_AUTH_FAILED |
|
||||
CRYPTO_TUNNEL_ESP_AUTH_FAILED)) {
|
||||
if (!(xo->status & CRYPTO_SUCCESS)) {
|
||||
if (xo->status &
|
||||
(CRYPTO_TRANSPORT_AH_AUTH_FAILED |
|
||||
CRYPTO_TRANSPORT_ESP_AUTH_FAILED |
|
||||
CRYPTO_TUNNEL_AH_AUTH_FAILED |
|
||||
CRYPTO_TUNNEL_ESP_AUTH_FAILED)) {
|
||||
|
||||
xfrm_audit_state_icvfail(x, skb,
|
||||
x->type->proto);
|
||||
x->stats.integrity_failed++;
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
|
||||
xfrm_audit_state_icvfail(x, skb,
|
||||
x->type->proto);
|
||||
x->stats.integrity_failed++;
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
|
||||
goto drop;
|
||||
if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
|
||||
goto lock;
|
||||
|
|
Загрузка…
Ссылка в новой задаче