> On May 11, 2020, at 9:56 AM, Neale Ranns (nranns) <nra...@cisco.com> wrote:
> 
> 
> 
> On 11/05/2020 14:28, "Christian Hopps" <cho...@chopps.org> wrote:
> 
> 
> 
>> On May 11, 2020, at 7:50 AM, Neale Ranns (nranns) <nra...@cisco.com> wrote:
>> 
>> 
>> 
>> From: <vpp-dev@lists.fd.io> on behalf of Christian Hopps <cho...@chopps.org>
>> Date: Sunday 10 May 2020 at 14:33
>> 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 tunnel interfaces?
>> 
>>> On May 9, 2020, at 7:23 AM, Neale Ranns via lists.fd.io 
>>> <nranns=cisco....@lists.fd.io> wrote:
>>> 
>>> 
>>> 
>>> Hi Chris,
>>> 
>>> 
>>>> Are there other properties of a tunnel mode SA that you need that are lost 
>>>> with this approach?
>>> 
>>> I need to use tunnel mode SAs provided by IKEv2. Transport mode is an 
>>> optional (normally on-the-wire IKEv2 negotiated) feature of IPsec. These 
>>> tunnel mode SAs will have IPTFS enabled on them, and that functionality is 
>>> only defined for IPsec tunnel mode SAs.
>>> 
>>> 
>>> The only difference in VPP between a transport and tunnel mode SA is the 
>>> presence of the encap. So I think it’s fair to say that what you need is an 
>>> interface to interact with the L[23] system, ‘encap’ to describe how to 
>>> encap/decap packets (i.e. what to copy from overlay/underlay (DSCP, ECN, 
>>> etc) and an SA (for the algo set);
>>> 
>>>  Interface + encap + SA
>>> 
>>> VPP doesn’t model encap separately. So it’s a question of where you add the 
>>> parenthesis.
>>> 
>>>  (interface + encap) + SA = ipip tunnel + transport mode SA
>>> 
>>> Or
>>> 
>>>  Interface + (encap + SA) = ipsec dedicated interface + tunnel mode SA
>>> 
>>> In both cases the same information is available, it’s just modelled 
>>> differently. The first model is used since it reuses the 
>>> types/functionality that VPP already has to support other use case, without 
>>> the need for a dedicated interface type. Is it not possible for you to work 
>>> with the first model, or is it less convenient?
>> 
>> SO, I have implemented 
>> https://tools.ietf.org/html/draft-ietf-ipsecme-iptfs-01 in VPP 19.08. The 
>> functionality is working as specified in the draft using tunnel mode SAs.
>> 
>> Conceptually what happens (commonly) is this:
>> 
>> 
>> Pkt   Pkt                                                     Single IPsec 
>> Tunnel Pkt
>> ---   ---                                             
>> --------------------------------------
>> [UA]..[Un] ---> user-intf [ VPP ] sa-tunnel-intf ---> [IP(SATunnel) + ESP + 
>> [UA]..[Un][Pad]]
>> 
>> 
>> The encpasulation *has* to occur at the SA tunnel point, not 
>> pre-encapsulated by a generic IP-IP interface with a transport mode SA 
>> attached to it downstream.
>> 
>> This is the condition I don’t fully understand….
>> 
>> 
>> The key here is that there is not a 1-1 mapping of user IP packets to IPsec 
>> packets. FWIW, this isn't just a problem for this particular IPTFS 
>> technology, there are other simple cases (e.g., sending only pad IPsec 
>> packets for limited traffic flow confidentiality) where there is not a 1-1 
>> mapping between user IP packets and SA tunnel mode packets.
>> 
>> Now, re-architecting IPTFS to exist outside of IPsec so that it could be a 
>> new generic IP tunnel technology is certainly a fun idea (topic for another 
>> thread), it's just not an option, or relevant to the functionality that 
>> appears to have been lost in VPP.
>> 
>> Here's a packet trace for how this works (incoming ping):
>> 
>> USER-SIDE:
>> 
>> 00:00:08:845351: dpdk-input
>>  ...
>>  ICMP echo_request checksum 0xaea9
>> 00:00:08:845366: ethernet-input
>> 00:00:08:845382: ip4-input-no-checksum
>>  ICMP: 11.11.11.253 -> 12.12.12.12
>>  ICMP echo_request checksum 0xaea9
>> 00:00:08:845389: ip4-lookup
>>  ICMP: 11.11.11.253 -> 12.12.12.12
>>  ICMP echo_request checksum 0xaea9
>> 00:00:08:845396: ip4-midchain
>>    ICMP: 11.11.11.253 -> 12.12.12.12
>>    ICMP echo_request checksum 0xaea9
>> 00:00:08:845402: iptfs-encap4-tun
>>  sa_index: 1
>> 
>> At this point in old code, the packet does not have the tunnel encap added, 
>> it new code it does.
> 
>    Right, so this is the problem, at this point -- pre-ipsec encapsulation -- 
> in the arc I am collecting (aggregating multiple user IP packets) into a 
> single payload to send over the IPsec SA tunnel. I can't have IP-IP packets 
> here.
> 
>    It's not OK to have to strip off superfluous IP headers (thus having paid 
> a price to have them added, only to be immediately removed in the next node 
> in the graph) from all the user packets just so I can get back to the 
> functionality I had before 20.01, that's not the same behavior. :)
> 
>> AGGREGATING AND QUEUEING OCCURS - The packet is encapsulated (along with any 
>> others currently waiting) into the next-to-be-sent IPTFS packet, which is 
>> queued to be sent on a timer from another thread, that output thread follows:
>> 
>> 
>> SEUCRE-SIDE:
>> 
>> Packet 1
>> 
>> This is the next IPTFS packet to send (in this case it just has the 1 ping 
>> packet inside but usually has multiple when there's real traffic):
>> 
>> 00:00:08:851581: handoff_trace
>>   HANDED-OFF: from thread 1 trace index 0
>> 00:00:08:851581: iptfs-output
>>     IPTFS Basic Header: flags: 0 resv 0 offset 0:[output gen: 526 pkt 0 of 
>> 1]:
>>     datablock  0: type: IPv4 offset:    4 pktlen:   84
>>     datablock  1: type: Pad  offset:   88 pktlen: 1382
>> 
>> In old code here you present the next crypto node with your IPTFS ‘frame’, 
>> i.e. payload. In new code you need to present this frame with the tunnel 
>> encap prepended and correct (IIUC your draft correctly your not playing 
>> tricks with the outer IP header’s length, so you don’t need control over how 
>> the ESP header/footer is crafted – it’s the ‘normal’ way). You can either do 
>> this by preserving and updating the encap that was on one of the original 
>> buffers, or slap on a new one. You can query the tunnel’s encap similarly to 
>> the way ipsec_tun_protect_update() does and make it available in the 
>> feature’s node.
> 
>    When you describe "preserve and update the encap" this is what I was 
> talking about when I said that will have to do more standards work to handle 
> the common cisco "gre+transport mode" ipsec case. This isn't the only way 
> people use IPsec though (IP tunnel w/ transport mode IPsec). I'm just 
> providing one counter example with IPTFS.
> 
> While it's flattering to think the VPP's implementation is what drives the 
> standards process, I doubt that's the case __ You write standards based on 
> externally visible behaviour, how any given implementation implements that 
> standard is a different matter. I appreciate running code is helpful to the 
> process though.

Just to be clear, we are in fact working on support in IETF/ipsecme to handle 
transport mode SAs, and this is largely driven by the GRE+transport case that 
is in common use.

This isn't being driven by VPPs 20.01 changes though. :)

We (IETF) really do need to specify how this works with transport mode SAs 
which inherit their transport from the user traffic.

> 
>    I think what's happened here is that the reworking of the VPP ipsec code 
> was an optimization/factorization that looked OK at the time; however, it was 
> founded on assumptions about equivalencies that don't actually exist in the 
> actual standardized IPsec framework.
> 
> I'd genuinely like to see standards work on the use of logical interfaces, as 
> opposed to the SPD approach.
> 
>    IOW it seems the VPP code was optimized for some common use cases, but 
> eliminated the ability to code to other use-cases that don't fit that common 
> pattern.
> 
> Optimised for all the cases that are supported in the repository, nudge 
> nudge...

Heh, the IPTFS code is being developed with the full intention of open sourcing 
(and upstreaming to VPP). :) 

> 
>    Is it *really* that big a deal to have a logical interface represent a 
> tunnel mode SA? It actually seems a fairly elegant to me. Instead of tossing 
> it out, why not just clean up the objectionable API pieces? The current 
> changes can continue to be used for the GRE tunnel case, so the current work 
> is not lost either.
> 
> We seem to have come full circle... there is a logical interface, it's called 
> ipipX. Clearly the name of the interface is not important.
> The logical interface shouldn't represent the SA, it should represent the 
> peering, and it's the peering that defines the encap. I say this because SAs 
> come and go as rekeying occurs, but the peering remains. You don't want to 
> delete your interface and recreate all your routes, each time you rekey. In 
> fact there's a good test; if the peering addresses can 
> regularly/reasonably/etc change during a rekey, then the ipip case is 
> definitely worse, since one would need to create a new ipip tunnel and IMO 
> that would justify a different interface type.
> 
> What would be preferable/more efficient for your feature is if the encap were 
> applied after your feature is run, but do I really need a new interface type 
> just for that? let me see what I can do.

Fantastic. :)

Thanks,
Chris.

> 
> /neale
> 
> 
>    Thanks,
>    Chris.
> 
> 
> 
>> …. so here is the change from tunnel mode to transport mode, but with the 
>> above changes, would this result in the correct packet on the wire?
>> 
>> 
>> 
>> 00:00:08:851622: dpdk-esp4-encrypt
>>   spi 1112 seq 1 seq_hi 0 iv_size 0 trunc_size 0
>>   pad_bytes 0 next_header 143
>>   cipher none auth none
>>     IPTFS Basic Header: flags: 0 resv 0 offset 0
>> 
>> This is the output from the DPDK encryption offload (same packet as above 
>> but encrypted)
>> 
>> Packet 2
>> 
>> 00:00:08:851659: dpdk-crypto-input
>>   cryptodev-id 0 next-index 1
>> 00:00:08:851663: ip4-lookup
>>   fib 0 dpo-idx 3 flow hash: 0x00000000
>>   IPSEC_ESP: 13.13.13.11 -> 13.13.13.12
>> 00:00:08:851671: ip4-rewrite
>> 00:00:08:851676: TenGigabitEthernet65/0/1-output
>>   TenGigabitEthernet65/0/1
>>   IP4: f8:f2:1e:3c:08:29 -> f8:f2:1e:3c:09:b1
>>   IPSEC_ESP: 13.13.13.11 -> 13.13.13.12
>> 00:00:08:851682: TenGigabitEthernet65/0/1-tx
>>   TenGigabitEthernet65/0/1 tx queue 5
>>   buffer 0x3feb11e: current data -32, length 1514, buffer-pool 0, ref-count 
>> 1, totlen-nifb 0, trace handle 0x5000001
>> 
>> 
>> To arrive at this setup the code I add myself as a feature.
>> 
>>  VNET_FEATURE_INIT (iptfs_encap4_tun_feat_node, static) = {
>>    .arc_name = "ip4-output",
>>    .node_name = "iptfs-encap4-tun",
>>    .runs_before = VNET_FEATURES ("esp4-encrypt-tun", 
>> "dpdk-esp4-encrypt-tun"),
>>  };
>> 
>>  ipsec_add_feature ("ip4-output", "iptfs-encap4-tun",
>>                     &tfsm->encap4_tun_feature_index);
>> 
>> then inside ipsec_tunnel_feature_set I do (in a callback, but whatever):
>> 
>>  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));
>> 
>> To enable the IPTFS feature on the ipsec* interface arc.
>> 
>> This part remains the same.
>> 
>> 
>> 
>> If I have missed a simple way to do this with the new code, I'm all ears and 
>> thankful for help. :)
>> 
>> 
>> I usually find that simple is in the eye of the beholder … but let me know 
>> if it can work 😊
>> 
>> Maybe slightly off topic, but do you get accurate output stats on the ipsec 
>> interface? In that trace I don’t see a node that would count.
>> 
>> /neale
>> 
>> 
>> 
>> 
>> 
>> Thanks,
>> Chris.
>> 
>> 
>>> 
>>> /neale
>>> 
>>> 
>>> 
>>> 
>>> There will be future work in IETF/ipsecme to enable a form of transport 
>>> mode support in IPTFS to handle the Cisco-preferred GRE with transport mode 
>>> IPsec configuration, but that is not available today, and obviously won't 
>>> be the only option standardized.
>>> 
>>> Thanks,
>>> Chris.
>>> 
>>> 
>>>> /neale
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> Thanks,
>>>> Chris.
>>>> 
>>>> 
>>>>> 
>>>>>   I did read through the Wiki and it seems that this change was motivated 
>>>>> by wanting to cleanup the IPsec API, but that hardly seems like 
>>>>> justification to eliminate the efficient use of an entire variant of 
>>>>> commonly used IPsec functionality.
>>>>> 
>>>>> Cleaning up the API was one motivation. It was a pain that each time we 
>>>>> added new attributes to SA creation (like ESN, UDP, algo=foo) (for use 
>>>>> with the SPD) we had to make similar changes to both the ipsec and 
>>>>> ipsec_gre create APIs. The other motivation was removing 2 interface 
>>>>> types that did exactly the same as the existing ipip and gre tunnels (and 
>>>>> the same goes for their APIs too, like how do I configure what DCSP, ECN, 
>>>>> DF to copy on encap/decap).
>>>>> 
>>>>> /neale
>>>>> 
>>>>> 
>>>>> 
>>>>>   Could we bring back the functionality using more "acceptable to the 
>>>>> project" APIs or something?
>>>>> 
>>>>>   Thanks,
>>>>>   Chris.
>>>>> 
>>>>>> 
>>>>>> /neale
>>>>>> 
>>>>>> 
>>>>>> From: <vpp-dev@lists.fd.io> on behalf of Christian Hopps 
>>>>>> <cho...@chopps.org>
>>>>>> Date: Wednesday 6 May 2020 at 14:32
>>>>>> To: vpp-dev <vpp-dev@lists.fd.io>
>>>>>> Cc: Christian Hopps <cho...@chopps.org>
>>>>>> Subject: [vpp-dev] IPsec tunnel interfaces?
>>>>>> 
>>>>>> Hi, vpp-dev,
>>>>>> 
>>>>>> Post 19.08 seems to have removed IPsec logical interfaces.
>>>>>> 
>>>>>> One cannot always use transport mode IPsec.
>>>>>> 
>>>>>> How can I get the efficiency of route based (FIB) IPsec w/o transport 
>>>>>> mode? Adding superfluous encapsulations (wasting bandwidth) to replace 
>>>>>> this (seemingly lost, hope not) functionality is not an option.
>>>>>> 
>>>>>> Thanks,
>>>>>> Chris.
>>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>> 
>> 

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.

View/Reply Online (#16309): https://lists.fd.io/g/vpp-dev/message/16309
Mute This Topic: https://lists.fd.io/mt/74027328/21656
Group Owner: vpp-dev+ow...@lists.fd.io
Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to