xt_CHECKSUM.c (2230B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* iptables module for the packet checksum mangling 3 * 4 * (C) 2002 by Harald Welte <laforge@netfilter.org> 5 * (C) 2010 Red Hat, Inc. 6 * 7 * Author: Michael S. Tsirkin <mst@redhat.com> 8*/ 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10#include <linux/module.h> 11#include <linux/skbuff.h> 12 13#include <linux/netfilter/x_tables.h> 14#include <linux/netfilter/xt_CHECKSUM.h> 15 16#include <linux/netfilter_ipv4/ip_tables.h> 17#include <linux/netfilter_ipv6/ip6_tables.h> 18 19MODULE_LICENSE("GPL"); 20MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>"); 21MODULE_DESCRIPTION("Xtables: checksum modification"); 22MODULE_ALIAS("ipt_CHECKSUM"); 23MODULE_ALIAS("ip6t_CHECKSUM"); 24 25static unsigned int 26checksum_tg(struct sk_buff *skb, const struct xt_action_param *par) 27{ 28 if (skb->ip_summed == CHECKSUM_PARTIAL && !skb_is_gso(skb)) 29 skb_checksum_help(skb); 30 31 return XT_CONTINUE; 32} 33 34static int checksum_tg_check(const struct xt_tgchk_param *par) 35{ 36 const struct xt_CHECKSUM_info *einfo = par->targinfo; 37 const struct ip6t_ip6 *i6 = par->entryinfo; 38 const struct ipt_ip *i4 = par->entryinfo; 39 40 if (einfo->operation & ~XT_CHECKSUM_OP_FILL) { 41 pr_info_ratelimited("unsupported CHECKSUM operation %x\n", 42 einfo->operation); 43 return -EINVAL; 44 } 45 if (!einfo->operation) 46 return -EINVAL; 47 48 switch (par->family) { 49 case NFPROTO_IPV4: 50 if (i4->proto == IPPROTO_UDP && 51 (i4->invflags & XT_INV_PROTO) == 0) 52 return 0; 53 break; 54 case NFPROTO_IPV6: 55 if ((i6->flags & IP6T_F_PROTO) && 56 i6->proto == IPPROTO_UDP && 57 (i6->invflags & XT_INV_PROTO) == 0) 58 return 0; 59 break; 60 } 61 62 pr_warn_once("CHECKSUM should be avoided. If really needed, restrict with \"-p udp\" and only use in OUTPUT\n"); 63 return 0; 64} 65 66static struct xt_target checksum_tg_reg __read_mostly = { 67 .name = "CHECKSUM", 68 .family = NFPROTO_UNSPEC, 69 .target = checksum_tg, 70 .targetsize = sizeof(struct xt_CHECKSUM_info), 71 .table = "mangle", 72 .checkentry = checksum_tg_check, 73 .me = THIS_MODULE, 74}; 75 76static int __init checksum_tg_init(void) 77{ 78 return xt_register_target(&checksum_tg_reg); 79} 80 81static void __exit checksum_tg_exit(void) 82{ 83 xt_unregister_target(&checksum_tg_reg); 84} 85 86module_init(checksum_tg_init); 87module_exit(checksum_tg_exit);