From b64d627096eb7e5106bc12b40c224d5cdd9d8bd9 Mon Sep 17 00:00:00 2001 From: laforge Date: Wed, 29 May 2002 12:26:13 +0000 Subject: bring ECN plugin in sync with new ECN target --- extensions/libipt_ECN.c | 75 ++++++++++++++++++++++++++++------ include/linux/netfilter_ipv4/ipt_ECN.h | 28 ++++++++----- 2 files changed, 80 insertions(+), 23 deletions(-) diff --git a/extensions/libipt_ECN.c b/extensions/libipt_ECN.c index fdd5c00..c7ee771 100644 --- a/extensions/libipt_ECN.c +++ b/extensions/libipt_ECN.c @@ -6,7 +6,7 @@ * * libipt_ECN.c borrowed heavily from libipt_DSCP.c * - * $Id: libipt_ECN.c,v 1.2 2002/02/18 21:32:56 laforge Exp $ + * $Id: libipt_ECN.c,v 1.3 2002/04/10 13:12:53 laforge Exp $ */ #include #include @@ -25,13 +25,20 @@ static void help(void) { printf( "ECN target options\n" -" --ecn-remove Remove all ECN bits which may be present\n" +" --ecn-tcp-remove Remove all ECN bits which may be present\n" " in the IPv4 header\n" +"ECN target EXPERIMENTAL options (use with extreme care!)\n" +" --ecn-ip-ect Set the IPv4 ECT codepoint (0 to 3)\n" +" --ecn-tcp-cwr Set the IPv4 CWR bit (0 or 1)\n" +" --ecn-tcp-ece Set the IPv4 CWR bit (0 or 1)\n" ); } static struct option opts[] = { - { "ecn-remove", 1, 0, 'F' }, + { "ecn-tcp-remove", 0, 0, 'F' }, + { "ecn-tcp-cwr", 1, 0, 'G' }, + { "ecn-tcp-ece", 1, 0, 'H' }, + { "ecn-ip-ect", 1, 0, '9' }, { 0 } }; @@ -40,6 +47,7 @@ parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { + unsigned int result; struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)(*target)->data; @@ -47,11 +55,43 @@ parse(int c, char **argv, int invert, unsigned int *flags, case 'F': if (*flags) exit_error(PARAMETER_PROBLEM, - "ECN target: Only use --ecn-remove ONCE!"); - einfo->operation = IPT_ECN_OP_REMOVE; + "ECN target: Only use --ecn-tcp-remove ONCE!"); + einfo->operation = IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR; + einfo->proto.tcp.ece = 0; + einfo->proto.tcp.cwr = 0; *flags = 1; break; - + case 'G': + if (*flags & IPT_ECN_OP_SET_CWR) + exit_error(PARAMETER_PROBLEM, + "ECN target: Only use --ecn-tcp-cwr ONCE!"); + if (string_to_number(optarg, 0, 1, &result)) + exit_error(PARAMETER_PROBLEM, + "ECN target: Value out of range"); + einfo->operation |= IPT_ECN_OP_SET_CWR; + einfo->proto.tcp.cwr = result; + *flags |= IPT_ECN_OP_SET_CWR; + break; + case 'H': + if (*flags & IPT_ECN_OP_SET_ECE) + exit_error(PARAMETER_PROBLEM, + "ECN target: Only use --ecn-tcp-ece ONCE!"); + if (string_to_number(optarg, 0, 1, &result)) + exit_error(PARAMETER_PROBLEM, + "ECN target: Value out of range"); + einfo->operation |= IPT_ECN_OP_SET_ECE; + einfo->proto.tcp.ece = result; + *flags |= IPT_ECN_OP_SET_ECE; + break; + case '9': + if (*flags & IPT_ECN_OP_SET_IP) + exit_error(PARAMETER_PROBLEM, + "ECN target: Only use --ecn-ip-ect ONCE!"); + if (string_to_number(optarg, 0, 3, &result)) + exit_error(PARAMETER_PROBLEM, + "ECN target: Value out of range"); + einfo->operation |= IPT_ECN_OP_SET_IP; + einfo->ip_ect = result; default: return 0; } @@ -79,9 +119,14 @@ print(const struct ipt_ip *ip, printf("ECN "); switch (einfo->operation) { - case IPT_ECN_OP_REMOVE: - printf("remove "); + case IPT_ECN_OP_SET_ECE: + printf("ECE=%u ", einfo->proto.tcp.ece); + break; + case IPT_ECN_OP_SET_CWR: + printf("CWR=%u ", einfo->proto.tcp.cwr); break; + case IPT_ECN_OP_SET_IP: + printf("ECT codepoint=%u ", einfo->ip_ect); default: printf("unsupported_ecn_operation "); break; @@ -95,10 +140,16 @@ save(const struct ipt_ip *ip, const struct ipt_entry_target *target) const struct ipt_ECN_info *einfo = (const struct ipt_ECN_info *)target->data; - switch (einfo->operation) { - case IPT_ECN_OP_REMOVE: - printf("--ecn-remove "); - break; + if (einfo->operation & IPT_ECN_OP_SET_ECE) { + printf("--ecn-tcp-ece %d ", einfo->proto.tcp.ece); + } + + if (einfo->operation & IPT_ECN_OP_SET_CWR) { + printf("--ecn-tcp-cwr %d ", einfo->proto.tcp.cwr); + } + + if (einfo->operation & IPT_ECN_OP_SET_IP) { + printf("--ecn-ip-ect %d ", einfo->ip_ect); } } diff --git a/include/linux/netfilter_ipv4/ipt_ECN.h b/include/linux/netfilter_ipv4/ipt_ECN.h index 1a02de7..bdbc2b3 100644 --- a/include/linux/netfilter_ipv4/ipt_ECN.h +++ b/include/linux/netfilter_ipv4/ipt_ECN.h @@ -4,22 +4,28 @@ * * This software is distributed under GNU GPL v2, 1991 * - * ipt_ECN.h,v 1.1 2002/02/17 21:30:16 laforge Exp + * $Id: ipt_ECN.h,v 1.2 2002/04/17 19:52:26 laforge Exp $ */ -#ifndef _IPT_DSCP_H -#define _IPT_DSCP_H +#ifndef _IPT_ECN_TARGET_H +#define _IPT_ECN_TARGET_H #include -#define IPT_ECN_MASK (~IPT_DSCP_MASK) +#define IPT_ECN_IP_MASK (~IPT_DSCP_MASK) -enum ipt_ecn_operation { - IPT_ECN_OP_NONE = 0, - IPT_ECN_OP_REMOVE, -}; -#define IPT_ECN_OP_MAX IPT_ECN_OP_REMOVE +#define IPT_ECN_OP_SET_IP 0x01 /* set ECN bits of IPv4 header */ +#define IPT_ECN_OP_SET_ECE 0x10 /* set ECE bit of TCP header */ +#define IPT_ECN_OP_SET_CWR 0x20 /* set CWR bit of TCP header */ + +#define IPT_ECN_OP_MASK 0xce struct ipt_ECN_info { - enum ipt_ecn_operation operation; + u_int8_t operation; /* bitset of operations */ + u_int8_t ip_ect; /* ECT codepoint of IPv4 header, pre-shifted */ + union { + struct { + u_int8_t ece:1, cwr:1; /* TCP ECT bits */ + } tcp; + } proto; }; -#endif /* _IPT_ECN_H */ +#endif /* _IPT_ECN_TARGET_H */ -- cgit v1.2.3