Hi Graham,
Dans un message du 05 aoû à 11:49, Graham Murray écrivait :
> When running with ECN enabled, unclean complains "TCP reserved bits
> not zero" on packets with the ECN and/or CWR bits set.
This check uses the TCP_RESERVED_BITS macro that is defined according to
RFC793 : 'Reserved: 6 bits Reserved for future use. Must be zero.'
ECN uses the last two bits of the reserved field.
Imho a packet with ECN bits should not be considered as unclean even if
ECN is not enabled on the firewall.
I see three solutions.
1) Removing this check. I've seen some network experts claiming that
reserved bits should never mean "equal to zero". But in this case,
RFC793 clearly states that these bits should be zero. Therefore, I don't
think it is the best solution.
2) Fixing the check by ignoring the ECN bits.
diff -uNr linux-2.4.7-vanilla/net/ipv4/netfilter/ipt_unclean.c linux-fixed-unclean/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.7-vanilla/net/ipv4/netfilter/ipt_unclean.c Sun Aug 5 16:37:48 2001
+++ linux-fixed-unclean/net/ipv4/netfilter/ipt_unclean.c Sun Aug 5 17:12:03 2001
@@ -321,8 +321,8 @@
return 0;
}
- /* CHECK: TCP reserved bits zero. */
- if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
+ /* CHECK: TCP reserved bits (except TCP ECN related bits) zero. */
+ if(tcp_flag_word(tcph) & TCP_RESERVED_BITS & ~(TCP_FLAG_CWR|TCP_FLAG_ECE)) {
limpk("TCP reserved bits not zero\n");
return 0;
}
3) Define TCP_RESERVED_BITS according to RFC ECN update. This macro is
used by netfilter (here and for the LOG target) and to define
TCP_HP_BITS (header prediction). Thus we need to modify TCP_HP_BITS
definition as well. Imho, the best solution.
diff -uNr linux-2.4.7-vanilla/include/linux/tcp.h linux-new-tcp-reserved-bits/include/linux/tcp.h
--- linux-2.4.7-vanilla/include/linux/tcp.h Sun Aug 5 16:37:43 2001
+++ linux-new-tcp-reserved-bits/include/linux/tcp.h Sun Aug 5 18:20:44 2001
@@ -110,7 +110,7 @@
TCP_FLAG_RST = __constant_htonl(0x00040000),
TCP_FLAG_SYN = __constant_htonl(0x00020000),
TCP_FLAG_FIN = __constant_htonl(0x00010000),
- TCP_RESERVED_BITS = __constant_htonl(0x0FC00000),
+ TCP_RESERVED_BITS = __constant_htonl(0x0F000000),
TCP_DATA_OFFSET = __constant_htonl(0xF0000000)
};
diff -uNr linux-2.4.7-vanilla/include/net/tcp_ecn.h linux-new-tcp-reserved-bits/include/net/tcp_ecn.h
--- linux-2.4.7-vanilla/include/net/tcp_ecn.h Sun Aug 5 16:37:44 2001
+++ linux-new-tcp-reserved-bits/include/net/tcp_ecn.h Sun Aug 5 18:22:36 2001
@@ -7,7 +7,7 @@
#include <net/inet_ecn.h>
-#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)|TCP_FLAG_ECE|TCP_FLAG_CWR)
+#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
#define TCP_ECN_OK 1
#define TCP_ECN_QUEUE_CWR 2
@@ -137,7 +137,7 @@
#else
-#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
+#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH) & ~(TCP_FLAG_ECE|TCP_FLAG_CWR))
#define TCP_ECN_send_syn(x...) do { } while (0)
Both patches have been tested. I currently run the second one (3rd
solution) on my own firewall flawlessly.
Any comments on this welcome.
Regards,
--
Guillaume Morin <guillaume@morinfr.org>
If it doesn't work, force it. If it breaks, it needed replacing anyway.
Dans un message du 05 aoû à 11:49, Graham Murray écrivait :
> When running with ECN enabled, unclean complains "TCP reserved bits
> not zero" on packets with the ECN and/or CWR bits set.
This check uses the TCP_RESERVED_BITS macro that is defined according to
RFC793 : 'Reserved: 6 bits Reserved for future use. Must be zero.'
ECN uses the last two bits of the reserved field.
Imho a packet with ECN bits should not be considered as unclean even if
ECN is not enabled on the firewall.
I see three solutions.
1) Removing this check. I've seen some network experts claiming that
reserved bits should never mean "equal to zero". But in this case,
RFC793 clearly states that these bits should be zero. Therefore, I don't
think it is the best solution.
2) Fixing the check by ignoring the ECN bits.
diff -uNr linux-2.4.7-vanilla/net/ipv4/netfilter/ipt_unclean.c linux-fixed-unclean/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.7-vanilla/net/ipv4/netfilter/ipt_unclean.c Sun Aug 5 16:37:48 2001
+++ linux-fixed-unclean/net/ipv4/netfilter/ipt_unclean.c Sun Aug 5 17:12:03 2001
@@ -321,8 +321,8 @@
return 0;
}
- /* CHECK: TCP reserved bits zero. */
- if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
+ /* CHECK: TCP reserved bits (except TCP ECN related bits) zero. */
+ if(tcp_flag_word(tcph) & TCP_RESERVED_BITS & ~(TCP_FLAG_CWR|TCP_FLAG_ECE)) {
limpk("TCP reserved bits not zero\n");
return 0;
}
3) Define TCP_RESERVED_BITS according to RFC ECN update. This macro is
used by netfilter (here and for the LOG target) and to define
TCP_HP_BITS (header prediction). Thus we need to modify TCP_HP_BITS
definition as well. Imho, the best solution.
diff -uNr linux-2.4.7-vanilla/include/linux/tcp.h linux-new-tcp-reserved-bits/include/linux/tcp.h
--- linux-2.4.7-vanilla/include/linux/tcp.h Sun Aug 5 16:37:43 2001
+++ linux-new-tcp-reserved-bits/include/linux/tcp.h Sun Aug 5 18:20:44 2001
@@ -110,7 +110,7 @@
TCP_FLAG_RST = __constant_htonl(0x00040000),
TCP_FLAG_SYN = __constant_htonl(0x00020000),
TCP_FLAG_FIN = __constant_htonl(0x00010000),
- TCP_RESERVED_BITS = __constant_htonl(0x0FC00000),
+ TCP_RESERVED_BITS = __constant_htonl(0x0F000000),
TCP_DATA_OFFSET = __constant_htonl(0xF0000000)
};
diff -uNr linux-2.4.7-vanilla/include/net/tcp_ecn.h linux-new-tcp-reserved-bits/include/net/tcp_ecn.h
--- linux-2.4.7-vanilla/include/net/tcp_ecn.h Sun Aug 5 16:37:44 2001
+++ linux-new-tcp-reserved-bits/include/net/tcp_ecn.h Sun Aug 5 18:22:36 2001
@@ -7,7 +7,7 @@
#include <net/inet_ecn.h>
-#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)|TCP_FLAG_ECE|TCP_FLAG_CWR)
+#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
#define TCP_ECN_OK 1
#define TCP_ECN_QUEUE_CWR 2
@@ -137,7 +137,7 @@
#else
-#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
+#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH) & ~(TCP_FLAG_ECE|TCP_FLAG_CWR))
#define TCP_ECN_send_syn(x...) do { } while (0)
Both patches have been tested. I currently run the second one (3rd
solution) on my own firewall flawlessly.
Any comments on this welcome.
Regards,
--
Guillaume Morin <guillaume@morinfr.org>
If it doesn't work, force it. If it breaks, it needed replacing anyway.