diff options
author | Masahide NAKAMURA <nakam@linux-ipv6.org> | 2006-08-23 21:11:50 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:06:41 -0400 |
commit | 1b5c229987dc4d0c92a38fac0cde2aeec08cd775 (patch) | |
tree | 5726243af6aa7194f1ed65e0340539e1ee5c6a42 /net/ipv6/xfrm6_policy.c | |
parent | 99505a843673faeae962a8cde128c7c034ba6b5e (diff) |
[XFRM] STATE: Support non-fragment outbound transformation headers.
For originated outbound IPv6 packets which will fragment, ip6_append_data()
should know length of extension headers before sending them and
the length is carried by dst_entry.
IPv6 IPsec headers fragment then transformation was
designed to place all headers after fragment header.
OTOH Mobile IPv6 extension headers do not fragment then
it is a good idea to make dst_entry have non-fragment length to tell it
to ip6_append_data().
Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/xfrm6_policy.c')
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 9328fc88708a..a3f68c8b737e 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -75,6 +75,24 @@ __xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr) | |||
75 | (struct in6_addr*)&x->props.saddr; | 75 | (struct in6_addr*)&x->props.saddr; |
76 | } | 76 | } |
77 | 77 | ||
78 | static inline void | ||
79 | __xfrm6_bundle_len_inc(int *len, int *nflen, struct xfrm_state *x) | ||
80 | { | ||
81 | if (x->type->flags & XFRM_TYPE_NON_FRAGMENT) | ||
82 | *nflen += x->props.header_len; | ||
83 | else | ||
84 | *len += x->props.header_len; | ||
85 | } | ||
86 | |||
87 | static inline void | ||
88 | __xfrm6_bundle_len_dec(int *len, int *nflen, struct xfrm_state *x) | ||
89 | { | ||
90 | if (x->type->flags & XFRM_TYPE_NON_FRAGMENT) | ||
91 | *nflen -= x->props.header_len; | ||
92 | else | ||
93 | *len -= x->props.header_len; | ||
94 | } | ||
95 | |||
78 | /* Allocate chain of dst_entry's, attach known xfrm's, calculate | 96 | /* Allocate chain of dst_entry's, attach known xfrm's, calculate |
79 | * all the metrics... Shortly, bundle a bundle. | 97 | * all the metrics... Shortly, bundle a bundle. |
80 | */ | 98 | */ |
@@ -99,6 +117,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
99 | int i; | 117 | int i; |
100 | int err = 0; | 118 | int err = 0; |
101 | int header_len = 0; | 119 | int header_len = 0; |
120 | int nfheader_len = 0; | ||
102 | int trailer_len = 0; | 121 | int trailer_len = 0; |
103 | 122 | ||
104 | dst = dst_prev = NULL; | 123 | dst = dst_prev = NULL; |
@@ -135,7 +154,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
135 | local = __xfrm6_bundle_addr_local(xfrm[i], local); | 154 | local = __xfrm6_bundle_addr_local(xfrm[i], local); |
136 | tunnel = 1; | 155 | tunnel = 1; |
137 | } | 156 | } |
138 | header_len += xfrm[i]->props.header_len; | 157 | __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); |
139 | trailer_len += xfrm[i]->props.trailer_len; | 158 | trailer_len += xfrm[i]->props.trailer_len; |
140 | 159 | ||
141 | if (tunnel) { | 160 | if (tunnel) { |
@@ -170,6 +189,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
170 | dst_prev->flags |= DST_HOST; | 189 | dst_prev->flags |= DST_HOST; |
171 | dst_prev->lastuse = jiffies; | 190 | dst_prev->lastuse = jiffies; |
172 | dst_prev->header_len = header_len; | 191 | dst_prev->header_len = header_len; |
192 | dst_prev->nfheader_len = nfheader_len; | ||
173 | dst_prev->trailer_len = trailer_len; | 193 | dst_prev->trailer_len = trailer_len; |
174 | memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); | 194 | memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); |
175 | 195 | ||
@@ -188,7 +208,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
188 | x->u.rt6.rt6i_src = rt0->rt6i_src; | 208 | x->u.rt6.rt6i_src = rt0->rt6i_src; |
189 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; | 209 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; |
190 | in6_dev_hold(rt0->rt6i_idev); | 210 | in6_dev_hold(rt0->rt6i_idev); |
191 | header_len -= x->u.dst.xfrm->props.header_len; | 211 | __xfrm6_bundle_len_dec(&header_len, &nfheader_len, x->u.dst.xfrm); |
192 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 212 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
193 | } | 213 | } |
194 | 214 | ||