2005-09-18 14:17:51 +07:00
|
|
|
#ifndef _ACKVEC_H
|
|
|
|
#define _ACKVEC_H
|
|
|
|
/*
|
|
|
|
* net/dccp/ackvec.h
|
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* An implementation of the DCCP protocol
|
2005-09-18 14:17:51 +07:00
|
|
|
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com>
|
2008-09-09 18:27:22 +07:00
|
|
|
*
|
2005-09-18 14:17:51 +07:00
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/compiler.h>
|
2008-09-09 18:27:22 +07:00
|
|
|
#include <linux/ktime.h>
|
2006-03-21 08:19:55 +07:00
|
|
|
#include <linux/list.h>
|
2005-09-18 14:17:51 +07:00
|
|
|
#include <linux/types.h>
|
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
/* Read about the ECN nonce to see why it is 253 */
|
|
|
|
#define DCCP_MAX_ACKVEC_OPT_LEN 253
|
|
|
|
/* We can spread an ack vector across multiple options */
|
|
|
|
#define DCCP_MAX_ACKVEC_LEN (DCCP_MAX_ACKVEC_OPT_LEN * 2)
|
2005-09-18 14:17:51 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
#define DCCP_ACKVEC_STATE_RECEIVED 0
|
|
|
|
#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
|
|
|
|
#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6)
|
2005-09-18 14:17:51 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
#define DCCP_ACKVEC_STATE_MASK 0xC0 /* 11000000 */
|
|
|
|
#define DCCP_ACKVEC_LEN_MASK 0x3F /* 00111111 */
|
dccp ccid-2: Ack Vector interface clean-up
This patch brings the Ack Vector interface up to date. Its main purpose is
to lay the basis for the subsequent patches of this set, which will use the
new data structure fields and routines.
There are no real algorithmic changes, rather an adaptation:
(1) Replaced the static Ack Vector size (2) with a #define so that it can
be adapted (with low loss / Ack Ratio, a value of 1 works, so 2 seems
to be sufficient for the moment) and added a solution so that computing
the ECN nonce will continue to work - even with larger Ack Vectors.
(2) Replaced the #defines for Ack Vector states with a complete enum.
(3) Replaced #defines to compute Ack Vector length and state with general
purpose routines (inlines), and updated code to use these.
(4) Added a `tail' field (conversion to circular buffer in subsequent patch).
(5) Updated the (outdated) documentation for Ack Vector struct.
(6) All sequence number containers now trimmed to 48 bits.
(7) Removal of unused bits:
* removed dccpav_ack_nonce from struct dccp_ackvec, since this is already
redundantly stored in the `dccpavr_ack_nonce' (of Ack Vector record);
* removed Elapsed Time for Ack Vectors (it was nowhere used);
* replaced semantics of dccpavr_sent_len with dccpavr_ack_runlen, since
the code needs to be able to remember the old run length;
* reduced the de-/allocation routines (redundant / duplicate tests).
Justification for removing Elapsed Time information [can be removed]:
---------------------------------------------------------------------
1. The Elapsed Time information for Ack Vectors was nowhere used in the code.
2. DCCP does not implement rate-based pacing of acknowledgments. The only
recommendation for always including Elapsed Time is in section 11.3 of
RFC 4340: "Receivers that rate-pace acknowledgements SHOULD [...]
include Elapsed Time options". But such is not the case here.
3. It does not really improve estimation accuracy. The Elapsed Time field only
records the time between the arrival of the last acknowledgeable packet and
the time the Ack Vector is sent out. Since Linux does not (yet) implement
delayed Acks, the time difference will typically be small, since often the
arrival of a data packet triggers sending feedback at the HC-receiver.
Justification for changes in de-/allocation routines [can be removed]:
----------------------------------------------------------------------
* INIT_LIST_HEAD in dccp_ackvec_record_new was redundant, since the list
pointers were later overwritten when the node was added via list_add();
* dccp_ackvec_record_new() was called in a single place only;
* calls to list_del_init() before calling dccp_ackvec_record_delete() were
redundant, since subsequently the entire element was k-freed;
* since all calls to dccp_ackvec_record_delete() were preceded to a call to
list_del_init(), the WARN_ON test would never evaluate to true;
* since all calls to dccp_ackvec_record_delete() were made from within
list_for_each_entry_safe(), the test for avr == NULL was redundant;
* list_empty() in ackvec_free was redundant, since the same condition is
embedded in the loop condition of the subsequent list_for_each_entry_safe().
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
2008-09-04 12:30:19 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
/** struct dccp_ackvec - ack vector
|
|
|
|
*
|
|
|
|
* This data structure is the one defined in RFC 4340, Appendix A.
|
2005-09-18 14:17:51 +07:00
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* @av_buf_head - circular buffer head
|
|
|
|
* @av_buf_tail - circular buffer tail
|
|
|
|
* @av_buf_ackno - ack # of the most recent packet acknowledgeable in the
|
|
|
|
* buffer (i.e. %av_buf_head)
|
|
|
|
* @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
|
|
|
|
* by the buffer with State 0
|
2005-09-18 14:17:51 +07:00
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* Additionally, the HC-Receiver must keep some information about the
|
|
|
|
* Ack Vectors it has recently sent. For each packet sent carrying an
|
|
|
|
* Ack Vector, it remembers four variables:
|
|
|
|
*
|
|
|
|
* @av_records - list of dccp_ackvec_record
|
|
|
|
* @av_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
|
|
|
|
*
|
|
|
|
* @av_time - the time in usecs
|
|
|
|
* @av_buf - circular buffer of acknowledgeable packets
|
2005-09-18 14:17:51 +07:00
|
|
|
*/
|
|
|
|
struct dccp_ackvec {
|
2008-09-09 18:27:22 +07:00
|
|
|
u64 av_buf_ackno;
|
dccp ccid-2: Ack Vector interface clean-up
This patch brings the Ack Vector interface up to date. Its main purpose is
to lay the basis for the subsequent patches of this set, which will use the
new data structure fields and routines.
There are no real algorithmic changes, rather an adaptation:
(1) Replaced the static Ack Vector size (2) with a #define so that it can
be adapted (with low loss / Ack Ratio, a value of 1 works, so 2 seems
to be sufficient for the moment) and added a solution so that computing
the ECN nonce will continue to work - even with larger Ack Vectors.
(2) Replaced the #defines for Ack Vector states with a complete enum.
(3) Replaced #defines to compute Ack Vector length and state with general
purpose routines (inlines), and updated code to use these.
(4) Added a `tail' field (conversion to circular buffer in subsequent patch).
(5) Updated the (outdated) documentation for Ack Vector struct.
(6) All sequence number containers now trimmed to 48 bits.
(7) Removal of unused bits:
* removed dccpav_ack_nonce from struct dccp_ackvec, since this is already
redundantly stored in the `dccpavr_ack_nonce' (of Ack Vector record);
* removed Elapsed Time for Ack Vectors (it was nowhere used);
* replaced semantics of dccpavr_sent_len with dccpavr_ack_runlen, since
the code needs to be able to remember the old run length;
* reduced the de-/allocation routines (redundant / duplicate tests).
Justification for removing Elapsed Time information [can be removed]:
---------------------------------------------------------------------
1. The Elapsed Time information for Ack Vectors was nowhere used in the code.
2. DCCP does not implement rate-based pacing of acknowledgments. The only
recommendation for always including Elapsed Time is in section 11.3 of
RFC 4340: "Receivers that rate-pace acknowledgements SHOULD [...]
include Elapsed Time options". But such is not the case here.
3. It does not really improve estimation accuracy. The Elapsed Time field only
records the time between the arrival of the last acknowledgeable packet and
the time the Ack Vector is sent out. Since Linux does not (yet) implement
delayed Acks, the time difference will typically be small, since often the
arrival of a data packet triggers sending feedback at the HC-receiver.
Justification for changes in de-/allocation routines [can be removed]:
----------------------------------------------------------------------
* INIT_LIST_HEAD in dccp_ackvec_record_new was redundant, since the list
pointers were later overwritten when the node was added via list_add();
* dccp_ackvec_record_new() was called in a single place only;
* calls to list_del_init() before calling dccp_ackvec_record_delete() were
redundant, since subsequently the entire element was k-freed;
* since all calls to dccp_ackvec_record_delete() were preceded to a call to
list_del_init(), the WARN_ON test would never evaluate to true;
* since all calls to dccp_ackvec_record_delete() were made from within
list_for_each_entry_safe(), the test for avr == NULL was redundant;
* list_empty() in ackvec_free was redundant, since the same condition is
embedded in the loop condition of the subsequent list_for_each_entry_safe().
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
2008-09-04 12:30:19 +07:00
|
|
|
struct list_head av_records;
|
2008-09-09 18:27:22 +07:00
|
|
|
ktime_t av_time;
|
|
|
|
u16 av_buf_head;
|
|
|
|
u16 av_vec_len;
|
|
|
|
u8 av_buf_nonce;
|
|
|
|
u8 av_ack_nonce;
|
|
|
|
u8 av_buf[DCCP_MAX_ACKVEC_LEN];
|
2005-09-18 14:17:51 +07:00
|
|
|
};
|
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
/** struct dccp_ackvec_record - ack vector record
|
2006-03-21 08:19:55 +07:00
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* ACK vector record as defined in Appendix A of spec.
|
2006-03-21 08:19:55 +07:00
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* The list is sorted by avr_ack_seqno
|
2006-03-21 08:19:55 +07:00
|
|
|
*
|
2008-09-09 18:27:22 +07:00
|
|
|
* @avr_node - node in av_records
|
|
|
|
* @avr_ack_seqno - sequence number of the packet this record was sent on
|
|
|
|
* @avr_ack_ackno - sequence number being acknowledged
|
|
|
|
* @avr_ack_ptr - pointer into av_buf where this record starts
|
|
|
|
* @avr_ack_nonce - av_ack_nonce at the time this record was sent
|
|
|
|
* @avr_sent_len - lenght of the record in av_buf
|
2006-03-21 08:19:55 +07:00
|
|
|
*/
|
|
|
|
struct dccp_ackvec_record {
|
2007-12-30 19:19:31 +07:00
|
|
|
struct list_head avr_node;
|
2008-09-09 18:27:22 +07:00
|
|
|
u64 avr_ack_seqno;
|
|
|
|
u64 avr_ack_ackno;
|
2007-12-30 19:19:31 +07:00
|
|
|
u16 avr_ack_ptr;
|
2008-09-09 18:27:22 +07:00
|
|
|
u16 avr_sent_len;
|
|
|
|
u8 avr_ack_nonce;
|
2006-03-21 08:19:55 +07:00
|
|
|
};
|
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
struct sock;
|
|
|
|
struct sk_buff;
|
|
|
|
|
|
|
|
#ifdef CONFIG_IP_DCCP_ACKVEC
|
|
|
|
extern int dccp_ackvec_init(void);
|
2006-03-21 08:16:17 +07:00
|
|
|
extern void dccp_ackvec_exit(void);
|
|
|
|
|
2006-03-21 08:15:42 +07:00
|
|
|
extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority);
|
2005-09-18 14:17:51 +07:00
|
|
|
extern void dccp_ackvec_free(struct dccp_ackvec *av);
|
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
|
|
|
|
const u64 ackno, const u8 state);
|
|
|
|
|
|
|
|
extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
|
|
|
|
struct sock *sk, const u64 ackno);
|
|
|
|
extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
|
|
|
|
u64 *ackno, const u8 opt,
|
|
|
|
const u8 *value, const u8 len);
|
2005-09-18 14:17:51 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb);
|
|
|
|
|
|
|
|
static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
|
|
|
|
{
|
|
|
|
return av->av_vec_len;
|
|
|
|
}
|
|
|
|
#else /* CONFIG_IP_DCCP_ACKVEC */
|
|
|
|
static inline int dccp_ackvec_init(void)
|
2005-09-18 14:17:51 +07:00
|
|
|
{
|
2008-09-09 18:27:22 +07:00
|
|
|
return 0;
|
2005-09-18 14:17:51 +07:00
|
|
|
}
|
2008-09-04 12:30:19 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
static inline void dccp_ackvec_exit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void dccp_ackvec_free(struct dccp_ackvec *av)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
|
|
|
|
const u64 ackno, const u8 state)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-04 12:30:19 +07:00
|
|
|
|
2008-09-09 18:27:22 +07:00
|
|
|
static inline void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
|
|
|
|
struct sock *sk, const u64 ackno)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
|
|
|
|
const u64 *ackno, const u8 opt,
|
|
|
|
const u8 *value, const u8 len)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int dccp_insert_option_ackvec(const struct sock *sk,
|
|
|
|
const struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_IP_DCCP_ACKVEC */
|
2005-09-18 14:17:51 +07:00
|
|
|
#endif /* _ACKVEC_H */
|