[IPSEC]: Fix policy updates missed by sockets

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>

+29 -1
+29 -1
net/xfrm/xfrm_policy.c
··· 346 struct xfrm_policy *pol, **p; 347 struct xfrm_policy *delpol = NULL; 348 struct xfrm_policy **newpos = NULL; 349 350 write_lock_bh(&xfrm_policy_lock); 351 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { ··· 382 xfrm_pol_hold(policy); 383 write_unlock_bh(&xfrm_policy_lock); 384 385 - if (delpol) { 386 xfrm_policy_kill(delpol); 387 } 388 return 0; 389 } 390 EXPORT_SYMBOL(xfrm_policy_insert);
··· 346 struct xfrm_policy *pol, **p; 347 struct xfrm_policy *delpol = NULL; 348 struct xfrm_policy **newpos = NULL; 349 + struct dst_entry *gc_list; 350 351 write_lock_bh(&xfrm_policy_lock); 352 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { ··· 381 xfrm_pol_hold(policy); 382 write_unlock_bh(&xfrm_policy_lock); 383 384 + if (delpol) 385 xfrm_policy_kill(delpol); 386 + 387 + read_lock_bh(&xfrm_policy_lock); 388 + gc_list = NULL; 389 + for (policy = policy->next; policy; policy = policy->next) { 390 + struct dst_entry *dst; 391 + 392 + write_lock(&policy->lock); 393 + dst = policy->bundles; 394 + if (dst) { 395 + struct dst_entry *tail = dst; 396 + while (tail->next) 397 + tail = tail->next; 398 + tail->next = gc_list; 399 + gc_list = dst; 400 + 401 + policy->bundles = NULL; 402 + } 403 + write_unlock(&policy->lock); 404 } 405 + read_unlock_bh(&xfrm_policy_lock); 406 + 407 + while (gc_list) { 408 + struct dst_entry *dst = gc_list; 409 + 410 + gc_list = dst->next; 411 + dst_free(dst); 412 + } 413 + 414 return 0; 415 } 416 EXPORT_SYMBOL(xfrm_policy_insert);