From: Christian Hopps <cho...@chopps.org> Date: Friday 26 June 2020 at 12:13 To: "Neale Ranns (nranns)" <nra...@cisco.com> Cc: Christian Hopps <cho...@chopps.org>, vpp-dev <vpp-dev@lists.fd.io> Subject: Re: [vpp-dev] ipsec interface revisted.
On Jun 26, 2020, at 4:22 AM, Neale Ranns (nranns) <nra...@cisco.com<mailto:nra...@cisco.com>> wrote: Hi Chris, As far as I'm concerned, it's your plugin, you can add whatever functionality you need. If you separate the new interface type out into another plugin, so it can be used without your feature, then the community will benefit twice. Let's just make sure we document the whys and hows of each model. My preferred outcome though would be to try and find a way for your feature to work with the existing model. If you'd like to explore those possibilities perhaps we could discuss code specifics. Hi Neale, I can try some code specifics. A major part of IPTFS is the constructing of the inner ESP payload, and emitting this with specific timing disassociated with the carried user traffic as described previously (and documented in https://tools.ietf.org/html/draft-ietf-ipsecme-iptfs-01). I'm going to leave out optimizations that may re-use buffers etc.. to keep things simple.. This IPTFS machinery receives and terminates the user (protected) packet buffer through the graph. IPTFS encapsulates this user packet into 1 or more IPTFS payloads along with other user traffic to the same SA. It then paces the output of these IPTFS payloads on a disconnected output worker. These IPTFS payloads are passed on to the esp_encrypt for adding ESP and the outer tunnel encap. So: e.g., No IPTFS, SA tunnel mode. [IP-A] [IP-A] [IPsec-IP|ESP|IP-A] worker A: [IP-A] -> ipsec-output -> esp-encrypt [outer-encap added] -> ip-lookup ... -> "if-tx" [IP-B] [IP-B] [IPsec-IP|ESP|IP-B] worker A: [IP-A] -> ipsec-output -> esp-encrypt [outer-encap added] -> ip-lookup ... -> "if-tx" [IP-C] [IP-C] [IPsec-IP|ESP|IP-C] worker A: [IP-A] -> ipsec-output -> esp-encrypt [outer-encap added] -> ip-lookup ... -> "if-tx" IPTFS: [IP-A] [IP-A] [TFS|IP-A] worker A: ipsec-output -> iptfs-encap-enq -> encapsualte with other user traffic construct in PACEQ [IP-B] [IP-B] [TFS|IP-A|IP-B] worker A: ipsec-output -> iptfs-encap-enq -> encapsualte with other user traffic construct in PACEQ [IP-C] [IP-C] [TFS|IP-A|IP-B|IP-C] worker A: ipsec-output -> iptfs-encap-enq -> encapsualte with other user traffic construct in PACEQ [TFS|IP-A|IP-B|IP-C] worker A: PACEQ -> iptfs-pacer (timed) enqueue to OUTQ [TFS|IP-A|IP-B|IP-C] [TFS|IP-A|IP-B|IP-C] [IPsec-IP|ESP|TFS|IP-A|IP-B|IP-C] worker B: OUTQ -> iptfs_output (timed) -> esp-encrypt [outer-encap added] -> ip-lookup ... -> "if-tx" Code Details (where does IPTFS hook): SA Policy Directed in ipsec_output_inline if (p0->policy == IPSEC_POLICY_ACTION_PROTECT) { ... if (sa->protocol == IPSEC_PROTOCOL_ESP) { if (ipsec_sa_is_IPTFS (sa)) next_node_index = im->tfs_encap_node_index; else if (is_ipv6) next_node_index = im->esp6_encrypt_node_index; else next_node_index = im->esp4_encrypt_node_index; Interface Directed [iptfs init code] ipsec_add_feature ("ip4-output", "iptfs-encap4-tun", &tfsm->encap4_tun_feature_index); [tunnel create code] In ipsec_tunnel_feature_set Instead of: arc = vnet_get_feature_arc_index ("ip4-output"); vnet_feature_enable_disable_with_index (arc, esp4_feature_index, t->sw_if_index, enable, &t->output_sa_index, sizeof (t->output_sa_index)); A callback is made to the TFS code which does: arc = vnet_get_feature_arc_index ("ip4-output"); vnet_feature_enable_disable_with_index ( arc, tfsm->encap4_tun_feature_index, t->sw_if_index, enable, &t->output_sa_index, sizeof (t->output_sa_index)); This latter Interface Directed code is what has been removed from VPP. The packets I receive on this path were not not (and should not) be already pre-encapsulated with any outer tunnel IP header, or I'm going to have to immediately remove this encap before placing the user traffic in the the TFS payload (see above). Having the overhead of adding an IP header, then immediately removing it simply to get traffic directed to my IPTFS encap routine is not a reasonable replacement. Reasonable or otherwise, that’s what the model would expect. All output features get packets with encap already applied, since the output feature arc is invoked post encap. You’ll notice that when running in the SPD context, you need to strip the ethernet encap too. You can ‘pre-compile’ the ip-header encap you will need to add post doing your magic, then set the length and update the checksum before sending (an example in adj_midchain_ipip44_fixup()). So the "new model" in VPP is that I have to add a non-encapsulating interface to direct the user traffic to me for TFS processing (i.e., unencapsulated). This interface is going to bear a striking resemblance to the one that was just removed from 19.08 VPP. :) Here is an implementation of a dedicated IPSec interface. It adds no encap in the adj rewrite, so your feature will not receive packets with any tunnel encap. I have kept the current model’s separation of interface creation from SA protection, since there are benefits to routing to have the interface present before the SAs are negotiated. Consequently, one still uses the ipsec_tun_protect API but all protecting SAs must be in tunnel mode. The midchain adjacency is stacked on the SA’s destination so the once encrypt is complete the next node is adj-midchain-tx and the packet is shipped to the peer. There’s some more detail in ipsec_itf.h on hows ad whys. Let me know if this is what you need. For rx have you added a ip-protocol dispatch in the decypt? If so we can upstream that change in this patch if you like. /neale Thanks, Chris. /neale tpyed by my fat tumhbs
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#16884): https://lists.fd.io/g/vpp-dev/message/16884 Mute This Topic: https://lists.fd.io/mt/74962223/21656 Group Owner: vpp-dev+ow...@lists.fd.io Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-