diff options
Diffstat (limited to 'net/netfilter/xt_TCPMSS.c')
| -rw-r--r-- | net/netfilter/xt_TCPMSS.c | 72 | 
1 files changed, 38 insertions, 34 deletions
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index cd24290f3b2..e762de5ee89 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -43,10 +43,42 @@ optlen(const u_int8_t *opt, unsigned int offset)  		return opt[offset+1];  } +static u_int32_t tcpmss_reverse_mtu(struct net *net, +				    const struct sk_buff *skb, +				    unsigned int family) +{ +	struct flowi fl; +	const struct nf_afinfo *ai; +	struct rtable *rt = NULL; +	u_int32_t mtu     = ~0U; + +	if (family == PF_INET) { +		struct flowi4 *fl4 = &fl.u.ip4; +		memset(fl4, 0, sizeof(*fl4)); +		fl4->daddr = ip_hdr(skb)->saddr; +	} else { +		struct flowi6 *fl6 = &fl.u.ip6; + +		memset(fl6, 0, sizeof(*fl6)); +		fl6->daddr = ipv6_hdr(skb)->saddr; +	} +	rcu_read_lock(); +	ai = nf_get_afinfo(family); +	if (ai != NULL) +		ai->route(net, (struct dst_entry **)&rt, &fl, false); +	rcu_read_unlock(); + +	if (rt != NULL) { +		mtu = dst_mtu(&rt->dst); +		dst_release(&rt->dst); +	} +	return mtu; +} +  static int  tcpmss_mangle_packet(struct sk_buff *skb,  		     const struct xt_action_param *par, -		     unsigned int in_mtu, +		     unsigned int family,  		     unsigned int tcphoff,  		     unsigned int minlen)  { @@ -76,6 +108,9 @@ tcpmss_mangle_packet(struct sk_buff *skb,  		return -1;  	if (info->mss == XT_TCPMSS_CLAMP_PMTU) { +		struct net *net = dev_net(par->in ? par->in : par->out); +		unsigned int in_mtu = tcpmss_reverse_mtu(net, skb, family); +  		if (dst_mtu(skb_dst(skb)) <= minlen) {  			net_err_ratelimited("unknown or invalid path-MTU (%u)\n",  					    dst_mtu(skb_dst(skb))); @@ -165,37 +200,6 @@ tcpmss_mangle_packet(struct sk_buff *skb,  	return TCPOLEN_MSS;  } -static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, -				    unsigned int family) -{ -	struct flowi fl; -	const struct nf_afinfo *ai; -	struct rtable *rt = NULL; -	u_int32_t mtu     = ~0U; - -	if (family == PF_INET) { -		struct flowi4 *fl4 = &fl.u.ip4; -		memset(fl4, 0, sizeof(*fl4)); -		fl4->daddr = ip_hdr(skb)->saddr; -	} else { -		struct flowi6 *fl6 = &fl.u.ip6; - -		memset(fl6, 0, sizeof(*fl6)); -		fl6->daddr = ipv6_hdr(skb)->saddr; -	} -	rcu_read_lock(); -	ai = nf_get_afinfo(family); -	if (ai != NULL) -		ai->route(&init_net, (struct dst_entry **)&rt, &fl, false); -	rcu_read_unlock(); - -	if (rt != NULL) { -		mtu = dst_mtu(&rt->dst); -		dst_release(&rt->dst); -	} -	return mtu; -} -  static unsigned int  tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par)  { @@ -204,7 +208,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par)  	int ret;  	ret = tcpmss_mangle_packet(skb, par, -				   tcpmss_reverse_mtu(skb, PF_INET), +				   PF_INET,  				   iph->ihl * 4,  				   sizeof(*iph) + sizeof(struct tcphdr));  	if (ret < 0) @@ -233,7 +237,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)  	if (tcphoff < 0)  		return NF_DROP;  	ret = tcpmss_mangle_packet(skb, par, -				   tcpmss_reverse_mtu(skb, PF_INET6), +				   PF_INET6,  				   tcphoff,  				   sizeof(*ipv6h) + sizeof(struct tcphdr));  	if (ret < 0)  | 
