Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 1 | #ifndef _ACKVEC_H |
| 2 | #define _ACKVEC_H |
| 3 | /* |
| 4 | * net/dccp/ackvec.h |
| 5 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 6 | * An implementation of Ack Vectors for the DCCP protocol |
| 7 | * Copyright (c) 2007 University of Aberdeen, Scotland, UK |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 8 | * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com> |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 9 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms of the GNU General Public License version 2 as |
| 11 | * published by the Free Software Foundation. |
| 12 | */ |
| 13 | |
Gerrit Renker | b20a9c2 | 2008-11-23 16:02:31 -0800 | [diff] [blame] | 14 | #include <linux/dccp.h> |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 15 | #include <linux/compiler.h> |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 16 | #include <linux/list.h> |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 17 | #include <linux/types.h> |
| 18 | |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 19 | /* |
| 20 | * Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN, |
| 21 | * the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1 |
| 22 | * will be sufficient for most cases of low Ack Ratios, using a value of 2 gives |
| 23 | * more headroom if Ack Ratio is higher or when the sender acknowledges slowly. |
| 24 | */ |
| 25 | #define DCCPAV_NUM_ACKVECS 2 |
| 26 | #define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS) |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 27 | |
Gerrit Renker | 361a5c1 | 2009-02-27 22:38:28 +0000 | [diff] [blame] | 28 | /* Estimated minimum average Ack Vector length - used for updating MPS */ |
| 29 | #define DCCPAV_MIN_OPTLEN 16 |
| 30 | |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 31 | enum dccp_ackvec_states { |
| 32 | DCCPAV_RECEIVED = 0x00, |
| 33 | DCCPAV_ECN_MARKED = 0x40, |
| 34 | DCCPAV_RESERVED = 0x80, |
| 35 | DCCPAV_NOT_RECEIVED = 0xC0 |
| 36 | }; |
| 37 | #define DCCPAV_MAX_RUNLEN 0x3F |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 38 | |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 39 | static inline u8 dccp_ackvec_runlen(const u8 *cell) |
| 40 | { |
| 41 | return *cell & DCCPAV_MAX_RUNLEN; |
| 42 | } |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 43 | |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 44 | static inline u8 dccp_ackvec_state(const u8 *cell) |
| 45 | { |
| 46 | return *cell & ~DCCPAV_MAX_RUNLEN; |
| 47 | } |
| 48 | |
| 49 | /** struct dccp_ackvec - Ack Vector main data structure |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 50 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 51 | * This implements a fixed-size circular buffer within an array and is largely |
| 52 | * based on Appendix A of RFC 4340. |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 53 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 54 | * @av_buf: circular buffer storage area |
| 55 | * @av_buf_head: head index; begin of live portion in @av_buf |
| 56 | * @av_buf_tail: tail index; first index _after_ the live portion in @av_buf |
| 57 | * @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf |
| 58 | * @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to |
| 59 | * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf |
| 60 | * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously) |
| 61 | * @av_veclen: length of the live portion of @av_buf |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 62 | */ |
| 63 | struct dccp_ackvec { |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 64 | u8 av_buf[DCCPAV_MAX_ACKVEC_LEN]; |
Gerrit Renker | a47c510 | 2007-12-30 04:19:31 -0800 | [diff] [blame] | 65 | u16 av_buf_head; |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 66 | u16 av_buf_tail; |
| 67 | u64 av_buf_ackno:48; |
| 68 | bool av_buf_nonce[DCCPAV_NUM_ACKVECS]; |
| 69 | struct list_head av_records; |
Gerrit Renker | a47c510 | 2007-12-30 04:19:31 -0800 | [diff] [blame] | 70 | u16 av_vec_len; |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 71 | }; |
| 72 | |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 73 | /** struct dccp_ackvec_record - Records information about sent Ack Vectors |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 74 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 75 | * These list entries define the additional information which the HC-Receiver |
| 76 | * keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A. |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 77 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 78 | * @avr_node: the list node in @av_records |
| 79 | * @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on |
| 80 | * @avr_ack_ackno: the Ack number that this record/Ack Vector refers to |
| 81 | * @avr_ack_ptr: pointer into @av_buf where this record starts |
| 82 | * @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending |
| 83 | * @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 84 | * |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 85 | * The list as a whole is sorted in descending order by @avr_ack_seqno. |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 86 | */ |
| 87 | struct dccp_ackvec_record { |
Gerrit Renker | a47c510 | 2007-12-30 04:19:31 -0800 | [diff] [blame] | 88 | struct list_head avr_node; |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 89 | u64 avr_ack_seqno:48; |
| 90 | u64 avr_ack_ackno:48; |
Gerrit Renker | a47c510 | 2007-12-30 04:19:31 -0800 | [diff] [blame] | 91 | u16 avr_ack_ptr; |
Gerrit Renker | f17a37c | 2010-11-10 21:20:07 +0100 | [diff] [blame] | 92 | u8 avr_ack_runlen; |
| 93 | u8 avr_ack_nonce:1; |
Andrea Bittau | 02bcf28 | 2006-03-20 17:19:55 -0800 | [diff] [blame] | 94 | }; |
| 95 | |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 96 | struct sock; |
| 97 | struct sk_buff; |
| 98 | |
Arnaldo Carvalho de Melo | 9b07ef5 | 2006-03-20 17:16:17 -0800 | [diff] [blame] | 99 | extern int dccp_ackvec_init(void); |
| 100 | extern void dccp_ackvec_exit(void); |
| 101 | |
Arnaldo Carvalho de Melo | 7400d78 | 2006-03-20 17:15:42 -0800 | [diff] [blame] | 102 | extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority); |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 103 | extern void dccp_ackvec_free(struct dccp_ackvec *av); |
| 104 | |
| 105 | extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, |
| 106 | const u64 ackno, const u8 state); |
| 107 | |
| 108 | extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, |
| 109 | struct sock *sk, const u64 ackno); |
| 110 | extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, |
Andrea Bittau | bdf13d2 | 2006-11-24 13:02:42 -0200 | [diff] [blame] | 111 | u64 *ackno, const u8 opt, |
| 112 | const u8 *value, const u8 len); |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 113 | |
Gerrit Renker | 7d87093 | 2010-11-10 21:21:02 +0100 | [diff] [blame^] | 114 | extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 115 | |
| 116 | static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) |
| 117 | { |
Gerrit Renker | a47c510 | 2007-12-30 04:19:31 -0800 | [diff] [blame] | 118 | return av->av_vec_len; |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 119 | } |
Arnaldo Carvalho de Melo | ae31c33 | 2005-09-18 00:17:51 -0700 | [diff] [blame] | 120 | #endif /* _ACKVEC_H */ |