diff --git a/doc/changelog.txt b/doc/changelog.txt index 5a39f07..c978450 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -2,6 +2,7 @@ HEAD ==== - RAWNAT: IPv6 variants erroneously rejected masks /33-/128 +- new target xt_CHECKSUM Xtables-addons 1.27 (May 16 2010) diff --git a/extensions/Kbuild b/extensions/Kbuild index 38877a9..e4e2490 100644 --- a/extensions/Kbuild +++ b/extensions/Kbuild @@ -7,6 +7,7 @@ obj-m += compat_xtables.o obj-${build_ACCOUNT} += ACCOUNT/ obj-${build_CHAOS} += xt_CHAOS.o +obj-${build_CHECKSUM} += xt_CHECKSUM.o obj-${build_DELUDE} += xt_DELUDE.o obj-${build_DHCPMAC} += xt_DHCPMAC.o obj-${build_ECHO} += xt_ECHO.o diff --git a/extensions/Mbuild b/extensions/Mbuild index 533a703..f5aa137 100644 --- a/extensions/Mbuild +++ b/extensions/Mbuild @@ -2,6 +2,7 @@ obj-${build_ACCOUNT} += ACCOUNT/ obj-${build_CHAOS} += libxt_CHAOS.so +obj-${build_CHECKSUM} += libxt_CHECKSUM.so obj-${build_DELUDE} += libxt_DELUDE.so obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so obj-${build_ECHO} += libxt_ECHO.so diff --git a/extensions/libxt_CHECKSUM.c b/extensions/libxt_CHECKSUM.c new file mode 100644 index 0000000..21bbebf --- /dev/null +++ b/extensions/libxt_CHECKSUM.c @@ -0,0 +1,99 @@ +/* Shared library add-on to xtables for CHECKSUM + * + * (C) 2002 by Harald Welte + * (C) 2010 by Red Hat, Inc + * Author: Michael S. Tsirkin + * + * This program is distributed under the terms of GNU GPL v2, 1991 + * + * libxt_CHECKSUM.c borrowed some bits from libipt_ECN.c + * + * $Id$ + */ +#include +#include +#include +#include + +#include +#include "xt_CHECKSUM.h" + +static void CHECKSUM_help(void) +{ + printf( +"CHECKSUM target options\n" +" --checksum-fill Fill in packet checksum.\n"); +} + +static const struct option CHECKSUM_opts[] = { + { "checksum-fill", 0, NULL, 'F' }, + { .name = NULL } +}; + +static int CHECKSUM_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_target **target) +{ + struct xt_CHECKSUM_info *einfo + = (struct xt_CHECKSUM_info *)(*target)->data; + + switch (c) { + case 'F': + if (*flags) + xtables_error(PARAMETER_PROBLEM, + "CHECKSUM target: Only use --checksum-fill ONCE!"); + einfo->operation = XT_CHECKSUM_OP_FILL; + *flags |= XT_CHECKSUM_OP_FILL; + break; + default: + return 0; + } + + return 1; +} + +static void CHECKSUM_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "CHECKSUM target: Parameter --checksum-fill is required"); +} + +static void CHECKSUM_print(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_CHECKSUM_info *einfo = + (const struct xt_CHECKSUM_info *)target->data; + + printf("CHECKSUM "); + + if (einfo->operation & XT_CHECKSUM_OP_FILL) + printf("fill "); +} + +static void CHECKSUM_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_CHECKSUM_info *einfo = + (const struct xt_CHECKSUM_info *)target->data; + + if (einfo->operation & XT_CHECKSUM_OP_FILL) + printf("--checksum-fill "); +} + +static struct xtables_target checksum_tg_reg = { + .name = "CHECKSUM", + .version = XTABLES_VERSION, + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_CHECKSUM_info)), + .help = CHECKSUM_help, + .parse = CHECKSUM_parse, + .final_check = CHECKSUM_check, + .print = CHECKSUM_print, + .save = CHECKSUM_save, + .extra_opts = CHECKSUM_opts, +}; + +static __attribute__((constructor)) void _init(void) +{ + xtables_register_target(&checksum_tg_reg); +} diff --git a/extensions/libxt_CHECKSUM.man b/extensions/libxt_CHECKSUM.man new file mode 100644 index 0000000..92ae700 --- /dev/null +++ b/extensions/libxt_CHECKSUM.man @@ -0,0 +1,8 @@ +This target allows to selectively work around broken/old applications. +It can only be used in the mangle table. +.TP +\fB\-\-checksum\-fill\fP +Compute and fill in the checksum in a packet that lacks a checksum. +This is particularly useful, if you need to work around old applications +such as dhcp clients, that do not work well with checksum offloads, +but don't want to disable checksum offload in your device. diff --git a/extensions/xt_CHECKSUM.c b/extensions/xt_CHECKSUM.c new file mode 100644 index 0000000..2ae1960 --- /dev/null +++ b/extensions/xt_CHECKSUM.c @@ -0,0 +1,75 @@ +/* iptables module for the packet checksum mangling + * + * (C) 2002 by Harald Welte + * (C) 2010 Red Hat, Inc. + * + * Author: Michael S. Tsirkin + * + * 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. +*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include +#include +#include + +#include +#include "xt_CHECKSUM.h" +#include "compat_xtables.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael S. Tsirkin "); +MODULE_DESCRIPTION("Xtables: checksum modification"); +MODULE_ALIAS("ipt_CHECKSUM"); +MODULE_ALIAS("ip6t_CHECKSUM"); + +static unsigned int +checksum_tg(struct sk_buff **pskb, const struct xt_action_param *par) +{ + struct sk_buff *skb = *pskb; + + if (skb->ip_summed == CHECKSUM_PARTIAL) + skb_checksum_help(skb); + + return XT_CONTINUE; +} + +static int checksum_tg_check(const struct xt_tgchk_param *par) +{ + const struct xt_CHECKSUM_info *einfo = par->targinfo; + + if (einfo->operation & ~XT_CHECKSUM_OP_FILL) { + pr_info("unsupported CHECKSUM operation %x\n", einfo->operation); + return -EINVAL; + } + if (!einfo->operation) { + pr_info("no CHECKSUM operation enabled\n"); + return -EINVAL; + } + return 0; +} + +static struct xt_target checksum_tg_reg __read_mostly = { + .name = "CHECKSUM", + .family = NFPROTO_UNSPEC, + .target = checksum_tg, + .targetsize = sizeof(struct xt_CHECKSUM_info), + .table = "mangle", + .checkentry = checksum_tg_check, + .me = THIS_MODULE, +}; + +static int __init checksum_tg_init(void) +{ + return xt_register_target(&checksum_tg_reg); +} + +static void __exit checksum_tg_exit(void) +{ + xt_unregister_target(&checksum_tg_reg); +} + +module_init(checksum_tg_init); +module_exit(checksum_tg_exit); diff --git a/extensions/xt_CHECKSUM.h b/extensions/xt_CHECKSUM.h new file mode 100644 index 0000000..56afe57 --- /dev/null +++ b/extensions/xt_CHECKSUM.h @@ -0,0 +1,18 @@ +/* Header file for iptables ipt_CHECKSUM target + * + * (C) 2002 by Harald Welte + * (C) 2010 Red Hat Inc + * Author: Michael S. Tsirkin + * + * This software is distributed under GNU GPL v2, 1991 +*/ +#ifndef _IPT_CHECKSUM_TARGET_H +#define _IPT_CHECKSUM_TARGET_H + +#define XT_CHECKSUM_OP_FILL 0x01 /* fill in checksum in IP header */ + +struct xt_CHECKSUM_info { + u_int8_t operation; /* bitset of operations */ +}; + +#endif /* _IPT_CHECKSUM_TARGET_H */ diff --git a/mconfig b/mconfig index b10731b..a119e26 100644 --- a/mconfig +++ b/mconfig @@ -2,6 +2,7 @@ # build_ACCOUNT=m build_CHAOS=m +build_CHECKSUM=m build_DELUDE=m build_DHCPMAC=m build_ECHO=