aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h19
-rw-r--r--net/ipv4/xfrm4_policy.c2
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/xfrm/xfrm_policy.c8
4 files changed, 28 insertions, 5 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 248874ecf8df..7f1630630dcf 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -869,6 +869,23 @@ xfrm_state_addr_check(struct xfrm_state *x,
869 return 0; 869 return 0;
870} 870}
871 871
872static __inline__ int
873xfrm_state_addr_flow_check(struct xfrm_state *x, struct flowi *fl,
874 unsigned short family)
875{
876 switch (family) {
877 case AF_INET:
878 return __xfrm4_state_addr_check(x,
879 (xfrm_address_t *)&fl->fl4_dst,
880 (xfrm_address_t *)&fl->fl4_src);
881 case AF_INET6:
882 return __xfrm6_state_addr_check(x,
883 (xfrm_address_t *)&fl->fl6_dst,
884 (xfrm_address_t *)&fl->fl6_src);
885 }
886 return 0;
887}
888
872static inline int xfrm_state_kern(struct xfrm_state *x) 889static inline int xfrm_state_kern(struct xfrm_state *x)
873{ 890{
874 return atomic_read(&x->tunnel_users); 891 return atomic_read(&x->tunnel_users);
@@ -1014,7 +1031,7 @@ extern void xfrm_policy_flush(void);
1014extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 1031extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
1015extern int xfrm_flush_bundles(void); 1032extern int xfrm_flush_bundles(void);
1016extern void xfrm_flush_all_bundles(void); 1033extern void xfrm_flush_all_bundles(void);
1017extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); 1034extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict);
1018extern void xfrm_init_pmtu(struct dst_entry *dst); 1035extern void xfrm_init_pmtu(struct dst_entry *dst);
1019 1036
1020extern wait_queue_head_t km_waitq; 1037extern wait_queue_head_t km_waitq;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index e517981ceadd..42d8ded0f96a 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -33,7 +33,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
33 xdst->u.rt.fl.fl4_dst == fl->fl4_dst && 33 xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
34 xdst->u.rt.fl.fl4_src == fl->fl4_src && 34 xdst->u.rt.fl.fl4_src == fl->fl4_src &&
35 xdst->u.rt.fl.fl4_tos == fl->fl4_tos && 35 xdst->u.rt.fl.fl4_tos == fl->fl4_tos &&
36 xfrm_bundle_ok(xdst, fl, AF_INET)) { 36 xfrm_bundle_ok(xdst, fl, AF_INET, 0)) {
37 dst_clone(dst); 37 dst_clone(dst);
38 break; 38 break;
39 } 39 }
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index a3f68c8b737e..729b4748d6d3 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -50,7 +50,9 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
50 xdst->u.rt6.rt6i_src.plen); 50 xdst->u.rt6.rt6i_src.plen);
51 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && 51 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
52 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && 52 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
53 xfrm_bundle_ok(xdst, fl, AF_INET6)) { 53 xfrm_bundle_ok(xdst, fl, AF_INET6,
54 (xdst->u.rt6.rt6i_dst.plen != 128 ||
55 xdst->u.rt6.rt6i_src.plen != 128))) {
54 dst_clone(dst); 56 dst_clone(dst);
55 break; 57 break;
56 } 58 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 56abb5c057d4..ad2a5cba1f5b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1167,7 +1167,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
1167 1167
1168static int stale_bundle(struct dst_entry *dst) 1168static int stale_bundle(struct dst_entry *dst)
1169{ 1169{
1170 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); 1170 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0);
1171} 1171}
1172 1172
1173void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) 1173void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
@@ -1282,7 +1282,7 @@ EXPORT_SYMBOL(xfrm_init_pmtu);
1282 * still valid. 1282 * still valid.
1283 */ 1283 */
1284 1284
1285int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family) 1285int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict)
1286{ 1286{
1287 struct dst_entry *dst = &first->u.dst; 1287 struct dst_entry *dst = &first->u.dst;
1288 struct xfrm_dst *last; 1288 struct xfrm_dst *last;
@@ -1304,6 +1304,10 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
1304 if (dst->xfrm->km.state != XFRM_STATE_VALID) 1304 if (dst->xfrm->km.state != XFRM_STATE_VALID)
1305 return 0; 1305 return 0;
1306 1306
1307 if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL &&
1308 !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
1309 return 0;
1310
1307 mtu = dst_mtu(dst->child); 1311 mtu = dst_mtu(dst->child);
1308 if (xdst->child_mtu_cached != mtu) { 1312 if (xdst->child_mtu_cached != mtu) {
1309 last = xdst; 1313 last = xdst;