Lines Matching +full:xo +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
7 * Split up af-specific portion
45 #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0]))
48 static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[2][AF_INET6 + 1];
59 if (WARN_ON(afinfo->family > AF_INET6)) in xfrm_input_register_afinfo()
60 return -EAFNOSUPPORT; in xfrm_input_register_afinfo()
63 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) in xfrm_input_register_afinfo()
64 err = -EEXIST; in xfrm_input_register_afinfo()
66 rcu_assign_pointer(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], afinfo); in xfrm_input_register_afinfo()
77 if (likely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family])) { in xfrm_input_unregister_afinfo()
78 if (unlikely(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family] != afinfo)) in xfrm_input_unregister_afinfo()
79 err = -EINVAL; in xfrm_input_unregister_afinfo()
81 RCU_INIT_POINTER(xfrm_input_afinfo[afinfo->is_ipip][afinfo->family], NULL); in xfrm_input_unregister_afinfo()
112 return -EAFNOSUPPORT; in xfrm_rcv_cb()
114 ret = afinfo->callback(skb, protocol, err); in xfrm_rcv_cb()
132 memset(sp->ovec, 0, sizeof(sp->ovec)); in secpath_set()
133 sp->olen = 0; in secpath_set()
134 sp->len = 0; in secpath_set()
135 sp->verified_cnt = 0; in secpath_set()
161 return -EINVAL; in xfrm_parse_spi()
166 return 1; in xfrm_parse_spi()
170 return -EINVAL; in xfrm_parse_spi()
182 int err = -EINVAL; in xfrm4_remove_beet_encap()
184 skb->protocol = htons(ETH_P_IP); in xfrm4_remove_beet_encap()
186 if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { in xfrm4_remove_beet_encap()
193 ph = (struct ip_beet_phdr *)skb->data; in xfrm4_remove_beet_encap()
195 phlen = sizeof(*ph) + ph->padlen; in xfrm4_remove_beet_encap()
196 optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); in xfrm4_remove_beet_encap()
200 XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr; in xfrm4_remove_beet_encap()
215 iph->ihl += optlen / 4; in xfrm4_remove_beet_encap()
216 iph->tot_len = htons(skb->len); in xfrm4_remove_beet_encap()
217 iph->daddr = x->sel.daddr.a4; in xfrm4_remove_beet_encap()
218 iph->saddr = x->sel.saddr.a4; in xfrm4_remove_beet_encap()
219 iph->check = 0; in xfrm4_remove_beet_encap()
220 iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl); in xfrm4_remove_beet_encap()
230 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip_ecn_decapsulate()
236 int err = -EINVAL; in xfrm4_remove_tunnel_encap()
238 skb->protocol = htons(ETH_P_IP); in xfrm4_remove_tunnel_encap()
247 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm4_remove_tunnel_encap()
248 ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb)); in xfrm4_remove_tunnel_encap()
249 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm4_remove_tunnel_encap()
254 if (skb->mac_len) in xfrm4_remove_tunnel_encap()
255 eth_hdr(skb)->h_proto = skb->protocol; in xfrm4_remove_tunnel_encap()
267 if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos)) in ipip6_ecn_decapsulate()
273 int err = -EINVAL; in xfrm6_remove_tunnel_encap()
275 skb->protocol = htons(ETH_P_IPV6); in xfrm6_remove_tunnel_encap()
284 if (x->props.flags & XFRM_STATE_DECAP_DSCP) in xfrm6_remove_tunnel_encap()
285 ipv6_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipipv6_hdr(skb)); in xfrm6_remove_tunnel_encap()
286 if (!(x->props.flags & XFRM_STATE_NOECN)) in xfrm6_remove_tunnel_encap()
291 if (skb->mac_len) in xfrm6_remove_tunnel_encap()
292 eth_hdr(skb)->h_proto = skb->protocol; in xfrm6_remove_tunnel_encap()
306 skb->protocol = htons(ETH_P_IPV6); in xfrm6_remove_beet_encap()
308 err = skb_cow_head(skb, size + skb->mac_len); in xfrm6_remove_beet_encap()
319 ip6h->payload_len = htons(skb->len - size); in xfrm6_remove_beet_encap()
320 ip6h->daddr = x->sel.daddr.in6; in xfrm6_remove_beet_encap()
321 ip6h->saddr = x->sel.saddr.in6; in xfrm6_remove_beet_encap()
334 * header currently is. skb->data shall point to the start of the
341 switch (x->props.mode) { in xfrm_inner_mode_encap_remove()
343 switch (x->sel.family) { in xfrm_inner_mode_encap_remove()
351 switch (XFRM_MODE_SKB_CB(skb)->protocol) { in xfrm_inner_mode_encap_remove()
358 return -EINVAL; in xfrm_inner_mode_encap_remove()
361 WARN_ON_ONCE(1); in xfrm_inner_mode_encap_remove()
362 return -EOPNOTSUPP; in xfrm_inner_mode_encap_remove()
367 switch (x->props.family) { in xfrm_prepare_input()
375 WARN_ON_ONCE(1); in xfrm_prepare_input()
376 return -EAFNOSUPPORT; in xfrm_prepare_input()
388 * currently is. skb->data shall point to the start of the payload.
392 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm4_transport_input() local
393 int ihl = skb->data - skb_transport_header(skb); in xfrm4_transport_input()
395 if (skb->transport_header != skb->network_header) { in xfrm4_transport_input()
398 if (xo) in xfrm4_transport_input()
399 xo->orig_mac_len = in xfrm4_transport_input()
401 skb->network_header = skb->transport_header; in xfrm4_transport_input()
403 ip_hdr(skb)->tot_len = htons(skb->len + ihl); in xfrm4_transport_input()
411 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm6_transport_input() local
412 int ihl = skb->data - skb_transport_header(skb); in xfrm6_transport_input()
414 if (skb->transport_header != skb->network_header) { in xfrm6_transport_input()
417 if (xo) in xfrm6_transport_input()
418 xo->orig_mac_len = in xfrm6_transport_input()
420 skb->network_header = skb->transport_header; in xfrm6_transport_input()
422 ipv6_hdr(skb)->payload_len = htons(skb->len + ihl - in xfrm6_transport_input()
427 WARN_ON_ONCE(1); in xfrm6_transport_input()
428 return -EAFNOSUPPORT; in xfrm6_transport_input()
435 switch (x->props.mode) { in xfrm_inner_mode_input()
440 if (x->props.family == AF_INET) in xfrm_inner_mode_input()
442 if (x->props.family == AF_INET6) in xfrm_inner_mode_input()
446 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
449 WARN_ON_ONCE(1); in xfrm_inner_mode_input()
453 return -EOPNOTSUPP; in xfrm_inner_mode_input()
459 struct net *net = dev_net(skb->dev); in xfrm_input()
465 u32 mark = skb->mark; in xfrm_input()
471 struct xfrm_offload *xo = xfrm_offload(skb); in xfrm_input() local
474 if (encap_type < 0 || (xo && (xo->flags & XFRM_GRO || encap_type == 0 || in xfrm_input()
478 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
479 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
485 if (encap_type == -1) in xfrm_input()
486 dev_put(skb->dev); in xfrm_input()
490 family = x->props.family; in xfrm_input()
492 /* An encap_type of -1 indicates async resumption. */ in xfrm_input()
493 if (encap_type == -1) { in xfrm_input()
494 async = 1; in xfrm_input()
495 seq = XFRM_SKB_CB(skb)->seq.input.low; 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 if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) { in xfrm_input()
592 skb->mark = xfrm_smark_get(skb->mark, x); in xfrm_input()
594 sp->xvec[sp->len++] = x; in xfrm_input()
603 spin_lock(&x->lock); in xfrm_input()
605 if (unlikely(x->km.state != XFRM_STATE_VALID)) { in xfrm_input()
606 if (x->km.state == XFRM_STATE_ACQ) in xfrm_input()
614 if ((x->encap ? x->encap->encap_type : 0) != encap_type) { in xfrm_input()
629 spin_unlock(&x->lock); in xfrm_input()
638 XFRM_SKB_CB(skb)->seq.input.low = seq; in xfrm_input()
639 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; in xfrm_input()
641 dev_hold(skb->dev); in xfrm_input()
644 nexthdr = x->type_offload->input_tail(x, skb); in xfrm_input()
646 nexthdr = x->type->input(x, skb); in xfrm_input()
648 if (nexthdr == -EINPROGRESS) in xfrm_input()
651 dev_put(skb->dev); in xfrm_input()
653 spin_lock(&x->lock); in xfrm_input()
655 if (nexthdr == -EBADMSG) { in xfrm_input()
657 x->type->proto); in xfrm_input()
658 x->stats.integrity_failed++; in xfrm_input()
674 x->curlft.bytes += skb->len; in xfrm_input()
675 x->curlft.packets++; in xfrm_input()
676 x->lastused = ktime_get_real_seconds(); in xfrm_input()
678 spin_unlock(&x->lock); in xfrm_input()
680 XFRM_MODE_SKB_CB(skb)->protocol = nexthdr; in xfrm_input()
687 if (x->outer_mode.flags & XFRM_MODE_FLAG_TUNNEL) { in xfrm_input()
688 decaps = 1; in xfrm_input()
696 daddr = &x->id.daddr; in xfrm_input()
697 family = x->props.family; in xfrm_input()
707 err = xfrm_rcv_cb(skb, family, x->type->proto, 0); in xfrm_input()
716 sp->olen = 0; in xfrm_input()
722 xo = xfrm_offload(skb); in xfrm_input()
723 if (xo) in xfrm_input()
724 xfrm_gro = xo->flags & XFRM_GRO; in xfrm_input()
726 err = -EAFNOSUPPORT; in xfrm_input()
728 afinfo = xfrm_state_afinfo_get_rcu(x->props.family); in xfrm_input()
730 err = afinfo->transport_finish(skb, xfrm_gro || async); in xfrm_input()
735 sp->olen = 0; in xfrm_input()
746 spin_unlock(&x->lock); in xfrm_input()
748 xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1); in xfrm_input()
756 return xfrm_input(skb, nexthdr, 0, -1); in xfrm_input_resume()
767 spin_lock_bh(&trans->queue_lock); in xfrm_trans_reinject()
768 skb_queue_splice_init(&trans->queue, &queue); in xfrm_trans_reinject()
769 spin_unlock_bh(&trans->queue_lock); in xfrm_trans_reinject()
773 XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net, in xfrm_trans_reinject()
786 if (skb_queue_len(&trans->queue) >= READ_ONCE(net_hotdata.max_backlog)) in xfrm_trans_queue_net()
787 return -ENOBUFS; in xfrm_trans_queue_net()
789 BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb)); in xfrm_trans_queue_net()
791 XFRM_TRANS_SKB_CB(skb)->finish = finish; in xfrm_trans_queue_net()
792 XFRM_TRANS_SKB_CB(skb)->net = net; in xfrm_trans_queue_net()
793 spin_lock_bh(&trans->queue_lock); in xfrm_trans_queue_net()
794 __skb_queue_tail(&trans->queue, skb); in xfrm_trans_queue_net()
795 spin_unlock_bh(&trans->queue_lock); in xfrm_trans_queue_net()
796 schedule_work(&trans->work); in xfrm_trans_queue_net()
805 return xfrm_trans_queue_net(dev_net(skb->dev), skb, finish); in xfrm_trans_queue()
823 spin_lock_init(&trans->queue_lock); in xfrm_input_init()
824 __skb_queue_head_init(&trans->queue); in xfrm_input_init()
825 INIT_WORK(&trans->work, xfrm_trans_reinject); in xfrm_input_init()