diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-08-24 06:29:04 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:08:45 -0400 |
commit | c7f5ea3a4d1ae6b3b426e113358fdc57494bc754 (patch) | |
tree | d77be695b79131617029d8586fd729a6b94b56e5 /net/xfrm | |
parent | 2575b65434d56559bd03854450b9b6aaf19b9c90 (diff) |
[XFRM]: Do not flush all bundles on SA insert.
Instead, simply set all potentially aliasing existing xfrm_state
objects to have the current generation counter value.
This will make routes get relooked up the next time an existing
route mentioning these aliased xfrm_state objects gets used,
via xfrm_dst_check().
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 10 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 25 |
2 files changed, 20 insertions, 15 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 7fc6944ee36f..cfa5c692f2e8 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1478,16 +1478,6 @@ int xfrm_flush_bundles(void) | |||
1478 | return 0; | 1478 | return 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | static int always_true(struct dst_entry *dst) | ||
1482 | { | ||
1483 | return 1; | ||
1484 | } | ||
1485 | |||
1486 | void xfrm_flush_all_bundles(void) | ||
1487 | { | ||
1488 | xfrm_prune_bundles(always_true); | ||
1489 | } | ||
1490 | |||
1491 | void xfrm_init_pmtu(struct dst_entry *dst) | 1481 | void xfrm_init_pmtu(struct dst_entry *dst) |
1492 | { | 1482 | { |
1493 | do { | 1483 | do { |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 98200397e098..77ef796c9d0d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -761,13 +761,30 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
761 | schedule_work(&xfrm_hash_work); | 761 | schedule_work(&xfrm_hash_work); |
762 | } | 762 | } |
763 | 763 | ||
764 | /* xfrm_state_lock is held */ | ||
765 | static void __xfrm_state_bump_genids(struct xfrm_state *xnew) | ||
766 | { | ||
767 | unsigned short family = xnew->props.family; | ||
768 | u32 reqid = xnew->props.reqid; | ||
769 | struct xfrm_state *x; | ||
770 | struct hlist_node *entry; | ||
771 | unsigned int h; | ||
772 | |||
773 | h = xfrm_dst_hash(&xnew->id.daddr, reqid, family); | ||
774 | hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) { | ||
775 | if (x->props.family == family && | ||
776 | x->props.reqid == reqid && | ||
777 | !xfrm_addr_cmp(&x->id.daddr, &xnew->id.daddr, family)) | ||
778 | x->genid = xfrm_state_genid; | ||
779 | } | ||
780 | } | ||
781 | |||
764 | void xfrm_state_insert(struct xfrm_state *x) | 782 | void xfrm_state_insert(struct xfrm_state *x) |
765 | { | 783 | { |
766 | spin_lock_bh(&xfrm_state_lock); | 784 | spin_lock_bh(&xfrm_state_lock); |
785 | __xfrm_state_bump_genids(x); | ||
767 | __xfrm_state_insert(x); | 786 | __xfrm_state_insert(x); |
768 | spin_unlock_bh(&xfrm_state_lock); | 787 | spin_unlock_bh(&xfrm_state_lock); |
769 | |||
770 | xfrm_flush_all_bundles(); | ||
771 | } | 788 | } |
772 | EXPORT_SYMBOL(xfrm_state_insert); | 789 | EXPORT_SYMBOL(xfrm_state_insert); |
773 | 790 | ||
@@ -889,15 +906,13 @@ int xfrm_state_add(struct xfrm_state *x) | |||
889 | x->id.proto, | 906 | x->id.proto, |
890 | &x->id.daddr, &x->props.saddr, 0); | 907 | &x->id.daddr, &x->props.saddr, 0); |
891 | 908 | ||
909 | __xfrm_state_bump_genids(x); | ||
892 | __xfrm_state_insert(x); | 910 | __xfrm_state_insert(x); |
893 | err = 0; | 911 | err = 0; |
894 | 912 | ||
895 | out: | 913 | out: |
896 | spin_unlock_bh(&xfrm_state_lock); | 914 | spin_unlock_bh(&xfrm_state_lock); |
897 | 915 | ||
898 | if (!err) | ||
899 | xfrm_flush_all_bundles(); | ||
900 | |||
901 | if (x1) { | 916 | if (x1) { |
902 | xfrm_state_delete(x1); | 917 | xfrm_state_delete(x1); |
903 | xfrm_state_put(x1); | 918 | xfrm_state_put(x1); |