]> Git Repo - J-linux.git/blob - net/netfilter/xt_CHECKSUM.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / net / netfilter / xt_CHECKSUM.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* iptables module for the packet checksum mangling
3  *
4  * (C) 2002 by Harald Welte <[email protected]>
5  * (C) 2010 Red Hat, Inc.
6  *
7  * Author: Michael S. Tsirkin <[email protected]>
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
19 MODULE_LICENSE("GPL");
20 MODULE_AUTHOR("Michael S. Tsirkin <[email protected]>");
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 && !skb_is_gso(skb))
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         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
66 static struct xt_target checksum_tg_reg[] __read_mostly = {
67         {
68                 .name           = "CHECKSUM",
69                 .family         = NFPROTO_IPV4,
70                 .target         = checksum_tg,
71                 .targetsize     = sizeof(struct xt_CHECKSUM_info),
72                 .table          = "mangle",
73                 .checkentry     = checksum_tg_check,
74                 .me             = THIS_MODULE,
75         },
76 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
77         {
78                 .name           = "CHECKSUM",
79                 .family         = NFPROTO_IPV6,
80                 .target         = checksum_tg,
81                 .targetsize     = sizeof(struct xt_CHECKSUM_info),
82                 .table          = "mangle",
83                 .checkentry     = checksum_tg_check,
84                 .me             = THIS_MODULE,
85         },
86 #endif
87 };
88
89 static int __init checksum_tg_init(void)
90 {
91         return xt_register_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
92 }
93
94 static void __exit checksum_tg_exit(void)
95 {
96         xt_unregister_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
97 }
98
99 module_init(checksum_tg_init);
100 module_exit(checksum_tg_exit);
This page took 0.030466 seconds and 4 git commands to generate.