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.

    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...

    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.

/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 (#16308): https://lists.fd.io/g/vpp-dev/message/16308
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