Blame view

net/netfilter/xt_TCPMSS.c 8.04 KB
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
1
2
3
4
5
6
7
8
9
  /*
   * This is a module which is used for setting the MSS option in TCP packets.
   *
   * Copyright (C) 2000 Marc Boucher <marc@mbsi.ca>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
10
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
11
12
13
  #include <linux/module.h>
  #include <linux/skbuff.h>
  #include <linux/ip.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
14
  #include <linux/gfp.h>
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
15
16
  #include <linux/ipv6.h>
  #include <linux/tcp.h>
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
17
18
  #include <net/dst.h>
  #include <net/flow.h>
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
19
  #include <net/ipv6.h>
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
20
  #include <net/route.h>
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
21
22
23
24
25
26
27
28
29
30
  #include <net/tcp.h>
  
  #include <linux/netfilter_ipv4/ip_tables.h>
  #include <linux/netfilter_ipv6/ip6_tables.h>
  #include <linux/netfilter/x_tables.h>
  #include <linux/netfilter/xt_tcpudp.h>
  #include <linux/netfilter/xt_TCPMSS.h>
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
2ae15b64e   Jan Engelhardt   [NETFILTER]: Upda...
31
  MODULE_DESCRIPTION("Xtables: TCP Maximum Segment Size (MSS) adjustment");
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  MODULE_ALIAS("ipt_TCPMSS");
  MODULE_ALIAS("ip6t_TCPMSS");
  
  static inline unsigned int
  optlen(const u_int8_t *opt, unsigned int offset)
  {
  	/* Beware zero-length options: make finite progress */
  	if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
  		return 1;
  	else
  		return opt[offset+1];
  }
  
  static int
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
46
  tcpmss_mangle_packet(struct sk_buff *skb,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
47
  		     const struct xt_tcpmss_info *info,
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
48
  		     unsigned int in_mtu,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
49
50
51
52
53
54
55
56
  		     unsigned int tcphoff,
  		     unsigned int minlen)
  {
  	struct tcphdr *tcph;
  	unsigned int tcplen, i;
  	__be16 oldval;
  	u16 newmss;
  	u8 *opt;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
57
  	if (!skb_make_writable(skb, skb->len))
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
58
  		return -1;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
59
60
  	tcplen = skb->len - tcphoff;
  	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
61

10a199394   Simon Arlott   netfilter: xt_TCP...
62
63
  	/* Header cannot be larger than the packet */
  	if (tcplen < tcph->doff*4)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
64
  		return -1;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
65
66
  
  	if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
adf30907d   Eric Dumazet   net: skb->dst acc...
67
  		if (dst_mtu(skb_dst(skb)) <= minlen) {
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
68
  			if (net_ratelimit())
ff67e4e42   Jan Engelhardt   netfilter: xt ext...
69
70
  				pr_err("unknown or invalid path-MTU (%u)
  ",
adf30907d   Eric Dumazet   net: skb->dst acc...
71
  				       dst_mtu(skb_dst(skb)));
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
72
73
  			return -1;
  		}
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
74
75
  		if (in_mtu <= minlen) {
  			if (net_ratelimit())
ff67e4e42   Jan Engelhardt   netfilter: xt ext...
76
77
78
  				pr_err("unknown or invalid path-MTU (%u)
  ",
  				       in_mtu);
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
79
80
  			return -1;
  		}
adf30907d   Eric Dumazet   net: skb->dst acc...
81
  		newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
82
83
84
85
86
87
88
89
90
91
  	} else
  		newmss = info->mss;
  
  	opt = (u_int8_t *)tcph;
  	for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) {
  		if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS &&
  		    opt[i+1] == TCPOLEN_MSS) {
  			u_int16_t oldmss;
  
  			oldmss = (opt[i+2] << 8) | opt[i+3];
170080645   Benjamin LaHaise   [NETFILTER]: xt_T...
92
93
94
95
96
  			/* Never increase MSS, even when setting it, as
  			 * doing so results in problems for hosts that rely
  			 * on MSS being set correctly.
  			 */
  			if (oldmss <= newmss)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
97
98
99
  				return 0;
  
  			opt[i+2] = (newmss & 0xff00) >> 8;
7c4e36bc1   Jan Engelhardt   [NETFILTER]: Remo...
100
  			opt[i+3] = newmss & 0x00ff;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
101

be0ea7d5d   Patrick McHardy   [NETFILTER]: Conv...
102
103
104
  			inet_proto_csum_replace2(&tcph->check, skb,
  						 htons(oldmss), htons(newmss),
  						 0);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
105
106
107
  			return 0;
  		}
  	}
10a199394   Simon Arlott   netfilter: xt_TCP...
108
109
110
111
112
  	/* There is data after the header so the option can't be added
  	   without moving it, and doing so may make the SYN packet
  	   itself too large. Accept the packet unmodified instead. */
  	if (tcplen > tcph->doff*4)
  		return 0;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
113
114
115
  	/*
  	 * MSS Option not found ?! add it..
  	 */
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
116
117
118
  	if (skb_tailroom(skb) < TCPOLEN_MSS) {
  		if (pskb_expand_head(skb, 0,
  				     TCPOLEN_MSS - skb_tailroom(skb),
2ca7b0ac0   Herbert Xu   [NETFILTER]: Avoi...
119
  				     GFP_ATOMIC))
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
120
  			return -1;
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
121
  		tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
122
  	}
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
123
  	skb_put(skb, TCPOLEN_MSS);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
124
125
126
  
  	opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
  	memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
be0ea7d5d   Patrick McHardy   [NETFILTER]: Conv...
127
128
  	inet_proto_csum_replace2(&tcph->check, skb,
  				 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
129
130
131
  	opt[0] = TCPOPT_MSS;
  	opt[1] = TCPOLEN_MSS;
  	opt[2] = (newmss & 0xff00) >> 8;
7c4e36bc1   Jan Engelhardt   [NETFILTER]: Remo...
132
  	opt[3] = newmss & 0x00ff;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
133

be0ea7d5d   Patrick McHardy   [NETFILTER]: Conv...
134
  	inet_proto_csum_replace4(&tcph->check, skb, 0, *((__be32 *)opt), 0);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
135
136
137
  
  	oldval = ((__be16 *)tcph)[6];
  	tcph->doff += TCPOLEN_MSS/4;
be0ea7d5d   Patrick McHardy   [NETFILTER]: Conv...
138
139
  	inet_proto_csum_replace2(&tcph->check, skb,
  				 oldval, ((__be16 *)tcph)[6], 0);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
140
141
  	return TCPOLEN_MSS;
  }
db1a75bdc   Jan Engelhardt   netfilter: xt_TCP...
142
143
  static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
  				    unsigned int family)
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
144
  {
a1bbb0e69   David S. Miller   netfilter: Use fl...
145
  	struct flowi fl;
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
146
147
148
  	const struct nf_afinfo *ai;
  	struct rtable *rt = NULL;
  	u_int32_t mtu     = ~0U;
a1bbb0e69   David S. Miller   netfilter: Use fl...
149
150
151
152
153
154
  	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;
db1a75bdc   Jan Engelhardt   netfilter: xt_TCP...
155

a1bbb0e69   David S. Miller   netfilter: Use fl...
156
  		memset(fl6, 0, sizeof(*fl6));
4e3fd7a06   Alexey Dobriyan   net: remove ipv6_...
157
  		fl6->daddr = ipv6_hdr(skb)->saddr;
a1bbb0e69   David S. Miller   netfilter: Use fl...
158
  	}
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
159
  	rcu_read_lock();
db1a75bdc   Jan Engelhardt   netfilter: xt_TCP...
160
  	ai = nf_get_afinfo(family);
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
161
  	if (ai != NULL)
0fae2e774   Florian Westphal   netfilter: af_inf...
162
  		ai->route(&init_net, (struct dst_entry **)&rt, &fl, false);
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
163
164
165
  	rcu_read_unlock();
  
  	if (rt != NULL) {
d8d1f30b9   Changli Gao   net-next: remove ...
166
167
  		mtu = dst_mtu(&rt->dst);
  		dst_release(&rt->dst);
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
168
169
170
  	}
  	return mtu;
  }
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
171
  static unsigned int
4b560b447   Jan Engelhardt   netfilter: xtable...
172
  tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
173
  {
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
174
  	struct iphdr *iph = ip_hdr(skb);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
175
176
  	__be16 newlen;
  	int ret;
7eb355865   Jan Engelhardt   netfilter: xtable...
177
  	ret = tcpmss_mangle_packet(skb, par->targinfo,
db1a75bdc   Jan Engelhardt   netfilter: xt_TCP...
178
  				   tcpmss_reverse_mtu(skb, PF_INET),
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
179
  				   iph->ihl * 4,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
180
181
182
183
  				   sizeof(*iph) + sizeof(struct tcphdr));
  	if (ret < 0)
  		return NF_DROP;
  	if (ret > 0) {
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
184
  		iph = ip_hdr(skb);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
185
  		newlen = htons(ntohs(iph->tot_len) + ret);
be0ea7d5d   Patrick McHardy   [NETFILTER]: Conv...
186
  		csum_replace2(&iph->check, iph->tot_len, newlen);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
187
188
189
190
  		iph->tot_len = newlen;
  	}
  	return XT_CONTINUE;
  }
c0cd11566   Igor Maravić   net:netfilter: us...
191
  #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
192
  static unsigned int
4b560b447   Jan Engelhardt   netfilter: xtable...
193
  tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
194
  {
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
195
  	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
196
  	u8 nexthdr;
75f2811c6   Jesse Gross   ipv6: Add fragmen...
197
  	__be16 frag_off;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
198
199
200
201
  	int tcphoff;
  	int ret;
  
  	nexthdr = ipv6h->nexthdr;
75f2811c6   Jesse Gross   ipv6: Add fragmen...
202
  	tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr, &frag_off);
9dc0564e8   Patrick McHardy   [NETFILTER]: xt_T...
203
  	if (tcphoff < 0)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
204
  		return NF_DROP;
7eb355865   Jan Engelhardt   netfilter: xtable...
205
  	ret = tcpmss_mangle_packet(skb, par->targinfo,
db1a75bdc   Jan Engelhardt   netfilter: xt_TCP...
206
  				   tcpmss_reverse_mtu(skb, PF_INET6),
37c08387f   Jan Engelhardt   [NETFILTER]: xt_T...
207
  				   tcphoff,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
208
209
210
211
  				   sizeof(*ipv6h) + sizeof(struct tcphdr));
  	if (ret < 0)
  		return NF_DROP;
  	if (ret > 0) {
3db05fea5   Herbert Xu   [NETFILTER]: Repl...
212
  		ipv6h = ipv6_hdr(skb);
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
213
214
215
216
217
  		ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret);
  	}
  	return XT_CONTINUE;
  }
  #endif
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
218
  /* Must specify -p tcp --syn */
e1931b784   Jan Engelhardt   [NETFILTER]: x_ta...
219
  static inline bool find_syn_match(const struct xt_entry_match *m)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
220
221
222
223
  {
  	const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data;
  
  	if (strcmp(m->u.kernel.match->name, "tcp") == 0 &&
a3433f35a   Changli Gao   tcp: unify tcp fl...
224
  	    tcpinfo->flg_cmp & TCPHDR_SYN &&
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
225
  	    !(tcpinfo->invflags & XT_TCP_INV_FLAGS))
e1931b784   Jan Engelhardt   [NETFILTER]: x_ta...
226
  		return true;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
227

e1931b784   Jan Engelhardt   [NETFILTER]: x_ta...
228
  	return false;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
229
  }
135367b8f   Jan Engelhardt   netfilter: xtable...
230
  static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
231
  {
af5d6dc20   Jan Engelhardt   netfilter: xtable...
232
233
  	const struct xt_tcpmss_info *info = par->targinfo;
  	const struct ipt_entry *e = par->entryinfo;
dcea992ac   Jan Engelhardt   netfilter: xtable...
234
  	const struct xt_entry_match *ematch;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
235
236
  
  	if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
af5d6dc20   Jan Engelhardt   netfilter: xtable...
237
  	    (par->hook_mask & ~((1 << NF_INET_FORWARD) |
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
238
239
  			   (1 << NF_INET_LOCAL_OUT) |
  			   (1 << NF_INET_POST_ROUTING))) != 0) {
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
240
241
242
  		pr_info("path-MTU clamping only supported in "
  			"FORWARD, OUTPUT and POSTROUTING hooks
  ");
d6b00a534   Jan Engelhardt   netfilter: xtable...
243
  		return -EINVAL;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
244
  	}
dcea992ac   Jan Engelhardt   netfilter: xtable...
245
246
  	xt_ematch_foreach(ematch, e)
  		if (find_syn_match(ematch))
d6b00a534   Jan Engelhardt   netfilter: xtable...
247
  			return 0;
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
248
249
  	pr_info("Only works on TCP SYN packets
  ");
d6b00a534   Jan Engelhardt   netfilter: xtable...
250
  	return -EINVAL;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
251
  }
c0cd11566   Igor Maravić   net:netfilter: us...
252
  #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
135367b8f   Jan Engelhardt   netfilter: xtable...
253
  static int tcpmss_tg6_check(const struct xt_tgchk_param *par)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
254
  {
af5d6dc20   Jan Engelhardt   netfilter: xtable...
255
256
  	const struct xt_tcpmss_info *info = par->targinfo;
  	const struct ip6t_entry *e = par->entryinfo;
dcea992ac   Jan Engelhardt   netfilter: xtable...
257
  	const struct xt_entry_match *ematch;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
258
259
  
  	if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
af5d6dc20   Jan Engelhardt   netfilter: xtable...
260
  	    (par->hook_mask & ~((1 << NF_INET_FORWARD) |
6e23ae2a4   Patrick McHardy   [NETFILTER]: Intr...
261
262
  			   (1 << NF_INET_LOCAL_OUT) |
  			   (1 << NF_INET_POST_ROUTING))) != 0) {
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
263
264
265
  		pr_info("path-MTU clamping only supported in "
  			"FORWARD, OUTPUT and POSTROUTING hooks
  ");
d6b00a534   Jan Engelhardt   netfilter: xtable...
266
  		return -EINVAL;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
267
  	}
dcea992ac   Jan Engelhardt   netfilter: xtable...
268
269
  	xt_ematch_foreach(ematch, e)
  		if (find_syn_match(ematch))
d6b00a534   Jan Engelhardt   netfilter: xtable...
270
  			return 0;
8bee4bad0   Jan Engelhardt   netfilter: xt ext...
271
272
  	pr_info("Only works on TCP SYN packets
  ");
d6b00a534   Jan Engelhardt   netfilter: xtable...
273
  	return -EINVAL;
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
274
275
  }
  #endif
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
276
  static struct xt_target tcpmss_tg_reg[] __read_mostly = {
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
277
  	{
ee999d8b9   Jan Engelhardt   netfilter: x_tabl...
278
  		.family		= NFPROTO_IPV4,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
279
  		.name		= "TCPMSS",
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
280
281
  		.checkentry	= tcpmss_tg4_check,
  		.target		= tcpmss_tg4,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
282
283
284
285
  		.targetsize	= sizeof(struct xt_tcpmss_info),
  		.proto		= IPPROTO_TCP,
  		.me		= THIS_MODULE,
  	},
c0cd11566   Igor Maravić   net:netfilter: us...
286
  #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
287
  	{
ee999d8b9   Jan Engelhardt   netfilter: x_tabl...
288
  		.family		= NFPROTO_IPV6,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
289
  		.name		= "TCPMSS",
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
290
291
  		.checkentry	= tcpmss_tg6_check,
  		.target		= tcpmss_tg6,
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
292
293
294
295
296
297
  		.targetsize	= sizeof(struct xt_tcpmss_info),
  		.proto		= IPPROTO_TCP,
  		.me		= THIS_MODULE,
  	},
  #endif
  };
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
298
  static int __init tcpmss_tg_init(void)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
299
  {
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
300
  	return xt_register_targets(tcpmss_tg_reg, ARRAY_SIZE(tcpmss_tg_reg));
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
301
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
302
  static void __exit tcpmss_tg_exit(void)
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
303
  {
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
304
  	xt_unregister_targets(tcpmss_tg_reg, ARRAY_SIZE(tcpmss_tg_reg));
cdd289a2f   Patrick McHardy   [NETFILTER]: add ...
305
  }
d3c5ee6d5   Jan Engelhardt   [NETFILTER]: x_ta...
306
307
  module_init(tcpmss_tg_init);
  module_exit(tcpmss_tg_exit);