diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_TCPMSS.c | 42 |
1 files changed, 13 insertions, 29 deletions
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 217e2b686322..beb5094703cb 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
@@ -147,17 +147,21 @@ tcpmss_mangle_packet(struct sk_buff *skb, | |||
147 | return TCPOLEN_MSS; | 147 | return TCPOLEN_MSS; |
148 | } | 148 | } |
149 | 149 | ||
150 | static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph) | 150 | static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, |
151 | unsigned int family) | ||
151 | { | 152 | { |
152 | struct flowi fl = { | 153 | struct flowi fl = {}; |
153 | .fl4_dst = iph->saddr, | ||
154 | }; | ||
155 | const struct nf_afinfo *ai; | 154 | const struct nf_afinfo *ai; |
156 | struct rtable *rt = NULL; | 155 | struct rtable *rt = NULL; |
157 | u_int32_t mtu = ~0U; | 156 | u_int32_t mtu = ~0U; |
158 | 157 | ||
158 | if (family == PF_INET) | ||
159 | fl.fl4_dst = ip_hdr(skb)->saddr; | ||
160 | else | ||
161 | fl.fl6_dst = ipv6_hdr(skb)->saddr; | ||
162 | |||
159 | rcu_read_lock(); | 163 | rcu_read_lock(); |
160 | ai = nf_get_afinfo(AF_INET); | 164 | ai = nf_get_afinfo(family); |
161 | if (ai != NULL) | 165 | if (ai != NULL) |
162 | ai->route((struct dst_entry **)&rt, &fl); | 166 | ai->route((struct dst_entry **)&rt, &fl); |
163 | rcu_read_unlock(); | 167 | rcu_read_unlock(); |
@@ -178,7 +182,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in, | |||
178 | __be16 newlen; | 182 | __be16 newlen; |
179 | int ret; | 183 | int ret; |
180 | 184 | ||
181 | ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph), | 185 | ret = tcpmss_mangle_packet(skb, targinfo, |
186 | tcpmss_reverse_mtu(skb, PF_INET), | ||
182 | iph->ihl * 4, | 187 | iph->ihl * 4, |
183 | sizeof(*iph) + sizeof(struct tcphdr)); | 188 | sizeof(*iph) + sizeof(struct tcphdr)); |
184 | if (ret < 0) | 189 | if (ret < 0) |
@@ -193,28 +198,6 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in, | |||
193 | } | 198 | } |
194 | 199 | ||
195 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) | 200 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) |
196 | static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph) | ||
197 | { | ||
198 | struct flowi fl = { | ||
199 | .fl6_dst = iph->saddr, | ||
200 | }; | ||
201 | const struct nf_afinfo *ai; | ||
202 | struct rtable *rt = NULL; | ||
203 | u_int32_t mtu = ~0U; | ||
204 | |||
205 | rcu_read_lock(); | ||
206 | ai = nf_get_afinfo(AF_INET6); | ||
207 | if (ai != NULL) | ||
208 | ai->route((struct dst_entry **)&rt, &fl); | ||
209 | rcu_read_unlock(); | ||
210 | |||
211 | if (rt != NULL) { | ||
212 | mtu = dst_mtu(&rt->u.dst); | ||
213 | dst_release(&rt->u.dst); | ||
214 | } | ||
215 | return mtu; | ||
216 | } | ||
217 | |||
218 | static unsigned int | 201 | static unsigned int |
219 | tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, | 202 | tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, |
220 | const struct net_device *out, unsigned int hooknum, | 203 | const struct net_device *out, unsigned int hooknum, |
@@ -229,7 +212,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, | |||
229 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); | 212 | tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); |
230 | if (tcphoff < 0) | 213 | if (tcphoff < 0) |
231 | return NF_DROP; | 214 | return NF_DROP; |
232 | ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h), | 215 | ret = tcpmss_mangle_packet(skb, targinfo, |
216 | tcpmss_reverse_mtu(skb, PF_INET6), | ||
233 | tcphoff, | 217 | tcphoff, |
234 | sizeof(*ipv6h) + sizeof(struct tcphdr)); | 218 | sizeof(*ipv6h) + sizeof(struct tcphdr)); |
235 | if (ret < 0) | 219 | if (ret < 0) |