9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/module.h>
15 #include <linux/tcp.h>
18 #include <linux/netfilter/x_tables.h>
19 #include <linux/netfilter_ipv4/ip_tables.h>
24 MODULE_DESCRIPTION(
"Xtables: Explicit Congestion Notification (ECN) flag modification");
29 set_ect_ip(
struct sk_buff *
skb,
const struct ipt_ECN_info *einfo)
31 struct iphdr *iph = ip_hdr(skb);
48 set_ect_tcp(
struct sk_buff *skb,
const struct ipt_ECN_info *einfo)
50 struct tcphdr _tcph, *tcph;
54 tcph = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_tcph), &_tcph);
58 if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
59 tcph->ece == einfo->proto.tcp.ece) &&
60 (!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
61 tcph->cwr == einfo->proto.tcp.cwr))
66 tcph = (
void *)ip_hdr(skb) + ip_hdrlen(skb);
68 oldval = ((
__be16 *)tcph)[6];
69 if (einfo->operation & IPT_ECN_OP_SET_ECE)
70 tcph->ece = einfo->proto.tcp.ece;
71 if (einfo->operation & IPT_ECN_OP_SET_CWR)
72 tcph->cwr = einfo->proto.tcp.cwr;
74 inet_proto_csum_replace2(&tcph->
check, skb,
75 oldval, ((
__be16 *)tcph)[6], 0);
82 const struct ipt_ECN_info *einfo = par->
targinfo;
84 if (einfo->operation & IPT_ECN_OP_SET_IP)
85 if (!set_ect_ip(skb, einfo))
88 if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR) &&
90 if (!set_ect_tcp(skb, einfo))
98 const struct ipt_ECN_info *einfo = par->
targinfo;
101 if (einfo->operation & IPT_ECN_OP_MASK) {
102 pr_info(
"unsupported ECN operation %x\n", einfo->operation);
106 pr_info(
"new ECT codepoint %x out of mask\n", einfo->ip_ect);
109 if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
111 pr_info(
"cannot use TCP operations on a non-tcp rule\n");
121 .targetsize =
sizeof(
struct ipt_ECN_info),
123 .checkentry = ecn_tg_check,
127 static int __init ecn_tg_init(
void)
132 static void __exit ecn_tg_exit(
void)