On Tue, Jun 30, 2020 at 09:22:18AM +1200, richard.n.proc...@gmail.com wrote:
> Hi Jason,
> 
> On 27/06/2020, at 10:09 PM, Jason A. Donenfeld <ja...@zx2c4.com> wrote:
> > [...] I thought I'd lay out my understanding of the matter,
> > and you can let me know whether or not this corresponds with what you  
> > had in mind:
> > [...]
> 
> My main concern is the end-to-end TCP or UDP transport checksum of the
> tunneled (or inner, or encapsulated) packet. Your argument seems to
> concern instead the per-hop IPv4 header checksum (which is also
> interesting to look at, but first things first).
> 
> As I read it, wg_decap() tells the stack to ignore the transport checksum
> of the tunneled packet, and I think this is incorrect for the following
> reason: the packet may have been corrupted outside of the tunnel, because
> the tunnel needn't cover the entire path the packet took through the
> network.
> 
> So a tunneled packet may be corrupt, and one addressed to the tunnel
> endpoint will be delivered with its end-to-end transport checksum
> unverified. Higher layers may receive corrupt data as as result.[*]  
> 
> (Routers, as intermediate network elements, are under no obligation to
> check end-to-end transport checksums. It isn't their job.)
> 
> One might argue (I do not) that this isn't a concern, because encryption
> these days is ubiquitous and comes with far stronger integrity checks.
> Nonetheless, even here transport checksums remain relevant for two
> reasons. Firsly, because networks remain unreliable: I see non-zero
> numbers of failed checksums on my systems. And, secondly, because higher
> layers require a reliable transport: TLS for instance will drop the
> connection when the MAC check fails[1].
> 
> Let's turn to the per-hop IPv4 checksum, which wg_decap() also tells the 
> stack to ignore. I suspect the cost of verifying that checksum -- 20 bytes 
> on a hot cache line -- is negligible both absolutely and relative to the 
> cost of decrypting the packet. And as the optimisation appears nowhere 
> else in the tree that I can find, removing it would make wg(4) no worse 
> than the other tunnels. Do you have evidence that the cost is in fact 
> significant?
> 
> Further, as Theo pointed out, the link layer has in any case no business 
> with the IPv4 checksum, being part of the network layer. Layer violations 
> are problematic for at least two reasons. Firstly, they constrict the 
> design space. For instance, I suppose the IPv4 checksum needn't be 
> per-hop. It might be updated incrementally, increasing its scope. But this 
> would be nullified by any link layer that, acting on a false assumption 
> about the layer above it, told the stack to ignore that layer's checksum. 
> Secondly, layer violations, an optimisation, which almost by definition 
> rely on additional premises, burden the correctness obligation and so 
> trade less work for the computer in narrow circumstances for (often much) 
> more work for the fallible human to show that the process remains sound.
> 
> On that balance I now think that skipping the IPv4 check a false economy,
> too. Hopefully I have managed to make my reasons clearer this time around, 
> please let me know if not, or if you disagree. 
> 
> See updated patch below, looking for oks to commit that.
>              
> cheers,
> Richard.
> 
> [*] By way of background, I understand the transport checksum was added to
> the early ARPANET primarily to guard against corruption inside its
> routers[0], after a router fault which "[brought] the network to its
> knees". In other words, end-to-end checks are necessary to catch faults in
> the routers; link-level checks aren't enough.
> 
> More generally, transport checksums set a lower bound on the reliability
> of the end-to-end transport, which decouples it from the reliability of  
> the underlying network.
> 
> [0] Kleinrock "Queuing Systems, Volume 2: Computer Applications",
> John Wiley and Sons (1976), p441
> 
> [1] RFC5246 TLS v1.2 (2008), section 7.2.2.
> 
> TLS's requirement is reasonable: it would otherwise be obliged to
> reimplement for itself retransmission, which would drag with it other
> transport layer mechanisms like acknowledgements and (for performance)
> sequence numbers and sliding windows.

I agree with all of this and think that this is the right fix.
OK claudio@
 
> Index: net/if_wg.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_wg.c,v
> retrieving revision 1.7
> diff -u -p -u -p -r1.7 if_wg.c
> --- net/if_wg.c       23 Jun 2020 10:03:49 -0000      1.7
> +++ net/if_wg.c       28 Jun 2020 20:17:07 -0000
> @@ -1660,14 +1660,8 @@ wg_decap(struct wg_softc *sc, struct mbu
>               goto error;
>       }
>  
> -     /*
> -      * We can mark incoming packet csum OK. We mark all flags OK
> -      * irrespective to the packet type.
> -      */
> -     m->m_pkthdr.csum_flags |= (M_IPV4_CSUM_IN_OK | M_TCP_CSUM_IN_OK |
> -         M_UDP_CSUM_IN_OK | M_ICMP_CSUM_IN_OK);
> -     m->m_pkthdr.csum_flags &= ~(M_IPV4_CSUM_IN_BAD | M_TCP_CSUM_IN_BAD |
> -         M_UDP_CSUM_IN_BAD | M_ICMP_CSUM_IN_BAD);
> +     /* tunneled packet was not offloaded */
> +     m->m_pkthdr.csum_flags = 0;
>  
>       m->m_pkthdr.ph_ifidx = sc->sc_if.if_index;
>       m->m_pkthdr.ph_rtableid = sc->sc_if.if_rdomain;
> 

-- 
:wq Claudio

Reply via email to