Skip to content

Commit

Permalink
[IPSEC]: Fix policy updates missed by sockets
Browse files Browse the repository at this point in the history
The problem is that when new policies are inserted, sockets do not see
the update (but all new route lookups do).

This bug is related to the SA insertion stale route issue solved
recently, and this policy visibility problem can be fixed in a similar
way.

The fix is to flush out the bundles of all policies deeper than the
policy being inserted.  Consider beginning state of "outgoing"
direction policy list:

	policy A --> policy B --> policy C --> policy D

First, realize that inserting a policy into a list only potentially
changes IPSEC routes for that direction.  Therefore we need not bother
considering the policies for other directions.  We need only consider
the existing policies in the list we are doing the inserting.

Consider new policy "B'", inserted after B.

	policy A --> policy B --> policy B' --> policy C --> policy D

Two rules:

1) If policy A or policy B matched before the insertion, they
   appear before B' and thus would still match after inserting
   B'

2) Policy C and D, now "shadowed" and after policy B', potentially
   contain stale routes because policy B' might be selected
   instead of them.

Therefore we only need flush routes assosciated with policies
appearing after a newly inserted policy, if any.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 22, 2005
1 parent 4c7e689 commit 9b78a82
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
struct xfrm_policy *pol, **p;
struct xfrm_policy *delpol = NULL;
struct xfrm_policy **newpos = NULL;
struct dst_entry *gc_list;

write_lock_bh(&xfrm_policy_lock);
for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
Expand Down Expand Up @@ -381,9 +382,36 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
xfrm_pol_hold(policy);
write_unlock_bh(&xfrm_policy_lock);

if (delpol) {
if (delpol)
xfrm_policy_kill(delpol);

read_lock_bh(&xfrm_policy_lock);
gc_list = NULL;
for (policy = policy->next; policy; policy = policy->next) {
struct dst_entry *dst;

write_lock(&policy->lock);
dst = policy->bundles;
if (dst) {
struct dst_entry *tail = dst;
while (tail->next)
tail = tail->next;
tail->next = gc_list;
gc_list = dst;

policy->bundles = NULL;
}
write_unlock(&policy->lock);
}
read_unlock_bh(&xfrm_policy_lock);

while (gc_list) {
struct dst_entry *dst = gc_list;

gc_list = dst->next;
dst_free(dst);
}

return 0;
}
EXPORT_SYMBOL(xfrm_policy_insert);
Expand Down

0 comments on commit 9b78a82

Please sign in to comment.