diff options
| -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) |
