summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2002-05-29 12:26:13 +0000
committerHarald Welte <laforge@gnumonks.org>2002-05-29 12:26:13 +0000
commitc980a240bad8f8995805df3bfdfb18180dd08d03 (patch)
tree193048f51112c61f51469ac050b9d2741eb47470
parentcea2ca33bbe40bcbe04f6d60f3af5b9a5c57fa1a (diff)
bring ECN plugin in sync with new ECN target
-rw-r--r--extensions/libipt_ECN.c75
-rw-r--r--include/linux/netfilter_ipv4/ipt_ECN.h28
2 files changed, 80 insertions, 23 deletions
diff --git a/extensions/libipt_ECN.c b/extensions/libipt_ECN.c
index fdd5c009..c7ee7710 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 <stdio.h>
#include <string.h>
@@ -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 1a02de76..bdbc2b39 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 <linux/netfilter_ipv4/ipt_DSCP.h>
-#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 */