I was contacted directly by someone who wanted to suggest that I try gif(4) instead. I have tried gif(4) in the past, but I ran into a lot of weirdness when using it in combination with IPsec (on 5.6-stable). After I shared my experience, he suggested that I send my synopsis to the list... so here it is.
Be forewarned... this is all from memory and it is from a while ago, so some details might be slightly inaccurate. If a developer is interested I will reproduce these scenarios again and report back with exact steps. A few examples: 1. Consider a scenario where "gif0" on a theoretical host is receiving an ICMP echo destined for its inside address, while the ipencap traffic is protected by a transport mode IPsec SA. From what I observed with tcpdump, the encapsulated echo never appears to arrive on either enc0 or gif0, the decapsulated echo arrives on enc0, and nothing at all arrives on gif0. The reply appears to be sent on gif0, and then the encapsulated reply is sent on enc0 (so that side is ok). I observed this while looking into some really weird PF rule behavior that was clearly not right. 2. For a gif(4) device with an IPv6 inside address and an IPv4 outside address, while the ipencap traffic is protected by a transport mode IPsec SA, my host would respond to one IPv6 echo (destined to the gif inside address) in a sequence of them, and no more. If the gif tunnel was not protected by IPsec this worked totally fine. Honestly I have no idea why this was happening, could have been something else with my configuration but it fits into a pattern of weirdness. 3. For a gif(4) device with IPv4 & IPv6 inside addresses and an IPv6 outside address, while the ipencap traffic is protected by a transport mode IPsec SA, only one inside address or the other would work at a time. 4. Consider a situation in which I create two PF rules "pass in on enc0 proto ipencap keep state (if-bound)" and "pass out on enc0 proto ipencap keep state (if-bound)" (also with appropriate address filters in both directions). This appears to pass the gif traffic as expected. However, if I suddenly delete the IPsec SA while the gif tunnel is being used, causing the gif traffic to suddenly come in on a different interface (other than enc0), PF continues to pass all the gif traffic until I run "pfctl -F state" (WTF?). For whatever reason, I just could not get gif(4) to play nicely with IPsec on my 5.6-stable boxes. I should note that it appeared to work fine in the absence of an IPsec SA, though. I spent a lot of time trying to diagnose the problem, and then eventually just gave up and reverted to gre(4), which resolved all the issues I identified. -Joe