diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/Kconfig | 16 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/xt_CHECKSUM.c | 70 |
3 files changed, 87 insertions, 0 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index aa2f106347e4..5fb8efa84df3 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -326,6 +326,22 @@ config NETFILTER_XT_CONNMARK | |||
326 | 326 | ||
327 | comment "Xtables targets" | 327 | comment "Xtables targets" |
328 | 328 | ||
329 | config NETFILTER_XT_TARGET_CHECKSUM | ||
330 | tristate "CHECKSUM target support" | ||
331 | depends on IP_NF_MANGLE || IP6_NF_MANGLE | ||
332 | depends on NETFILTER_ADVANCED | ||
333 | ---help--- | ||
334 | This option adds a `CHECKSUM' target, which can be used in the iptables mangle | ||
335 | table. | ||
336 | |||
337 | You can use this target to compute and fill in the checksum in | ||
338 | a packet that lacks a checksum. This is particularly useful, | ||
339 | if you need to work around old applications such as dhcp clients, | ||
340 | that do not work well with checksum offloads, but don't want to disable | ||
341 | checksum offload in your device. | ||
342 | |||
343 | To compile it as a module, choose M here. If unsure, say N. | ||
344 | |||
329 | config NETFILTER_XT_TARGET_CLASSIFY | 345 | config NETFILTER_XT_TARGET_CLASSIFY |
330 | tristate '"CLASSIFY" target support' | 346 | tristate '"CLASSIFY" target support' |
331 | depends on NETFILTER_ADVANCED | 347 | depends on NETFILTER_ADVANCED |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index e28420aac5ef..36ef8e63be1e 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o | |||
45 | obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o | 45 | obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o |
46 | 46 | ||
47 | # targets | 47 | # targets |
48 | obj-$(CONFIG_NETFILTER_XT_TARGET_CHECKSUM) += xt_CHECKSUM.o | ||
48 | obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o | 49 | obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o |
49 | obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o | 50 | obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o |
50 | obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o | 51 | obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o |
diff --git a/net/netfilter/xt_CHECKSUM.c b/net/netfilter/xt_CHECKSUM.c new file mode 100644 index 000000000000..0f642ef8cd26 --- /dev/null +++ b/net/netfilter/xt_CHECKSUM.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* iptables module for the packet checksum mangling | ||
2 | * | ||
3 | * (C) 2002 by Harald Welte <laforge@netfilter.org> | ||
4 | * (C) 2010 Red Hat, Inc. | ||
5 | * | ||
6 | * Author: Michael S. Tsirkin <mst@redhat.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/skbuff.h> | ||
15 | |||
16 | #include <linux/netfilter/x_tables.h> | ||
17 | #include <linux/netfilter/xt_CHECKSUM.h> | ||
18 | |||
19 | MODULE_LICENSE("GPL"); | ||
20 | MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>"); | ||
21 | MODULE_DESCRIPTION("Xtables: checksum modification"); | ||
22 | MODULE_ALIAS("ipt_CHECKSUM"); | ||
23 | MODULE_ALIAS("ip6t_CHECKSUM"); | ||
24 | |||
25 | static unsigned int | ||
26 | checksum_tg(struct sk_buff *skb, const struct xt_action_param *par) | ||
27 | { | ||
28 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
29 | skb_checksum_help(skb); | ||
30 | |||
31 | return XT_CONTINUE; | ||
32 | } | ||
33 | |||
34 | static int checksum_tg_check(const struct xt_tgchk_param *par) | ||
35 | { | ||
36 | const struct xt_CHECKSUM_info *einfo = par->targinfo; | ||
37 | |||
38 | if (einfo->operation & ~XT_CHECKSUM_OP_FILL) { | ||
39 | pr_info("unsupported CHECKSUM operation %x\n", einfo->operation); | ||
40 | return -EINVAL; | ||
41 | } | ||
42 | if (!einfo->operation) { | ||
43 | pr_info("no CHECKSUM operation enabled\n"); | ||
44 | return -EINVAL; | ||
45 | } | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static struct xt_target checksum_tg_reg __read_mostly = { | ||
50 | .name = "CHECKSUM", | ||
51 | .family = NFPROTO_UNSPEC, | ||
52 | .target = checksum_tg, | ||
53 | .targetsize = sizeof(struct xt_CHECKSUM_info), | ||
54 | .table = "mangle", | ||
55 | .checkentry = checksum_tg_check, | ||
56 | .me = THIS_MODULE, | ||
57 | }; | ||
58 | |||
59 | static int __init checksum_tg_init(void) | ||
60 | { | ||
61 | return xt_register_target(&checksum_tg_reg); | ||
62 | } | ||
63 | |||
64 | static void __exit checksum_tg_exit(void) | ||
65 | { | ||
66 | xt_unregister_target(&checksum_tg_reg); | ||
67 | } | ||
68 | |||
69 | module_init(checksum_tg_init); | ||
70 | module_exit(checksum_tg_exit); | ||