Lines Matching +full:xo +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
7 * Split up af-specific portion
42 #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0]))
45 static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[2][AF_INET6 + 1];
56 if (WARN_ON(afinfo->family > AF_INET6)) in xfrm_input_register_afinfo()
57 return -EAFNOSUPPORT; in xfrm_input_register_afinfo()
60 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) in xfrm_input_register_afinfo()
61 err = -EEXIST; in xfrm_input_register_afinfo()
63 rcu_assign_pointer(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], afinfo); in xfrm_input_register_afinfo()
74 if (likely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) { in xfrm_input_unregister_afinfo()
75 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family] != afinfo)) in xfrm_input_unregister_afinfo()
76 err = -EINVAL; in xfrm_input_unregister_afinfo()
78 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], NULL); in xfrm_input_unregister_afinfo()
109 return -EAFNOSUPPORT; in xfrm_rcv_cb()
111 ret = afinfo->callback(skb, protocol, err); in xfrm_rcv_cb()
129 memset(sp->ovec, 0, sizeof(sp->ovec)); in secpath_set()
130 sp->olen = 0; in secpath_set()
131 sp->len = 0; in secpath_set()
157 return -EINVAL; in xfrm_parse_spi()
162 return 1; in xfrm_parse_spi()
166 return -EINVAL; in xfrm_parse_spi()
178 int err = -EINVAL; in xfrm4_remove_beet_encap()
180 if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { in xfrm4_remove_beet_encap()
187 ph = (struct ip_beet_phdr *)skb->data; in xfrm4_remove_beet_encap()
189 phlen = sizeof(*ph) + ph->padlen; in xfrm4_remove_beet_encap()
190 optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); in xfrm4_remove_beet_encap()
194 XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr; in xfrm4_remove_beet_encap()
209 iph->ihl += optlen / 4; in xfrm4_remove_beet_encap()
210 iph->tot_len = htons(skb->len); in xfrm4_remove_beet_encap()
211 iph->daddr = x->sel.daddr.a4; in xfrm4_remove_beet_encap()
212 iph->saddr = x->sel.saddr.a4; in xfrm4_remove_beet_encap()
213 iph->check = 0; in xfrm4_remove_beet_encap()
214 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); in xfrm4_remove_beet_encap()
224 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip_ecn_decapsulate()
230 int err = -EINVAL; in xfrm4_remove_tunnel_encap()
232 if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) in xfrm4_remove_tunnel_encap()
242 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm4_remove_tunnel_encap()
243 ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb)); in xfrm4_remove_tunnel_encap()
244 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm4_remove_tunnel_encap()
249 if (skb->mac_len) in xfrm4_remove_tunnel_encap()
250 eth_hdr(skb)->h_proto = skb->protocol; in xfrm4_remove_tunnel_encap()
262 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip6_ecn_decapsulate()
268 int err = -EINVAL; in xfrm6_remove_tunnel_encap()
270 if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) in xfrm6_remove_tunnel_encap()
279 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm6_remove_tunnel_encap()
282 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm6_remove_tunnel_encap()
287 if (skb->mac_len) in xfrm6_remove_tunnel_encap()
288 eth_hdr(skb)->h_proto = skb->protocol; in xfrm6_remove_tunnel_encap()
302 err = skb_cow_head(skb, size + skb->mac_len); in xfrm6_remove_beet_encap()
313 ip6h->payload_len = htons(skb->len - size); in xfrm6_remove_beet_encap()
314 ip6h->daddr = x->sel.daddr.in6; in xfrm6_remove_beet_encap()
315 ip6h->saddr = x->sel.saddr.in6; in xfrm6_remove_beet_encap()
328 * header currently is. skb->data shall point to the start of the
336 switch (inner_mode->encap) { in xfrm_inner_mode_encap_remove()
338 if (inner_mode->family == AF_INET) in xfrm_inner_mode_encap_remove()
340 if (inner_mode->family == AF_INET6) in xfrm_inner_mode_encap_remove()
344 if (inner_mode->family == AF_INET) in xfrm_inner_mode_encap_remove()
346 if (inner_mode->family == AF_INET6) in xfrm_inner_mode_encap_remove()
351 WARN_ON_ONCE(1); in xfrm_inner_mode_encap_remove()
352 return -EOPNOTSUPP; in xfrm_inner_mode_encap_remove()
357 const struct xfrm_mode *inner_mode = &x->inner_mode; in xfrm_prepare_input()
359 switch (x->outer_mode.family) { in xfrm_prepare_input()
367 WARN_ON_ONCE(1); in xfrm_prepare_input()
368 return -EAFNOSUPPORT; in xfrm_prepare_input()
371 if (x->sel.family == AF_UNSPEC) { in xfrm_prepare_input()
372 inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); in xfrm_prepare_input()
374 return -EAFNOSUPPORT; in xfrm_prepare_input()
377 switch (inner_mode->family) { in xfrm_prepare_input()
379 skb->protocol = htons(ETH_P_IP); in xfrm_prepare_input()
382 skb->protocol = htons(ETH_P_IPV6); in xfrm_prepare_input()
385 WARN_ON_ONCE(1); in xfrm_prepare_input()
398 * currently is. skb->data shall point to the start of the payload.
402 int ihl = skb->data - skb_transport_header(skb); in xfrm4_transport_input()
404 if (skb->transport_header != skb->network_header) { in xfrm4_transport_input()
407 skb->network_header = skb->transport_header; in xfrm4_transport_input()
409 ip_hdr(skb)->tot_len = htons(skb->len + ihl); in xfrm4_transport_input()
417 int ihl = skb->data - skb_transport_header(skb); in xfrm6_transport_input()
419 if (skb->transport_header != skb->network_header) { in xfrm6_transport_input()
422 skb->network_header = skb->transport_header; in xfrm6_transport_input()
424 ipv6_hdr(skb)->payload_len = htons(skb->len + ihl - in xfrm6_transport_input()
429 WARN_ON_ONCE(1); in xfrm6_transport_input()
430 return -EAFNOSUPPORT; in xfrm6_transport_input()
438 switch (inner_mode->encap) { in xfrm_inner_mode_input()
443 if (inner_mode->family == AF_INET) in xfrm_inner_mode_input()
445 if (inner_mode->family == AF_INET6) in xfrm_inner_mode_input()
449 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
452 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
456 return -EOPNOTSUPP; in xfrm_inner_mode_input()
462 struct net *net = dev_net(skb->dev); in xfrm_input()
469 u32 mark = skb->mark; in xfrm_input()
475 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_input() local
481 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
482 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
488 if (encap_type == -1) in xfrm_input()
489 dev_put(skb->dev); in xfrm_input()
493 family = x->outer_mode.family; in xfrm_input()
495 /* An encap_type of -1 indicates async resumption. */ in xfrm_input()
496 if (encap_type == -1) { in xfrm_input()
497 async = 1; in xfrm_input()
498 seq = XFRM_SKB_CB(skb)->seq.input.low; in xfrm_input()
502 /* encap_type < -1 indicates a GRO call. */ in xfrm_input()
504 seq = XFRM_SPI_SKB_CB(skb)->seq; in xfrm_input()
506 if (xo && (xo->flags & CRYPTO_DONE)) { in xfrm_input()
508 family = XFRM_SPI_SKB_CB(skb)->family; in xfrm_input()
510 if (!(xo->status & CRYPTO_SUCCESS)) { in xfrm_input()
511 if (xo->status & in xfrm_input()
518 x->type->proto); in xfrm_input()
519 x->stats.integrity_failed++; in xfrm_input()
524 if (xo->status & CRYPTO_INVALID_PROTOCOL) { in xfrm_input()
542 family = XFRM_SPI_SKB_CB(skb)->family; in xfrm_input()
544 /* if tunnel is present override skb->mark value with tunnel i_key */ in xfrm_input()
547 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) in xfrm_input()
548 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); in xfrm_input()
551 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) in xfrm_input()
552 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); in xfrm_input()
570 XFRM_SPI_SKB_CB(skb)->daddroff); in xfrm_input()
574 if (sp->len == XFRM_MAX_DEPTH) { in xfrm_input()
588 skb->mark = xfrm_smark_get(skb->mark, x); in xfrm_input()
590 sp->xvec[sp->len++] = x; in xfrm_input()
599 spin_lock(&x->lock); in xfrm_input()
601 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
602 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
610 if ((x->encap ? x->encap->encap_type : 0) != encap_type) { in xfrm_input()
615 if (x->repl->check(x, skb, seq)) { in xfrm_input()
625 spin_unlock(&x->lock); in xfrm_input()
634 XFRM_SKB_CB(skb)->seq.input.low = seq; in xfrm_input()
635 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; in xfrm_input()
637 dev_hold(skb->dev); in xfrm_input()
640 nexthdr = x->type_offload->input_tail(x, skb); in xfrm_input()
642 nexthdr = x->type->input(x, skb); in xfrm_input()
644 if (nexthdr == -EINPROGRESS) in xfrm_input()
647 dev_put(skb->dev); in xfrm_input()
649 spin_lock(&x->lock); in xfrm_input()
651 if (nexthdr == -EBADMSG) { in xfrm_input()
653 x->type->proto); in xfrm_input()
654 x->stats.integrity_failed++; in xfrm_input()
663 if (x->repl->recheck(x, skb, seq)) { in xfrm_input()
668 x->repl->advance(x, seq); in xfrm_input()
670 x->curlft.bytes += skb->len; in xfrm_input()
671 x->curlft.packets++; in xfrm_input()
673 spin_unlock(&x->lock); in xfrm_input()
675 XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; in xfrm_input()
677 inner_mode = &x->inner_mode; in xfrm_input()
679 if (x->sel.family == AF_UNSPEC) { in xfrm_input()
680 inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); in xfrm_input()
692 if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) { in xfrm_input()
693 decaps = 1; in xfrm_input()
701 daddr = &x->id.daddr; in xfrm_input()
702 family = x->outer_mode.family; in xfrm_input()
712 err = xfrm_rcv_cb(skb, family, x->type->proto, 0); in xfrm_input()
721 sp->olen = 0; in xfrm_input()
726 xo = xfrm_offload(skb); in xfrm_input()
727 if (xo) in xfrm_input()
728 xfrm_gro = xo->flags & XFRM_GRO; in xfrm_input()
730 err = -EAFNOSUPPORT; in xfrm_input()
732 afinfo = xfrm_state_afinfo_get_rcu(x->inner_mode.family); in xfrm_input()
734 err = afinfo->transport_finish(skb, xfrm_gro || async); in xfrm_input()
739 sp->olen = 0; in xfrm_input()
749 spin_unlock(&x->lock); in xfrm_input()
751 xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1); in xfrm_input()
759 return xfrm_input(skb, nexthdr, 0, -1); in xfrm_input_resume()
770 skb_queue_splice_init(&trans->queue, &queue); in xfrm_trans_reinject()
773 XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net, in xfrm_trans_reinject()
785 if (skb_queue_len(&trans->queue) >= READ_ONCE(netdev_max_backlog)) in xfrm_trans_queue_net()
786 return -ENOBUFS; in xfrm_trans_queue_net()
788 BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb)); in xfrm_trans_queue_net()
790 XFRM_TRANS_SKB_CB(skb)->finish = finish; in xfrm_trans_queue_net()
791 XFRM_TRANS_SKB_CB(skb)->net = net; in xfrm_trans_queue_net()
792 __skb_queue_tail(&trans->queue, skb); in xfrm_trans_queue_net()
793 tasklet_schedule(&trans->tasklet); in xfrm_trans_queue_net()
802 return xfrm_trans_queue_net(dev_net(skb->dev), skb, finish); in xfrm_trans_queue()
820 __skb_queue_head_init(&trans->queue); in xfrm_input_init()
821 tasklet_init(&trans->tasklet, xfrm_trans_reinject, in xfrm_input_init()