* [PATCH 0/10]: DCCPv4/6 support for ECN/ECT(0) [not found] <dccp_test_tree_sending_ecn_for_review> @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 1/10]: Put the ECN bits into the dccp_skb_cb Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev This extends DCCP with ECN/ECT(0) capability, requesting review and comments. In particular, * following RFC 2474 and RFC 3168, the set takes an AF-independent approach, * the kernel still takes an AF-dependent approach (inet->tos, inet6->tclass), so it would be good to have input what the general trend is, * some of the patches touch on general issues and hence need discussion. Patch #1: Adds the ECN bits into the CB, for processing by DCCP and its CCIDs. Patch #2: Adds a sysctl to for dccpv4/6 ECN support (similar to tcp_ecn sysctl). Patch #3: Adds feature-negotiation handler for DCCP ECN support. Patch #4: Is a hack to add ECN support. It is _not_ meant for consideration. I'd appreciate any suggestions of doing this better. Currently there is no full IPv6 ECN support: only TCPv4 uses ECN, SCTPv6 uses a workaround. If you are reviewing this, please also check the next one. Patch #5: Disables userspace modification of ECN bits via IP_TOS/IPV6_TCLASS, since this will corrupt the internal ECN values. It is needed by this approach for DCCP, but also by SCTPv6, since it is otherwise possible to modify the ECN bits of np->tclass in userspace. Patch #6: Extends the TFRC loss interval code of DCCP to support ECN. Patch #7: Complements patch #6 by adding support for ECN-CE congestion events. Patch #8: Adds Ack Vector ECN support to CCID-2. Patch #9: AF-independent modification of DCCP ECN bits (compare #5). Patch #10: AF-independent reading of DCCP-ECN bits; complements #9. All patches (apart from #5) have been tested for approximately one year and are now integrated into the DCCP test tree available at git://eden-feed.erg.abdn.ac.uk/dccp_exp [subtree 'dccp'] http://eden-feed.erg.abdn.ac.uk [web view] http://eden-feed.erg.abdn.ac.uk/latest-dccp-test-tree.tar.bz2 Before doing this, I compile-tested the tree again and ran a quick iperf test to ensure that ECT(0) is now working (DCCPv6 tested via ::1 loopback). ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 1/10]: Put the ECN bits into the dccp_skb_cb 2009-08-09 19:48 ` [PATCH 0/10]: DCCPv4/6 support for ECN/ECT(0) Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 2/10] Add sysctl to toggle the local support for ECN Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This adds the two bits from the IPv4 TOS or IPv6 Traffic Class field into the dccp_skb_cb. To make the required room, dccp_opt_len is curtailed to 10 bits, since the DCCP option length can not exceed 1020 < 2^10-1. Further changes: ---------------- * added code to copy the TOS/traffic class field contents, * supplied a utility function that checks for CE, * deleted duplicate inclusion of headers. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- net/dccp/dccp.h | 10 +++++++++- net/dccp/ipv4.c | 5 ++--- net/dccp/ipv6.c | 15 ++++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -14,6 +14,7 @@ #include <linux/dccp.h> #include <linux/ktime.h> +#include <net/inet_ecn.h> #include <net/snmp.h> #include <net/sock.h> #include <net/tcp.h> @@ -355,6 +356,7 @@ static inline int dccp_bad_service_code(const struct sock *sk, * dccp_skb_cb - DCCP per-packet control information * @dccpd_type: one of %dccp_pkt_type (or unknown) * @dccpd_ccval: CCVal field (5.1), see e.g. RFC 4342, 8.1 + * @dccpd_ecn: ECN bits read from the IPv4 TOS / IPv6 Traffic Class field * @dccpd_reset_code: one of %dccp_reset_codes * @dccpd_reset_data: Data1..3 fields (depend on @dccpd_reset_code) * @dccpd_opt_len: total length of all options (5.8) in the packet @@ -371,15 +373,21 @@ struct dccp_skb_cb { } header; __u8 dccpd_type:4; __u8 dccpd_ccval:4; + __u8 dccpd_ecn:2; __u8 dccpd_reset_code, dccpd_reset_data[3]; - __u16 dccpd_opt_len; + __u16 dccpd_opt_len:10; __u64 dccpd_seq; __u64 dccpd_ack_seq; }; #define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0])) +static inline bool dccp_skb_is_ecn_ce(const struct sk_buff *skb) +{ + return (DCCP_SKB_CB(skb)->dccpd_ecn & INET_ECN_MASK) == INET_ECN_CE; +} + /* RFC 4340, sec. 7.7 */ static inline int dccp_non_data_packet(const struct sk_buff *skb) { --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -10,16 +10,13 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/dccp.h> #include <linux/icmp.h> #include <linux/module.h> -#include <linux/skbuff.h> #include <linux/random.h> #include <net/icmp.h> #include <net/inet_common.h> #include <net/inet_hashtables.h> -#include <net/inet_sock.h> #include <net/protocol.h> #include <net/sock.h> #include <net/timewait_sock.h> @@ -783,6 +780,8 @@ static int dccp_v4_rcv(struct sk_buff *skb) goto discard_it; iph = ip_hdr(skb); + DCCP_SKB_CB(skb)->dccpd_ecn = iph->tos & INET_ECN_MASK; + /* Step 1: If header checksum is incorrect, drop packet and return */ if (dccp_v4_csum_finish(skb, iph->saddr, iph->daddr)) { DCCP_WARN("dropped packet with invalid checksum\n"); --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -19,7 +19,6 @@ #include <net/addrconf.h> #include <net/inet_common.h> #include <net/inet_hashtables.h> -#include <net/inet_sock.h> #include <net/inet6_connection_sock.h> #include <net/inet6_hashtables.h> #include <net/ip6_route.h> @@ -783,6 +782,7 @@ discard: static int dccp_v6_rcv(struct sk_buff *skb) { + struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); const struct dccp_hdr *dh; struct sock *sk; int min_cov; @@ -792,6 +792,8 @@ static int dccp_v6_rcv(struct sk_buff *skb) if (dccp_invalid_packet(skb)) goto discard_it; + dcb->dccpd_ecn = ipv6_get_dsfield(ipv6_hdr(skb)) & INET_ECN_MASK; + /* Step 1: If header checksum is incorrect, drop packet and return. */ if (dccp_v6_csum_finish(skb, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr)) { @@ -801,13 +803,13 @@ static int dccp_v6_rcv(struct sk_buff *skb) dh = dccp_hdr(skb); - DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); - DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; + dcb->dccpd_seq = dccp_hdr_seq(dh); + dcb->dccpd_type = dh->dccph_type; if (dccp_packet_without_ack(skb)) - DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ; + dcb->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ; else - DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb); + dcb->dccpd_ack_seq = dccp_hdr_ack_seq(skb); /* Step 2: * Look up flow ID in table and get corresponding socket */ @@ -863,8 +865,7 @@ no_dccp_socket: * Drop packet and return */ if (dh->dccph_type != DCCP_PKT_RESET) { - DCCP_SKB_CB(skb)->dccpd_reset_code = - DCCP_RESET_CODE_NO_CONNECTION; + dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; dccp_v6_ctl_send_reset(sk, skb); } -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 2/10] Add sysctl to toggle the local support for ECN 2009-08-09 19:48 ` dccp-test-tree [PATCH 1/10]: Put the ECN bits into the dccp_skb_cb Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 3/10] Add feature-negotiation handler for ECN-Incapable feature Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This sysctl disables local ECN support for interpreting ECN bits. When set to 0, the host behaves as if it were ECN-incapable: ECN bits are ignored and the mandatory "Change L(ECN Incapable, 1)" (RFC 4340, 12.1) is sent during feature negotiation to signal to the other endpoint to signal that ECN bits will not be interpreted. The behaviour is slightly different from the tcp_ecn sysctl, since DCCP connections are ECN-enabled per default. Setting ECT codepoints in outgoing packets can not be controlled by this sysctl, but is possible by setting the sysctl to 0 at the remote (receiving) end. This signals that the remote end can not read ECN bits. Due to RFC 4340, 12.2, all outgoing packets are then sent as ECN-incapable. Inter-operability issues: the host does not set a preference for the remote ECN Incapable feature. Within the existing feature-negotiation infrastructure, this ensures that all valid values (ECN Incapable = 0 or 1) are acceptable. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- Documentation/networking/dccp.txt | 12 ++++++++++++ net/dccp/feat.c | 23 ++++++++++++++++------- net/dccp/feat.h | 1 + net/dccp/sysctl.c | 8 ++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -29,6 +29,12 @@ It has a base protocol and pluggable congestion control IDs (CCIDs). DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol is at http://www.ietf.org/html.charters/dccp-charter.html +ECN Support +=========== +By default, all outgoing packets are sent with ECT(0) as per RFC 3168, sec. 5. +This can be disabled by setting the `ecn_local' sysctl to 0 (see below). The +ECN Nonce (RFC 3540) is not supported. + Missing features ================ @@ -163,6 +169,12 @@ seq_window = 100 The initial sequence window (sec. 7.5.2) of the sender. This influences the local ackno validity and the remote seqno validity windows (7.5.1). +ecn_local = 1 + This toggles local ECN support: when set to 0, ECN Incapable (sec. 12.1) + is sent and ECN bits of incoming packets are ignored. Note that this is + different from tcp_ecn: to disable sending of ECT codepoints, the remote + peer needs to set this sysctl to zero. + tx_qlen = 5 The size of the transmit buffer in packets. A value of 0 corresponds to an unbounded transmit buffer. --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -29,7 +29,8 @@ /* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */ unsigned long sysctl_dccp_sequence_window __read_mostly = 100; int sysctl_dccp_rx_ccid __read_mostly = 2, - sysctl_dccp_tx_ccid __read_mostly = 2; + sysctl_dccp_tx_ccid __read_mostly = 2, + sysctl_dccp_ecn_local __read_mostly = true; /* * Feature activation handlers. @@ -1111,7 +1112,8 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, * No particular preferences have been registered. We deal with * this situation by assuming that all valid values are equally * acceptable, and apply the following checks: - * - if the peer's list is a singleton, we accept a valid value; + * - if the peer's list is a singleton, we accept a valid value + * (allows to cope gracefully with e.g. remote ECN Incapable); * - if we are the server, we first try to see if the peer (the * client) advertises the default value. If yes, we use it, * otherwise we accept the preferred value; @@ -1430,11 +1432,18 @@ int dccp_feat_init(struct sock *sk) rc = __feat_register_sp(fn, DCCPF_SHORT_SEQNOS, true, true, &off, 1); if (rc) return rc; - - /* RFC 4340 12.1: "If a DCCP is not ECN capable, ..." */ - rc = __feat_register_sp(fn, DCCPF_ECN_INCAPABLE, true, true, &on, 1); - if (rc) - return rc; + /* + * ECN Incapable Feature (RFC 4340, 12.1) + * + * We do not register preferences for the feature-remote value, so that + * the preference list is empty and either value is locally acceptable. + */ + if (!sysctl_dccp_ecn_local) { + rc = __feat_register_sp(fn, DCCPF_ECN_INCAPABLE, + true, true, &on, 1); + if (rc) + return rc; + } /* * We advertise the available list of CCIDs and reorder according to --- a/net/dccp/feat.h +++ b/net/dccp/feat.h @@ -106,6 +106,7 @@ struct ccid_dependency { extern unsigned long sysctl_dccp_sequence_window; extern int sysctl_dccp_rx_ccid; extern int sysctl_dccp_tx_ccid; +extern int sysctl_dccp_ecn_local; extern int dccp_feat_init(struct sock *sk); extern void dccp_feat_initialise_sysctls(void); --- a/net/dccp/sysctl.c +++ b/net/dccp/sysctl.c @@ -78,6 +78,14 @@ static struct ctl_table dccp_default_table[] = { .extra2 = &u8_max, }, { + .procname = "ecn_local", + .data = &sysctl_dccp_ecn_local, + .maxlen = sizeof(sysctl_dccp_ecn_local), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + }, + { .procname = "tx_qlen", .data = &sysctl_dccp_tx_qlen, .maxlen = sizeof(sysctl_dccp_tx_qlen), -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 3/10] Add feature-negotiation handler for ECN-Incapable feature 2009-08-09 19:48 ` dccp-test-tree [PATCH 2/10] Add sysctl to toggle the local support for ECN Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 4/10] net: Hack to enable IPv6 ECN support Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This completes the feature-negotiation support for ECN in DCCP: * a socket field to indicate whether this end is ECN-incapable, * a socket field to record whether the remote end is ECN-capable, * a feature-negotiation handler to activate the local/remote features. When local ECN support is disabled, the ECN bits are erased before passing the skb on to the CCIDs (which perform the actual ECN processing). If the remote end is ECN-capable, dccp_transmit_skb() sets the ECT(0) codepoint. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- include/linux/dccp.h | 4 ++++ net/dccp/feat.c | 13 ++++++++++++- net/dccp/input.c | 13 +++++++++++++ net/dccp/output.c | 3 +++ 4 files changed, 32 insertions(+), 1 deletions(-) --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -467,6 +467,8 @@ struct dccp_ackvec; * @dccps_r_ack_ratio - feature-remote Ack Ratio * @dccps_l_seq_win - local Sequence Window (influences ack number validity) * @dccps_r_seq_win - remote Sequence Window (influences seq number validity) + * @dccps_l_ecn_ok - this host understands ECN bits (RFC 4340, 12.1) + * @dccps_r_ecn_ok - the remote end understands ECN bits * @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) @@ -512,6 +514,8 @@ struct dccp_sock { __u16 dccps_r_ack_ratio; __u64 dccps_l_seq_win:48; __u64 dccps_r_seq_win:48; + bool dccps_l_ecn_ok:1, + dccps_r_ecn_ok:1; __u8 dccps_pcslen:4; __u8 dccps_pcrlen:4; __u8 dccps_send_ndp_count:1; --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -72,6 +72,17 @@ static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx) return 0; } +static int dccp_hdlr_ecn(struct sock *sk, u64 ecn_incapable, bool rx) +{ + struct dccp_sock *dp = dccp_sk(sk); + + if (rx) + dp->dccps_l_ecn_ok = (ecn_incapable == 0); + else + dp->dccps_r_ecn_ok = (ecn_incapable == 0); + return 0; +} + static int dccp_hdlr_ack_ratio(struct sock *sk, u64 ratio, bool rx) { #ifndef __CCID2_COPES_GRACEFULLY_WITH_DYNAMIC_ACK_RATIO_UPDATES__ @@ -170,7 +181,7 @@ static const struct { { DCCPF_CCID, FEAT_AT_TX, FEAT_SP, 2, dccp_hdlr_ccid }, { DCCPF_SHORT_SEQNOS, FEAT_AT_TX, FEAT_SP, 0, NULL }, { DCCPF_SEQUENCE_WINDOW, FEAT_AT_TX, FEAT_NN, 100, dccp_hdlr_seq_win }, - { DCCPF_ECN_INCAPABLE, FEAT_AT_RX, FEAT_SP, 0, NULL }, + { DCCPF_ECN_INCAPABLE, FEAT_AT_RX, FEAT_SP, 0, dccp_hdlr_ecn }, { DCCPF_ACK_RATIO, FEAT_AT_TX, FEAT_NN, 2, dccp_hdlr_ack_ratio}, { DCCPF_SEND_ACK_VECTOR, FEAT_AT_RX, FEAT_SP, 0, dccp_hdlr_ackvec }, { DCCPF_SEND_NDP_COUNT, FEAT_AT_TX, FEAT_SP, 0, dccp_hdlr_ndp }, --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -159,6 +159,17 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) dccp_time_wait(sk, DCCP_TIME_WAIT, 0); } +static void dccp_handle_ecn_codepoints(struct sock *sk, struct sk_buff *skb) +{ + /* + * When locally disabled, erase ECN codepoints (a peer conforming to + * RFC 4340, 12.2 should set these to zero anyway). + */ + if (!dccp_sk(sk)->dccps_l_ecn_ok) + DCCP_SKB_CB(skb)->dccpd_ecn = INET_ECN_NOT_ECT; + +} + static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) { struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; @@ -372,6 +383,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, if (dccp_parse_options(sk, NULL, skb)) return 1; + dccp_handle_ecn_codepoints(sk, skb); dccp_handle_ackvec_processing(sk, skb); dccp_deliver_input_to_ccids(sk, skb); @@ -665,6 +677,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, case DCCP_PARTOPEN: /* Step 8: if using Ack Vectors, mark packet acknowledgeable */ + dccp_handle_ecn_codepoints(sk, skb); dccp_handle_ackvec_processing(sk, skb); dccp_deliver_input_to_ccids(sk, skb); /* fall through */ --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -130,6 +130,9 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) break; } + if (dp->dccps_r_ecn_ok) + INET_ECN_xmit(sk); + icsk->icsk_af_ops->send_check(sk, 0, skb); if (set_ack) -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 4/10] net: Hack to enable IPv6 ECN support 2009-08-09 19:48 ` dccp-test-tree [PATCH 3/10] Add feature-negotiation handler for ECN-Incapable feature Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 5/10] net: Mask out ECN bits when setting TOS/TCLASS Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker ECN is not currently supported on inet6 sockets. This is a hack to copy over the ECN bits when ECN-capable transport has been enabled on the inet_sk socket. This allows to support DCCPv6 ECN support, but needs to be revised: * the inet_sock already has an u8 `tos' field for the DSCP/ECN bits; * the same field is present as u8 `tclass' field in ipv6_pinfo; * the DS field (RFC 2474) and the ECN bits (RFC 3168) are AF-independent, so TOS/Traffic Class could be made AF-independent; * sockets that include ipv6_pinfo also include struct inet_sock. Ideally there should be one field, e.g. `inet->dsfield', but doing this requires some more careful analysis, since inet_sk(sk)->tos and inet6_sk(sk)->tclass are referenced all over the source code. Leaving this for the moment, to be completed later. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- include/net/inet_ecn.h | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -46,9 +46,13 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) (label) &= ~htonl(INET_ECN_MASK << 20); \ } while (0) +/* + * XXX Hack: copy over the ECN bits from inet_sk to inet6_sk. + * This should be replaced by a single `dsfield' in inet + */ #define IP6_ECN_flow_xmit(sk, label) do { \ - if (INET_ECN_is_capable(inet6_sk(sk)->tclass)) \ - (label) |= htonl(INET_ECN_ECT_0 << 20); \ + IP6_ECN_flow_init(label); \ + (label) |= htonl((inet_sk(sk)->tos & INET_ECN_MASK) << 20); \ } while (0) static inline int IP_ECN_set_ce(struct iphdr *iph) -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 5/10] net: Mask out ECN bits when setting TOS/TCLASS 2009-08-09 19:48 ` dccp-test-tree [PATCH 4/10] net: Hack to enable IPv6 ECN support Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 6/10] Extend the loss interval code to support ECN events Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This patch is needed by the AF-independent approach to provide DCCPv4/6 ECN support. Since this approach handles ECN at in the module, the patch disables user-side manipulation of ECN bits via TOS/TCLASS. However, it also fixes a bug occurring in SCTPv6: when passing values that contain 0x1 in the ECN bits, the internal value of ECT(0) gets turned into 0x3 = CE, i.e. it suggests to the other side that congestion was experienced. I am working on these issues and would greatly appreciate feedback/suggestions. (NB - not touched datagram_send_ctl(), since it is used only by udpv6/rawv6). An alternative for modifying ECN bits in user space is in a subsequent patch. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- net/ipv4/ip_sockglue.c | 7 ++++--- net/ipv6/ipv6_sockglue.c | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -27,6 +27,7 @@ #include <net/ip.h> #include <net/icmp.h> #include <net/tcp_states.h> +#include <net/inet_ecn.h> #include <linux/udp.h> #include <linux/igmp.h> #include <linux/netfilter.h> @@ -550,9 +551,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR; break; case IP_TOS: /* This sets both TOS and Precedence */ - if (sk->sk_type == SOCK_STREAM) { - val &= ~3; - val |= inet->tos & 3; + if (sk->sk_type != SOCK_RAW) { + val &= ~INET_ECN_MASK; + val |= inet->tos & INET_ECN_MASK; } if (inet->tos != val) { inet->tos = val; --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -318,6 +318,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, /* RFC 3542, 6.5: default traffic class of 0x0 */ if (val == -1) val = 0; + if (sk->sk_type != SOCK_RAW) + val &= ~INET_ECN_MASK; np->tclass = val; retv = 0; break; -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 6/10] Extend the loss interval code to support ECN events 2009-08-09 19:48 ` dccp-test-tree [PATCH 5/10] net: Mask out ECN bits when setting TOS/TCLASS Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 7/10] Extend the packet-history code to support ECN-marked-CE events Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This updates the TFRC loss intervals code, which so far could only support lost packets, to also handle the case of ECN-marked-CE packets: * the begin and length of the loss interval are different; * there are combinations of loss + ECN-marked-CE which the code does not currently consider (it is not worth the complexity), comments have been added to point this out. Further changes: ---------------- The implementation of the "is the loss interval already closed?" check as per RFC 4342, 10.2 has been improved to test the condition more efficiently. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- net/dccp/ccids/lib/loss_interval.c | 76 ++++++++++++++++++++++++++++-------- 1 files changed, 59 insertions(+), 17 deletions(-) --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c @@ -124,12 +124,12 @@ void tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb) tfrc_lh_calc_i_mean(lh); } -/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */ -static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur, - struct tfrc_rx_hist_entry *new_loss) +/* RFC 4342, 10.2: test for the existence of packet with sequence number S */ +static bool tfrc_lh_closed_check(struct tfrc_loss_interval *cur, const u8 ccval) { - return dccp_delta_seqno(cur->li_seqno, new_loss->tfrchrx_seqno) > 0 && - (cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4); + if (SUB16(ccval, cur->li_ccval) > 4) + cur->li_is_closed = true; + return cur->li_is_closed; } /** tfrc_lh_interval_add - Insert new record into the Loss Interval database @@ -142,27 +142,69 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur, bool tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh, u32 (*calc_first_li)(struct sock *), struct sock *sk) { - struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new; + struct tfrc_loss_interval *cur = tfrc_lh_peek(lh); + struct tfrc_rx_hist_entry *cong_evt; + u64 cong_evt_seqno; + + /* + * Determine if the new event is caused by a lost or ECN-marked packet. + * Both events can coincide (e.g. if the third packet after a loss is + * marked as CE). We avoid the complexity caused by such mixed cases: + * 1) if the cause is a lost packet, we do not check whether it is + * also an ECN-marked packet (not necessary); + * 2) calling this routine with a loss_count of 0..NDUPACK-1 implies + * that the cause is an ECN-marked-CE packet. + * FIXME: if in this case the loss_count is not 0, loss tracking is + * reset. This is a complex corner case (see packet_history.c) and + * hence currently not supported. + */ + if (rh->loss_count == TFRC_NDUPACK) { + /* + * The sequence number of the first packet known to be lost is + * the successor of the last packet received before the gap. + */ + cong_evt = tfrc_rx_hist_loss_prev(rh); + cong_evt_seqno = ADD48(cong_evt->tfrchrx_seqno, 1); + } else { + /* + * ECN-marked packet. Since ECN-marks are reported as soon as a + * packet is delivered, it is stored in the last-received entry. + */ + cong_evt = tfrc_rx_hist_last_rcv(rh); + cong_evt_seqno = cong_evt->tfrchrx_seqno; + } - if (cur != NULL && !tfrc_lh_is_new_loss(cur, tfrc_rx_hist_loss_prev(rh))) - return false; + /* Test if this event starts a new loss interval */ + if (cur != NULL) { + s64 len = dccp_delta_seqno(cur->li_seqno, cong_evt_seqno); + if (len <= 0) + return false; + + if (!tfrc_lh_closed_check(cur, cong_evt->tfrchrx_ccval)) + return false; - new = tfrc_lh_demand_next(lh); - if (unlikely(new == NULL)) { + /* RFC 5348, 5.3: length between subsequent intervals */ + cur->li_length = len; + } + + /* Make the new interval the current one */ + cur = tfrc_lh_demand_next(lh); + if (unlikely(cur == NULL)) { DCCP_CRIT("Cannot allocate/add loss record."); return false; } - new->li_seqno = tfrc_rx_hist_loss_prev(rh)->tfrchrx_seqno; - new->li_ccval = tfrc_rx_hist_loss_prev(rh)->tfrchrx_ccval; - new->li_is_closed = 0; + cur->li_seqno = cong_evt_seqno; + cur->li_ccval = cong_evt->tfrchrx_ccval; + cur->li_is_closed = false; if (++lh->counter == 1) - lh->i_mean = new->li_length = (*calc_first_li)(sk); + lh->i_mean = cur->li_length = (*calc_first_li)(sk); else { - cur->li_length = dccp_delta_seqno(cur->li_seqno, new->li_seqno); - new->li_length = dccp_delta_seqno(new->li_seqno, - tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno) + 1; + /* RFC 5348, 5.3: length of the open loss interval I_0 */ + cur->li_length = dccp_delta_seqno(cur->li_seqno, + tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno) + 1; + if (lh->counter > (2*LIH_SIZE)) lh->counter -= LIH_SIZE; -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 7/10] Extend the packet-history code to support ECN-marked-CE events 2009-08-09 19:48 ` dccp-test-tree [PATCH 6/10] Extend the loss interval code to support ECN events Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 8/10] ccid-2: Ack Vector ECN support Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This extends the main accounting routine, tfrc_rx_congestion_event, to also consider ECN-marks. Loss and ECN-marks are treated separately: when there is already a loss event, it is not necessary to also check for ECN marks (there will be at most one new congestion event anyway). Conversely, if there is an ECN-event, tracking a pending loss is disabled. This is due to the fact that considering every possible combination of loss_count with/-out ECN-marks creates a lot of complexity which does not seem warranted -- comments added to point this out. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- net/dccp/ccids/lib/packet_history.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c @@ -360,6 +360,27 @@ bool tfrc_rx_congestion_event(struct tfrc_rx_hist *h, */ new_event = tfrc_lh_interval_add(lh, h, first_li, sk); __three_after_loss(h); + + } else if (dccp_data_packet(skb) && dccp_skb_is_ecn_ce(skb)) { + /* + * We only test for ECN marks on data packets. This is the way + * the RFC considers ECN marks - a future implementation may + * find it useful to also check ECN marks on non-data packets. + */ + new_event = tfrc_lh_interval_add(lh, h, first_li, sk); + /* + * Also combinations of loss and ECN-marks (as per the warning) + * are not supported. The permutations of loss combined with or + * without ECN-marks create a lot of complexity, which does not + * seem warranted: ECN-marked packets immediately trigger con- + * gestion events. + * Testing is needed to see whether ignoring the loss_count in + * light of an ECN-marked-CE event really has any disadvantages. + */ + if (new_event && h->loss_count) { + DCCP_WARN("Ignoring loss count due to ECN\n"); + tfrc_rx_hist_resume_rtt_sampling(h); + } } /* -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 8/10] ccid-2: Ack Vector ECN support 2009-08-09 19:48 ` dccp-test-tree [PATCH 7/10] Extend the packet-history code to support ECN-marked-CE events Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 9/10] Userspace support for modifying the ECN bits of Data/DataAck packets Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This adds Ack Vector support for registering ECN packets marked as congestion-experienced (CE), and a FIXME to look after the Ack Vector Nonce Sum (RFC 4340, 12.2 and RFC 3450, 3.). Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- net/dccp/ackvec.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -250,6 +250,16 @@ void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb) u64 seqno = DCCP_SKB_CB(skb)->dccpd_seq; enum dccp_ackvec_states state = DCCPAV_RECEIVED; + if (DCCP_SKB_CB(skb)->dccpd_ecn == INET_ECN_CE) + state = DCCPAV_ECN_MARKED; + else if (DCCP_SKB_CB(skb)->dccpd_ecn == INET_ECN_ECT_1) + /* + * FIXME: As long as we get ECT(0), the nonce sum is 0 as per + * RFC 3540, sec. 3. Supporting ECT(1) requires more work, as + * e.g. older Ack Vector cells must then be summed over again. + */ + DCCP_WARN("Ack Vector Nonce sum does not yet support ECT(1)\n"); + if (dccp_ackvec_is_empty(av)) { dccp_ackvec_add_new(av, 1, seqno, state); av->av_tail_ackno = seqno; -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 9/10] Userspace support for modifying the ECN bits of Data/DataAck packets 2009-08-09 19:48 ` dccp-test-tree [PATCH 8/10] ccid-2: Ack Vector ECN support Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 2009-08-09 19:48 ` dccp-test-tree [PATCH 10/10] Userspace support for reading ECN bits Gerrit Renker 0 siblings, 1 reply; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This allows to pass ECN bits as cmsg ancillary data with a cmsg_type of DCCP_SCM_ECN_BITS for Data/DataAck packets. The scope of this patch is for developing user-space applications that work with, modify, or control the use of ECN bits on data packets. RFC: This is an AF-independent alternative to using IP_TOS/IPV6_TCLASS for modifying the ECN bits. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- Documentation/networking/dccp.txt | 12 ++++++++++-- include/linux/dccp.h | 1 + net/dccp/output.c | 10 +++++++--- net/dccp/proto.c | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -32,8 +32,16 @@ is at http://www.ietf.org/html.charters/dccp-charter.html ECN Support =========== By default, all outgoing packets are sent with ECT(0) as per RFC 3168, sec. 5. -This can be disabled by setting the `ecn_local' sysctl to 0 (see below). The -ECN Nonce (RFC 3540) is not supported. +This can be disabled by setting the `ecn_local' sysctl to 0 (see below). + +For Data/DataAck packets, the ECN bits can be modified by passing an appropriate +cmsg(3) value as ancillary data to sendmsg(2). The argument is an uint8_t value +between 0..3 (corresponding to Not-ECT, ECT(1), ECT(0), and CE). Values greater +than 3 are not accepted. Values need to be wrapped into a cmsg(3) header: + cmsg->cmsg_level = SOL_DCCP; + cmsg->cmsg_type = DCCP_SCM_ECN_BITS; + cmsg->cmsg_len = CMSG_LEN(sizeof(uint8_t)); /* or CMSG_LEN(1) */ + Missing features ================ --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -202,6 +202,7 @@ enum dccp_cmsg_type { DCCP_SCM_PRIORITY = 1, DCCP_SCM_QPOLICY_MAX = 0xFFFF, /* ^-- Up to here reserved exclusively for qpolicy parameters */ + DCCP_SCM_ECN_BITS, DCCP_SCM_MAX }; --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -53,7 +53,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) const u32 dccp_header_size = sizeof(*dh) + sizeof(struct dccp_hdr_ext) + dccp_packet_hdr_len(dcb->dccpd_type); - int err, set_ack = 1; + int err, set_ack = 1, ecn_bits = INET_ECN_ECT_0; u64 ackno = dp->dccps_gsr; /* * Increment GSS here already in case the option code needs it. @@ -66,6 +66,8 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) set_ack = 0; /* fall through */ case DCCP_PKT_DATAACK: + /* ECN bits of Data/DataAck are set in dccp_sendmsg() */ + ecn_bits = DCCP_SKB_CB(skb)->dccpd_ecn; case DCCP_PKT_RESET: break; @@ -130,8 +132,10 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) break; } - if (dp->dccps_r_ecn_ok) - INET_ECN_xmit(sk); + if (dp->dccps_r_ecn_ok) { + inet_sk(sk)->tos &= ~INET_ECN_MASK; + inet_sk(sk)->tos |= ecn_bits & INET_ECN_MASK; + } icsk->icsk_af_ops->send_check(sk, 0, skb); --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -707,7 +707,17 @@ EXPORT_SYMBOL_GPL(compat_dccp_getsockopt); static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) { + const struct dccp_sock *dp = dccp_sk(skb->sk); struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg); + u8 val; + + /* + * Setting ECN bits via DCCP_SCM_ECN_BITS: Data/DataAck only. + * See dccp_transmit_skb() where further processing takes place. + * By default, when no cmsg bits are supplied and when ECN is not + * disabled, ECT(0) is used for all outgoing packets (RFC 3168, 5.). + */ + DCCP_SKB_CB(skb)->dccpd_ecn = INET_ECN_ECT_0; /* * Assign an (opaque) qpolicy priority value to skb->priority. @@ -739,6 +749,16 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) return -EINVAL; skb->priority = *(__u32 *)CMSG_DATA(cmsg); break; + case DCCP_SCM_ECN_BITS: + if (!dp->dccps_r_ecn_ok) + return -EINVAL; + if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u8))) + return -EINVAL; + val = *(__u8 *)CMSG_DATA(cmsg); + if (val > INET_ECN_MASK) + return -EINVAL; + DCCP_SKB_CB(skb)->dccpd_ecn = val; + break; default: return -EINVAL; } -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* dccp-test-tree [PATCH 10/10] Userspace support for reading ECN bits 2009-08-09 19:48 ` dccp-test-tree [PATCH 9/10] Userspace support for modifying the ECN bits of Data/DataAck packets Gerrit Renker @ 2009-08-09 19:48 ` Gerrit Renker 0 siblings, 0 replies; 11+ messages in thread From: Gerrit Renker @ 2009-08-09 19:48 UTC (permalink / raw) To: dccp; +Cc: netdev, Gerrit Renker This adds support to read the ECN bits of incoming DCCP packets. RFC: This is an AF-independent alternative to IP_RECVTOS/IPV6_RECVTCLASS. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> --- Documentation/networking/dccp.txt | 6 ++++++ include/linux/dccp.h | 5 ++++- net/dccp/proto.c | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 1 deletions(-) --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -41,6 +41,8 @@ than 3 are not accepted. Values need to be wrapped into a cmsg(3) header: cmsg->cmsg_level = SOL_DCCP; cmsg->cmsg_type = DCCP_SCM_ECN_BITS; cmsg->cmsg_len = CMSG_LEN(sizeof(uint8_t)); /* or CMSG_LEN(1) */ +The process can be reversed for recvmsg(2) when the DCCP_SOCKOPT_GET_ECN_BITS +socket option is enabled (see below), using the same cmsg encapsulation. Missing features @@ -131,6 +133,10 @@ DCCP_SOCKOPT_RECV_CSCOV is for the receiver and has a different meaning: it restrictive this setting (see [RFC 4340, sec. 9.2.1]). Partial coverage settings are inherited to the child socket after accept(). +DCCP_SOCKOPT_GET_ECN_BITS takes a boolean int value and enables the delivery + of ECN bits as ancillary data to recvmsg(2). The data is received as + uint8_t value at SOL_DCCP level and cmsg_type of DCCP_SCM_ECN_BITS. + The following two options apply to CCID 3 exclusively and are getsockopt()-only. In either case, a TFRC info struct (defined in <linux/tfrc.h>) is returned. DCCP_SOCKOPT_CCID_RX_INFO --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -228,6 +228,7 @@ enum dccp_packet_dequeueing_policy { #define DCCP_SOCKOPT_RX_CCID 15 #define DCCP_SOCKOPT_QPOLICY_ID 16 #define DCCP_SOCKOPT_QPOLICY_TXQLEN 17 +#define DCCP_SOCKOPT_GET_ECN_BITS 18 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 @@ -470,6 +471,7 @@ struct dccp_ackvec; * @dccps_r_seq_win - remote Sequence Window (influences seq number validity) * @dccps_l_ecn_ok - this host understands ECN bits (RFC 4340, 12.1) * @dccps_r_ecn_ok - the remote end understands ECN bits + * @dccps_get_ecn_bits - this host requests ECN bits as recvmsg() ancillary data * @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) @@ -516,7 +518,8 @@ struct dccp_sock { __u64 dccps_l_seq_win:48; __u64 dccps_r_seq_win:48; bool dccps_l_ecn_ok:1, - dccps_r_ecn_ok:1; + dccps_r_ecn_ok:1, + dccps_get_ecn_bits:1; __u8 dccps_pcslen:4; __u8 dccps_pcrlen:4; __u8 dccps_send_ndp_count:1; --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -550,6 +550,9 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, else dp->dccps_tx_qlen = val; break; + case DCCP_SOCKOPT_GET_ECN_BITS: + dp->dccps_get_ecn_bits = (val != 0); + break; default: err = -ENOPROTOOPT; break; @@ -663,6 +666,9 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, case DCCP_SOCKOPT_QPOLICY_TXQLEN: val = dp->dccps_tx_qlen; break; + case DCCP_SOCKOPT_GET_ECN_BITS: + val = dp->dccps_get_ecn_bits; + break; case 128 ... 191: return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, len, (u32 __user *)optval, optlen); @@ -825,6 +831,13 @@ out_discard: EXPORT_SYMBOL_GPL(dccp_sendmsg); +static void dccp_cmsg_recv_ecn_bits(struct msghdr *msg, struct sk_buff *skb) +{ + u8 val = DCCP_SKB_CB(skb)->dccpd_ecn; + + put_cmsg(msg, SOL_DCCP, DCCP_SCM_ECN_BITS, sizeof(val), &val); +} + int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int flags, int *addr_len) { @@ -919,6 +932,8 @@ verify_sock_status: len = -EFAULT; break; } + if (dccp_sk(sk)->dccps_get_ecn_bits) + dccp_cmsg_recv_ecn_bits(msg, skb); found_fin_ok: if (!(flags & MSG_PEEK)) sk_eat_skb(sk, skb, 0); -- 1.6.0.rc2 ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-08-09 19:53 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <dccp_test_tree_sending_ecn_for_review>
2009-08-09 19:48 ` [PATCH 0/10]: DCCPv4/6 support for ECN/ECT(0) Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 1/10]: Put the ECN bits into the dccp_skb_cb Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 2/10] Add sysctl to toggle the local support for ECN Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 3/10] Add feature-negotiation handler for ECN-Incapable feature Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 4/10] net: Hack to enable IPv6 ECN support Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 5/10] net: Mask out ECN bits when setting TOS/TCLASS Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 6/10] Extend the loss interval code to support ECN events Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 7/10] Extend the packet-history code to support ECN-marked-CE events Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 8/10] ccid-2: Ack Vector ECN support Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 9/10] Userspace support for modifying the ECN bits of Data/DataAck packets Gerrit Renker
2009-08-09 19:48 ` dccp-test-tree [PATCH 10/10] Userspace support for reading ECN bits Gerrit Renker
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox