diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2005-12-19 17:23:23 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-12-19 17:23:23 -0500 |
commit | 399c180ac5f0cb66ef9479358e0b8b6bafcbeafe (patch) | |
tree | 4014154b7800e96058d94f78dc34a53681e8d5e5 | |
parent | 9e999993c71e1506378d26d81f842277aff8a250 (diff) |
[IPSEC]: Perform SA switchover immediately.
When we insert a new xfrm_state which potentially
subsumes an existing one, make sure all cached
bundles are flushed so that the new SA is used
immediately.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/xfrm.h | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 19 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 5 |
3 files changed, 20 insertions, 5 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 5beae1ccd574..1cdb87912137 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -890,6 +890,7 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | |||
890 | extern void xfrm_policy_flush(void); | 890 | extern void xfrm_policy_flush(void); |
891 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 891 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
892 | extern int xfrm_flush_bundles(void); | 892 | extern int xfrm_flush_bundles(void); |
893 | extern void xfrm_flush_all_bundles(void); | ||
893 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); | 894 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); |
894 | extern void xfrm_init_pmtu(struct dst_entry *dst); | 895 | extern void xfrm_init_pmtu(struct dst_entry *dst); |
895 | 896 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 0db9e57013fd..54a4be6a7d26 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1014,13 +1014,12 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
1014 | } | 1014 | } |
1015 | EXPORT_SYMBOL(__xfrm_route_forward); | 1015 | EXPORT_SYMBOL(__xfrm_route_forward); |
1016 | 1016 | ||
1017 | /* Optimize later using cookies and generation ids. */ | ||
1018 | |||
1019 | static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | 1017 | static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) |
1020 | { | 1018 | { |
1021 | if (!stale_bundle(dst)) | 1019 | /* If it is marked obsolete, which is how we even get here, |
1022 | return dst; | 1020 | * then we have purged it from the policy bundle list and we |
1023 | 1021 | * did that for a good reason. | |
1022 | */ | ||
1024 | return NULL; | 1023 | return NULL; |
1025 | } | 1024 | } |
1026 | 1025 | ||
@@ -1104,6 +1103,16 @@ int xfrm_flush_bundles(void) | |||
1104 | return 0; | 1103 | return 0; |
1105 | } | 1104 | } |
1106 | 1105 | ||
1106 | static int always_true(struct dst_entry *dst) | ||
1107 | { | ||
1108 | return 1; | ||
1109 | } | ||
1110 | |||
1111 | void xfrm_flush_all_bundles(void) | ||
1112 | { | ||
1113 | xfrm_prune_bundles(always_true); | ||
1114 | } | ||
1115 | |||
1107 | void xfrm_init_pmtu(struct dst_entry *dst) | 1116 | void xfrm_init_pmtu(struct dst_entry *dst) |
1108 | { | 1117 | { |
1109 | do { | 1118 | do { |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7cf48aa6c95b..479effc97666 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -431,6 +431,8 @@ void xfrm_state_insert(struct xfrm_state *x) | |||
431 | spin_lock_bh(&xfrm_state_lock); | 431 | spin_lock_bh(&xfrm_state_lock); |
432 | __xfrm_state_insert(x); | 432 | __xfrm_state_insert(x); |
433 | spin_unlock_bh(&xfrm_state_lock); | 433 | spin_unlock_bh(&xfrm_state_lock); |
434 | |||
435 | xfrm_flush_all_bundles(); | ||
434 | } | 436 | } |
435 | EXPORT_SYMBOL(xfrm_state_insert); | 437 | EXPORT_SYMBOL(xfrm_state_insert); |
436 | 438 | ||
@@ -478,6 +480,9 @@ out: | |||
478 | spin_unlock_bh(&xfrm_state_lock); | 480 | spin_unlock_bh(&xfrm_state_lock); |
479 | xfrm_state_put_afinfo(afinfo); | 481 | xfrm_state_put_afinfo(afinfo); |
480 | 482 | ||
483 | if (!err) | ||
484 | xfrm_flush_all_bundles(); | ||
485 | |||
481 | if (x1) { | 486 | if (x1) { |
482 | xfrm_state_delete(x1); | 487 | xfrm_state_delete(x1); |
483 | xfrm_state_put(x1); | 488 | xfrm_state_put(x1); |