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

1 // SPDX-License-Identifier: GPL-2.0
7 * Split up af-specific portion
44 #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0]))
47 static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[2][AF_INET6 + 1];
58 if (WARN_ON(afinfo->family > AF_INET6)) in xfrm_input_register_afinfo()
59 return -EAFNOSUPPORT; in xfrm_input_register_afinfo()
62 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) in xfrm_input_register_afinfo()
63 err = -EEXIST; in xfrm_input_register_afinfo()
65 rcu_assign_pointer(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], afinfo); in xfrm_input_register_afinfo()
76 if (likely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) { in xfrm_input_unregister_afinfo()
77 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family] != afinfo)) in xfrm_input_unregister_afinfo()
78 err = -EINVAL; in xfrm_input_unregister_afinfo()
80 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], NULL); in xfrm_input_unregister_afinfo()
111 return -EAFNOSUPPORT; in xfrm_rcv_cb()
113 ret = afinfo->callback(skb, protocol, err); in xfrm_rcv_cb()
131 memset(sp->ovec, 0, sizeof(sp->ovec)); in secpath_set()
132 sp->olen = 0; in secpath_set()
133 sp->len = 0; in secpath_set()
134 sp->verified_cnt = 0; in secpath_set()
160 return -EINVAL; in xfrm_parse_spi()
165 return 1; in xfrm_parse_spi()
169 return -EINVAL; in xfrm_parse_spi()
181 int err = -EINVAL; in xfrm4_remove_beet_encap()
183 skb->protocol = htons(ETH_P_IP); in xfrm4_remove_beet_encap()
185 if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { in xfrm4_remove_beet_encap()
192 ph = (struct ip_beet_phdr *)skb->data; in xfrm4_remove_beet_encap()
194 phlen = sizeof(*ph) + ph->padlen; in xfrm4_remove_beet_encap()
195 optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); in xfrm4_remove_beet_encap()
199 XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr; in xfrm4_remove_beet_encap()
214 iph->ihl += optlen / 4; in xfrm4_remove_beet_encap()
215 iph->tot_len = htons(skb->len); in xfrm4_remove_beet_encap()
216 iph->daddr = x->sel.daddr.a4; in xfrm4_remove_beet_encap()
217 iph->saddr = x->sel.saddr.a4; in xfrm4_remove_beet_encap()
218 iph->check = 0; in xfrm4_remove_beet_encap()
219 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); in xfrm4_remove_beet_encap()
229 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip_ecn_decapsulate()
235 int err = -EINVAL; in xfrm4_remove_tunnel_encap()
237 skb->protocol = htons(ETH_P_IP); in xfrm4_remove_tunnel_encap()
246 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm4_remove_tunnel_encap()
247 ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb)); in xfrm4_remove_tunnel_encap()
248 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm4_remove_tunnel_encap()
253 if (skb->mac_len) in xfrm4_remove_tunnel_encap()
254 eth_hdr(skb)->h_proto = skb->protocol; in xfrm4_remove_tunnel_encap()
266 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip6_ecn_decapsulate()
272 int err = -EINVAL; in xfrm6_remove_tunnel_encap()
274 skb->protocol = htons(ETH_P_IPV6); in xfrm6_remove_tunnel_encap()
283 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm6_remove_tunnel_encap()
284 ipv6_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipipv6_hdr(skb)); in xfrm6_remove_tunnel_encap()
285 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm6_remove_tunnel_encap()
290 if (skb->mac_len) in xfrm6_remove_tunnel_encap()
291 eth_hdr(skb)->h_proto = skb->protocol; in xfrm6_remove_tunnel_encap()
305 skb->protocol = htons(ETH_P_IPV6); in xfrm6_remove_beet_encap()
307 err = skb_cow_head(skb, size + skb->mac_len); in xfrm6_remove_beet_encap()
318 ip6h->payload_len = htons(skb->len - size); in xfrm6_remove_beet_encap()
319 ip6h->daddr = x->sel.daddr.in6; in xfrm6_remove_beet_encap()
320 ip6h->saddr = x->sel.saddr.in6; in xfrm6_remove_beet_encap()
333 * header currently is. skb->data shall point to the start of the
340 switch (x->props.mode) { in xfrm_inner_mode_encap_remove()
342 switch (x->sel.family) { in xfrm_inner_mode_encap_remove()
350 switch (XFRM_MODE_SKB_CB(skb)->protocol) { in xfrm_inner_mode_encap_remove()
357 return -EINVAL; in xfrm_inner_mode_encap_remove()
360 WARN_ON_ONCE(1); in xfrm_inner_mode_encap_remove()
361 return -EOPNOTSUPP; in xfrm_inner_mode_encap_remove()
366 switch (x->props.family) { in xfrm_prepare_input()
374 WARN_ON_ONCE(1); in xfrm_prepare_input()
375 return -EAFNOSUPPORT; in xfrm_prepare_input()
387 * currently is. skb->data shall point to the start of the payload.
391 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm4_transport_input() local
392 int ihl = skb->data - skb_transport_header(skb); in xfrm4_transport_input()
394 if (skb->transport_header != skb->network_header) { in xfrm4_transport_input()
397 if (xo) in xfrm4_transport_input()
398 xo->orig_mac_len = in xfrm4_transport_input()
400 skb->network_header = skb->transport_header; in xfrm4_transport_input()
402 ip_hdr(skb)->tot_len = htons(skb->len + ihl); in xfrm4_transport_input()
410 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm6_transport_input() local
411 int ihl = skb->data - skb_transport_header(skb); in xfrm6_transport_input()
413 if (skb->transport_header != skb->network_header) { in xfrm6_transport_input()
416 if (xo) in xfrm6_transport_input()
417 xo->orig_mac_len = in xfrm6_transport_input()
419 skb->network_header = skb->transport_header; in xfrm6_transport_input()
421 ipv6_hdr(skb)->payload_len = htons(skb->len + ihl - in xfrm6_transport_input()
426 WARN_ON_ONCE(1); in xfrm6_transport_input()
427 return -EAFNOSUPPORT; in xfrm6_transport_input()
434 switch (x->props.mode) { in xfrm_inner_mode_input()
439 if (x->props.family == AF_INET) in xfrm_inner_mode_input()
441 if (x->props.family == AF_INET6) in xfrm_inner_mode_input()
445 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
448 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
452 return -EOPNOTSUPP; in xfrm_inner_mode_input()
458 struct net *net = dev_net(skb->dev); in xfrm_input()
464 u32 mark = skb->mark; in xfrm_input()
470 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_input() local
476 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
477 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
483 if (encap_type == -1) in xfrm_input()
484 dev_put(skb->dev); in xfrm_input()
488 family = x->props.family; in xfrm_input()
490 /* An encap_type of -1 indicates async resumption. */ in xfrm_input()
491 if (encap_type == -1) { in xfrm_input()
492 async = 1; in xfrm_input()
493 seq = XFRM_SKB_CB(skb)->seq.input.low; in xfrm_input()
497 /* encap_type < -1 indicates a GRO call. */ in xfrm_input()
499 seq = XFRM_SPI_SKB_CB(skb)->seq; in xfrm_input()
501 if (xo && (xo->flags & CRYPTO_DONE)) { in xfrm_input()
503 family = XFRM_SPI_SKB_CB(skb)->family; in xfrm_input()
505 if (!(xo->status & CRYPTO_SUCCESS)) { in xfrm_input()
506 if (xo->status & in xfrm_input()
513 x->type->proto); in xfrm_input()
514 x->stats.integrity_failed++; in xfrm_input()
519 if (xo->status & CRYPTO_INVALID_PROTOCOL) { in xfrm_input()
537 family = XFRM_SPI_SKB_CB(skb)->family; in xfrm_input()
539 /* if tunnel is present override skb->mark value with tunnel i_key */ in xfrm_input()
542 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) in xfrm_input()
543 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key); in xfrm_input()
546 if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6) in xfrm_input()
547 mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key); in xfrm_input()
565 XFRM_SPI_SKB_CB(skb)->daddroff); in xfrm_input()
569 if (sp->len == XFRM_MAX_DEPTH) { in xfrm_input()
583 skb->mark = xfrm_smark_get(skb->mark, x); in xfrm_input()
585 sp->xvec[sp->len++] = x; in xfrm_input()
594 spin_lock(&x->lock); in xfrm_input()
596 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
597 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
605 if ((x->encap ? x->encap->encap_type : 0) != encap_type) { in xfrm_input()
620 spin_unlock(&x->lock); in xfrm_input()
629 XFRM_SKB_CB(skb)->seq.input.low = seq; in xfrm_input()
630 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; in xfrm_input()
632 dev_hold(skb->dev); in xfrm_input()
635 nexthdr = x->type_offload->input_tail(x, skb); in xfrm_input()
637 nexthdr = x->type->input(x, skb); in xfrm_input()
639 if (nexthdr == -EINPROGRESS) in xfrm_input()
642 dev_put(skb->dev); in xfrm_input()
644 spin_lock(&x->lock); in xfrm_input()
646 if (nexthdr == -EBADMSG) { in xfrm_input()
648 x->type->proto); in xfrm_input()
649 x->stats.integrity_failed++; in xfrm_input()
665 x->curlft.bytes += skb->len; in xfrm_input()
666 x->curlft.packets++; in xfrm_input()
667 x->lastused = ktime_get_real_seconds(); in xfrm_input()
669 spin_unlock(&x->lock); in xfrm_input()
671 XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; in xfrm_input()
678 if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) { in xfrm_input()
679 decaps = 1; in xfrm_input()
687 daddr = &x->id.daddr; in xfrm_input()
688 family = x->props.family; in xfrm_input()
698 err = xfrm_rcv_cb(skb, family, x->type->proto, 0); in xfrm_input()
707 sp->olen = 0; in xfrm_input()
713 xo = xfrm_offload(skb); in xfrm_input()
714 if (xo) in xfrm_input()
715 xfrm_gro = xo->flags & XFRM_GRO; in xfrm_input()
717 err = -EAFNOSUPPORT; in xfrm_input()
719 afinfo = xfrm_state_afinfo_get_rcu(x->props.family); in xfrm_input()
721 err = afinfo->transport_finish(skb, xfrm_gro || async); in xfrm_input()
726 sp->olen = 0; in xfrm_input()
737 spin_unlock(&x->lock); in xfrm_input()
739 xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1); in xfrm_input()
747 return xfrm_input(skb, nexthdr, 0, -1); in xfrm_input_resume()
758 spin_lock_bh(&trans->queue_lock); in xfrm_trans_reinject()
759 skb_queue_splice_init(&trans->queue, &queue); in xfrm_trans_reinject()
760 spin_unlock_bh(&trans->queue_lock); in xfrm_trans_reinject()
764 XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net, in xfrm_trans_reinject()
777 if (skb_queue_len(&trans->queue) >= READ_ONCE(netdev_max_backlog)) in xfrm_trans_queue_net()
778 return -ENOBUFS; in xfrm_trans_queue_net()
780 BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb)); in xfrm_trans_queue_net()
782 XFRM_TRANS_SKB_CB(skb)->finish = finish; in xfrm_trans_queue_net()
783 XFRM_TRANS_SKB_CB(skb)->net = net; in xfrm_trans_queue_net()
784 spin_lock_bh(&trans->queue_lock); in xfrm_trans_queue_net()
785 __skb_queue_tail(&trans->queue, skb); in xfrm_trans_queue_net()
786 spin_unlock_bh(&trans->queue_lock); in xfrm_trans_queue_net()
787 schedule_work(&trans->work); in xfrm_trans_queue_net()
796 return xfrm_trans_queue_net(dev_net(skb->dev), skb, finish); in xfrm_trans_queue()
814 spin_lock_init(&trans->queue_lock); in xfrm_input_init()
815 __skb_queue_head_init(&trans->queue); in xfrm_input_init()
816 INIT_WORK(&trans->work, xfrm_trans_reinject); in xfrm_input_init()