diff options
-rw-r--r-- | include/net/dst.h | 1 | ||||
-rw-r--r-- | include/net/xfrm.h | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 24 |
5 files changed, 27 insertions, 3 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 36d54fc248b0..a8d825f90305 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -54,6 +54,7 @@ struct dst_entry | |||
54 | unsigned long expires; | 54 | unsigned long expires; |
55 | 55 | ||
56 | unsigned short header_len; /* more space at head required */ | 56 | unsigned short header_len; /* more space at head required */ |
57 | unsigned short nfheader_len; /* more non-fragment space at head required */ | ||
57 | unsigned short trailer_len; /* space to reserve at tail */ | 58 | unsigned short trailer_len; /* space to reserve at tail */ |
58 | 59 | ||
59 | u32 metrics[RTAX_MAX]; | 60 | u32 metrics[RTAX_MAX]; |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index aa3ac994477b..aa93cc1f6299 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -260,6 +260,8 @@ struct xfrm_type | |||
260 | char *description; | 260 | char *description; |
261 | struct module *owner; | 261 | struct module *owner; |
262 | __u8 proto; | 262 | __u8 proto; |
263 | __u8 flags; | ||
264 | #define XFRM_TYPE_NON_FRAGMENT 1 | ||
263 | 265 | ||
264 | int (*init_state)(struct xfrm_state *x); | 266 | int (*init_state)(struct xfrm_state *x); |
265 | void (*destructor)(struct xfrm_state *); | 267 | void (*destructor)(struct xfrm_state *); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index a5bed741de2c..e517981ceadd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -135,6 +135,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
135 | dst_prev->flags |= DST_HOST; | 135 | dst_prev->flags |= DST_HOST; |
136 | dst_prev->lastuse = jiffies; | 136 | dst_prev->lastuse = jiffies; |
137 | dst_prev->header_len = header_len; | 137 | dst_prev->header_len = header_len; |
138 | dst_prev->nfheader_len = 0; | ||
138 | dst_prev->trailer_len = trailer_len; | 139 | dst_prev->trailer_len = trailer_len; |
139 | memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); | 140 | memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); |
140 | 141 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 2a376b7d91b4..258e3e45f5e0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -971,7 +971,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
971 | 971 | ||
972 | hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); | 972 | hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); |
973 | 973 | ||
974 | fragheaderlen = sizeof(struct ipv6hdr) + (opt ? opt->opt_nflen : 0); | 974 | fragheaderlen = sizeof(struct ipv6hdr) + rt->u.dst.nfheader_len + (opt ? opt->opt_nflen : 0); |
975 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); | 975 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); |
976 | 976 | ||
977 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { | 977 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { |
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 | ||