aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/xfrm4_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/xfrm4_policy.c')
-rw-r--r--net/ipv4/xfrm4_policy.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 8f50eae47d03..eabcd27b1767 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -21,6 +21,25 @@ static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
21 return __ip_route_output_key((struct rtable**)dst, fl); 21 return __ip_route_output_key((struct rtable**)dst, fl);
22} 22}
23 23
24static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
25{
26 struct rtable *rt;
27 struct flowi fl_tunnel = {
28 .nl_u = {
29 .ip4_u = {
30 .daddr = daddr->a4,
31 },
32 },
33 };
34
35 if (!xfrm4_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
36 saddr->a4 = rt->rt_src;
37 dst_release(&rt->u.dst);
38 return 0;
39 }
40 return -EHOSTUNREACH;
41}
42
24static struct dst_entry * 43static struct dst_entry *
25__xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) 44__xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
26{ 45{
@@ -33,7 +52,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
33 xdst->u.rt.fl.fl4_dst == fl->fl4_dst && 52 xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
34 xdst->u.rt.fl.fl4_src == fl->fl4_src && 53 xdst->u.rt.fl.fl4_src == fl->fl4_src &&
35 xdst->u.rt.fl.fl4_tos == fl->fl4_tos && 54 xdst->u.rt.fl.fl4_tos == fl->fl4_tos &&
36 xfrm_bundle_ok(xdst, fl, AF_INET)) { 55 xfrm_bundle_ok(xdst, fl, AF_INET, 0)) {
37 dst_clone(dst); 56 dst_clone(dst);
38 break; 57 break;
39 } 58 }
@@ -93,10 +112,11 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
93 112
94 xdst = (struct xfrm_dst *)dst1; 113 xdst = (struct xfrm_dst *)dst1;
95 xdst->route = &rt->u.dst; 114 xdst->route = &rt->u.dst;
115 xdst->genid = xfrm[i]->genid;
96 116
97 dst1->next = dst_prev; 117 dst1->next = dst_prev;
98 dst_prev = dst1; 118 dst_prev = dst1;
99 if (xfrm[i]->props.mode) { 119 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
100 remote = xfrm[i]->id.daddr.a4; 120 remote = xfrm[i]->id.daddr.a4;
101 local = xfrm[i]->props.saddr.a4; 121 local = xfrm[i]->props.saddr.a4;
102 tunnel = 1; 122 tunnel = 1;
@@ -135,6 +155,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
135 dst_prev->flags |= DST_HOST; 155 dst_prev->flags |= DST_HOST;
136 dst_prev->lastuse = jiffies; 156 dst_prev->lastuse = jiffies;
137 dst_prev->header_len = header_len; 157 dst_prev->header_len = header_len;
158 dst_prev->nfheader_len = 0;
138 dst_prev->trailer_len = trailer_len; 159 dst_prev->trailer_len = trailer_len;
139 memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); 160 memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
140 161
@@ -296,6 +317,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
296 .family = AF_INET, 317 .family = AF_INET,
297 .dst_ops = &xfrm4_dst_ops, 318 .dst_ops = &xfrm4_dst_ops,
298 .dst_lookup = xfrm4_dst_lookup, 319 .dst_lookup = xfrm4_dst_lookup,
320 .get_saddr = xfrm4_get_saddr,
299 .find_bundle = __xfrm4_find_bundle, 321 .find_bundle = __xfrm4_find_bundle,
300 .bundle_create = __xfrm4_bundle_create, 322 .bundle_create = __xfrm4_bundle_create,
301 .decode_session = _decode_session4, 323 .decode_session = _decode_session4,