[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 346 struct xfrm_policy *pol, **p; 347 347 struct xfrm_policy *delpol = NULL; 348 348 struct xfrm_policy **newpos = NULL; 349 + struct dst_entry *gc_list; 349 350 350 351 write_lock_bh(&xfrm_policy_lock); 351 352 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { ··· 382 381 xfrm_pol_hold(policy); 383 382 write_unlock_bh(&xfrm_policy_lock); 384 383 385 - if (delpol) { 384 + if (delpol) 386 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); 387 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 + 388 414 return 0; 389 415 } 390 416 EXPORT_SYMBOL(xfrm_policy_insert);