mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 12:00:58 +07:00
[IPSEC]: Validate properly in xfrm_dst_check()
If dst->obsolete is -1, this is a signal from the bundle creator that we want the XFRM dst and the dsts that it references to be validated on every use. I misunderstood this intention when I changed xfrm_dst_check() to always return NULL. Now, when we purge a dst entry, by running dst_free() on it. This will set the dst->obsolete to a positive integer, and we want to return NULL in that case so that the socket does a relookup for the route. Thus, if dst->obsolete<0, let stale_bundle() validate the state, else always return NULL. In general, we need to do things more intelligently here because we flush too much state during rule changes. Herbert Xu has some ideas wherein the key manager gives us some help in this area. We can also use smarter state management algorithms inside of the kernel as well. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1c7628bd7a
commit
d49c73c729
@ -1134,12 +1134,33 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
|
||||
}
|
||||
EXPORT_SYMBOL(__xfrm_route_forward);
|
||||
|
||||
/* Optimize later using cookies and generation ids. */
|
||||
|
||||
static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
|
||||
{
|
||||
/* If it is marked obsolete, which is how we even get here,
|
||||
* then we have purged it from the policy bundle list and we
|
||||
* did that for a good reason.
|
||||
/* Code (such as __xfrm4_bundle_create()) sets dst->obsolete
|
||||
* to "-1" to force all XFRM destinations to get validated by
|
||||
* dst_ops->check on every use. We do this because when a
|
||||
* normal route referenced by an XFRM dst is obsoleted we do
|
||||
* not go looking around for all parent referencing XFRM dsts
|
||||
* so that we can invalidate them. It is just too much work.
|
||||
* Instead we make the checks here on every use. For example:
|
||||
*
|
||||
* XFRM dst A --> IPv4 dst X
|
||||
*
|
||||
* X is the "xdst->route" of A (X is also the "dst->path" of A
|
||||
* in this example). If X is marked obsolete, "A" will not
|
||||
* notice. That's what we are validating here via the
|
||||
* stale_bundle() check.
|
||||
*
|
||||
* When a policy's bundle is pruned, we dst_free() the XFRM
|
||||
* dst which causes it's ->obsolete field to be set to a
|
||||
* positive non-zero integer. If an XFRM dst has been pruned
|
||||
* like this, we want to force a new route lookup.
|
||||
*/
|
||||
if (dst->obsolete < 0 && !stale_bundle(dst))
|
||||
return dst;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user