--- zzzz-none-000/linux-5.4.213/net/xfrm/xfrm_output.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/net/xfrm/xfrm_output.c 2024-08-14 09:02:15.000000000 +0000 @@ -15,9 +15,13 @@ #include #include #include +#include +#include #include "xfrm_inout.h" +static struct avm_pa_dev_info xfrm_out_dev_info __read_mostly; + static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb); static int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); @@ -502,10 +506,22 @@ struct net *net = xs_net(skb_dst(skb)->xfrm); while (likely((err = xfrm_output_one(skb, err)) == 0)) { - nf_reset_ct(skb); + nf_reset_no_generic_ct(skb); - err = skb_dst(skb)->ops->local_out(net, skb->sk, skb); - if (unlikely(err != 1)) + if (!skb_dst(skb)->xfrm) { + /* Now encrypted, try to accelerate the other half. + * The skb must be reset to allow for a secondary session. + */ + avm_pa_reset_skb(skb); + } + /* We want to invert the likely indication because avm_pa + * very likely accelerates the packet. We take the opportunity + * and do a direct call optimization as well. + */ + err = INDIRECT_CALL_INET(skb_dst(skb)->ops->local_out, + __ip6_local_out, __ip_local_out, + net, skb->sk, skb); + if (likely(err != 1)) /* likely accelerated by avm_pa */ goto out; if (!skb_dst(skb)->xfrm) @@ -570,6 +586,8 @@ secpath_reset(skb); + avm_pa_add_xfrm_session(&xfrm_out_dev_info, skb, skb_dst(skb)->xfrm); + if (xfrm_dev_offload_ok(skb, x)) { struct sec_path *sp; @@ -658,3 +676,32 @@ } } EXPORT_SYMBOL_GPL(xfrm_local_error); + +static void xfrm_out_transmit(void *arg, struct sk_buff *skb) +{ + int ret; + + ret = xfrm_output(NULL, skb); + if (unlikely(ret < 0)) + net_err_ratelimited("%s failed: %d\n", __func__, ret); +} + +static void __init xfrm_output_avm_pa_register(void) +{ + struct avm_pa_pid_cfg cfg = {0}; + int ret; + + snprintf(cfg.name, sizeof(cfg.name), "xfrm_out"); + cfg.framing = avm_pa_framing_ipdev; + cfg.default_mtu = 0xffff; + cfg.tx_func = xfrm_out_transmit; + ret = avm_pa_dev_pid_register(&xfrm_out_dev_info, &cfg); + if (ret < 0) + pr_err("%s: failed to register avm_pa pid %s: %d\n", + __func__, cfg.name, ret); +} + +void __init xfrm_output_init(void) +{ + xfrm_output_avm_pa_register(); +}