-
Notifications
You must be signed in to change notification settings - Fork 10
Description
UFT entries (fastpath transforms) are created in response to any slowpath traversal, and have their own expiry timestamps and lifecycle. Currently this is 60s from last hit, and LFT entries (stateful allows) also expire after 60s. Suppose we have a UDP request/response pair between A (internal) and B (external):
Packet A->B:
- No outbound UFT entry; slowpath.
- Firewall; no LFT entry.
- Rule evaluation: stateful allow.
- In/out LFT pair are created at time t_0.
- NAT; no LFT entry.
- Rule evaluation: stateful allow on SNAT action.
- In/out LFT pair are created at time t_1, choosing port p.
- Packet is sent upstream; outbound UFT entry created at time t_2.
Packet B->A:
- No inbound UFT entry; slowpath.
- NAT; LFT exists (allow).
- In LFT hit time refreshed to t_3.
- Firewall; LFT exists (allow).
- In LFT hit time refreshed to t_4.
- Packet is sent to guest inbound UFT entry created at time t_5.
Packet A->B:
- Outbound UFT entry exists; apply fastpath transform.
- Out UFT hit time refreshed to t_6.
- Packet is sent upstream.
I've omitted most of the stateless layers here, but the problem is obvious when we see that the LFT timers are never revisted: since the expiry timers are the same, our UFTs outlive all LFTs that were involved in creating them after 60s. This leads to unpleasant situations where finite resources are concerned -- e.g., another flow is able to use the port after t_3 + 60s (or t_1 + 60s accounting for #788).
The existence of a UFT should prevent any of the LFTs it created from going away. Equally, a hit on a UFT should in some way refresh the timer of every LFT involved in the process (e.g., propagate a UFT's last_hit time downwards when it expires).