Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ed1deb70
Commit
ed1deb70
authored
Nov 11, 2010
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dccp' of
git://eden-feed.erg.abdn.ac.uk/net-next-2.6
parents
72cdd1d9
b3d14bff
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
225 additions
and
236 deletions
+225
-236
net/dccp/ackvec.c
net/dccp/ackvec.c
+83
-168
net/dccp/ackvec.h
net/dccp/ackvec.h
+65
-50
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.c
+5
-8
net/dccp/dccp.h
net/dccp/dccp.h
+7
-4
net/dccp/input.c
net/dccp/input.c
+2
-4
net/dccp/options.c
net/dccp/options.c
+63
-2
No files found.
net/dccp/ackvec.c
View file @
ed1deb70
This diff is collapsed.
Click to expand it.
net/dccp/ackvec.h
View file @
ed1deb70
...
...
@@ -3,9 +3,9 @@
/*
* net/dccp/ackvec.h
*
* An implementation of the DCCP protocol
* An implementation of Ack Vectors for the DCCP protocol
* Copyright (c) 2007 University of Aberdeen, Scotland, UK
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com>
*
* 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.
...
...
@@ -13,75 +13,89 @@
#include <linux/dccp.h>
#include <linux/compiler.h>
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/types.h>
/* We can spread an ack vector across multiple options */
#define DCCP_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * 2)
/*
* Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN,
* the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1
* will be sufficient for most cases of low Ack Ratios, using a value of 2 gives
* more headroom if Ack Ratio is higher or when the sender acknowledges slowly.
* The maximum value is bounded by the u16 types for indices and functions.
*/
#define DCCPAV_NUM_ACKVECS 2
#define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS)
/* Estimated minimum average Ack Vector length - used for updating MPS */
#define DCCPAV_MIN_OPTLEN 16
#define DCCP_ACKVEC_STATE_RECEIVED 0
#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6)
enum
dccp_ackvec_states
{
DCCPAV_RECEIVED
=
0x00
,
DCCPAV_ECN_MARKED
=
0x40
,
DCCPAV_RESERVED
=
0x80
,
DCCPAV_NOT_RECEIVED
=
0xC0
};
#define DCCPAV_MAX_RUNLEN 0x3F
#define DCCP_ACKVEC_STATE_MASK 0xC0
/* 11000000 */
#define DCCP_ACKVEC_LEN_MASK 0x3F
/* 00111111 */
static
inline
u8
dccp_ackvec_runlen
(
const
u8
*
cell
)
{
return
*
cell
&
DCCPAV_MAX_RUNLEN
;
}
/** struct dccp_ackvec - ack vector
*
* This data structure is the one defined in RFC 4340, Appendix A.
*
* @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
*
* 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:
static
inline
u8
dccp_ackvec_state
(
const
u8
*
cell
)
{
return
*
cell
&
~
DCCPAV_MAX_RUNLEN
;
}
/** struct dccp_ackvec - Ack Vector main data structure
*
*
@av_records - list of dccp_ackvec_record
*
@av_ack_nonce - the one-bit sum of the ECN Nonces for all State
0.
*
This implements a fixed-size circular buffer within an array and is largely
*
based on Appendix A of RFC 434
0.
*
* @av_time - the time in usecs
* @av_buf - circular buffer of acknowledgeable packets
* @av_buf: circular buffer storage area
* @av_buf_head: head index; begin of live portion in @av_buf
* @av_buf_tail: tail index; first index _after_ the live portion in @av_buf
* @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf
* @av_tail_ackno: lowest seqno of acknowledgeable packet recorded in @av_buf
* @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to
* %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf
* @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound
* @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously)
* @av_veclen: length of the live portion of @av_buf
*/
struct
dccp_ackvec
{
u64
av_buf_ackno
;
struct
list_head
av_records
;
ktime_t
av_time
;
u8
av_buf
[
DCCPAV_MAX_ACKVEC_LEN
];
u16
av_buf_head
;
u16
av_buf_tail
;
u64
av_buf_ackno
:
48
;
u64
av_tail_ackno
:
48
;
bool
av_buf_nonce
[
DCCPAV_NUM_ACKVECS
];
u8
av_overflow
:
1
;
struct
list_head
av_records
;
u16
av_vec_len
;
u8
av_buf_nonce
;
u8
av_ack_nonce
;
u8
av_buf
[
DCCP_MAX_ACKVEC_LEN
];
};
/** struct dccp_ackvec_record -
ack vector record
/** struct dccp_ackvec_record -
Records information about sent Ack Vectors
*
* ACK vector record as defined in Appendix A of spec.
* These list entries define the additional information which the HC-Receiver
* keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A.
*
* The list is sorted by avr_ack_seqno
* @avr_node: the list node in @av_records
* @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on
* @avr_ack_ackno: the Ack number that this record/Ack Vector refers to
* @avr_ack_ptr: pointer into @av_buf where this record starts
* @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending
* @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent
*
* @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
* The list as a whole is sorted in descending order by @avr_ack_seqno.
*/
struct
dccp_ackvec_record
{
struct
list_head
avr_node
;
u64
avr_ack_seqno
;
u64
avr_ack_ackno
;
u64
avr_ack_seqno
:
48
;
u64
avr_ack_ackno
:
48
;
u16
avr_ack_ptr
;
u
16
avr_sent_
len
;
u8
avr_ack_nonce
;
u
8
avr_ack_run
len
;
u8
avr_ack_nonce
:
1
;
};
struct
sock
;
...
...
@@ -102,10 +116,11 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
u64
*
ackno
,
const
u8
opt
,
const
u8
*
value
,
const
u8
len
);
extern
int
dccp_insert_option_ackvec
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
extern
int
dccp_ackvec_update_records
(
struct
dccp_ackvec
*
av
,
u64
seq
,
u8
sum
);
extern
u16
dccp_ackvec_buflen
(
const
struct
dccp_ackvec
*
av
);
static
inline
int
dccp_ackvec_pending
(
const
struct
dccp_ackvec
*
av
)
static
inline
bool
dccp_ackvec_is_empty
(
const
struct
dccp_ackvec
*
av
)
{
return
av
->
av_
vec_len
;
return
av
->
av_
overflow
==
0
&&
av
->
av_buf_head
==
av
->
av_buf_tail
;
}
#endif
/* _ACKVEC_H */
net/dccp/ccids/ccid2.c
View file @
ed1deb70
...
...
@@ -513,8 +513,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
&
vector
,
&
veclen
))
!=
-
1
)
{
/* go through this ack vector */
while
(
veclen
--
)
{
const
u8
rl
=
*
vector
&
DCCP_ACKVEC_LEN_MASK
;
u64
ackno_end_rl
=
SUB48
(
ackno
,
rl
);
u64
ackno_end_rl
=
SUB48
(
ackno
,
dccp_ackvec_runlen
(
vector
));
ccid2_pr_debug
(
"ackvec start:%llu end:%llu
\n
"
,
(
unsigned
long
long
)
ackno
,
...
...
@@ -537,17 +536,15 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
* run length
*/
while
(
between48
(
seqp
->
ccid2s_seq
,
ackno_end_rl
,
ackno
))
{
const
u8
state
=
*
vector
&
DCCP_ACKVEC_STATE_MASK
;
const
u8
state
=
dccp_ackvec_state
(
vector
);
/* new packet received or marked */
if
(
state
!=
DCCP
_ACKVEC_STATE
_NOT_RECEIVED
&&
if
(
state
!=
DCCP
AV
_NOT_RECEIVED
&&
!
seqp
->
ccid2s_acked
)
{
if
(
state
==
DCCP_ACKVEC_STATE_ECN_MARKED
)
{
if
(
state
==
DCCPAV_ECN_MARKED
)
ccid2_congestion_event
(
sk
,
seqp
);
}
else
else
ccid2_new_ack
(
sk
,
seqp
,
&
maxincr
);
...
...
net/dccp/dccp.h
View file @
ed1deb70
...
...
@@ -457,12 +457,15 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
dp
->
dccps_awh
=
dp
->
dccps_gss
;
}
static
inline
int
dccp_ackvec_pending
(
const
struct
sock
*
sk
)
{
return
dccp_sk
(
sk
)
->
dccps_hc_rx_ackvec
!=
NULL
&&
!
dccp_ackvec_is_empty
(
dccp_sk
(
sk
)
->
dccps_hc_rx_ackvec
);
}
static
inline
int
dccp_ack_pending
(
const
struct
sock
*
sk
)
{
const
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
return
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_pending
(
dp
->
dccps_hc_rx_ackvec
))
||
inet_csk_ack_scheduled
(
sk
);
return
dccp_ackvec_pending
(
sk
)
||
inet_csk_ack_scheduled
(
sk
);
}
extern
int
dccp_feat_finalise_settings
(
struct
dccp_sock
*
dp
);
...
...
net/dccp/input.c
View file @
ed1deb70
...
...
@@ -378,8 +378,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_add
(
dp
->
dccps_hc_rx_ackvec
,
sk
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCP_ACKVEC_STATE_RECEIVED
))
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCPAV_RECEIVED
))
goto
discard
;
dccp_deliver_input_to_ccids
(
sk
,
skb
);
...
...
@@ -637,8 +636,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_add
(
dp
->
dccps_hc_rx_ackvec
,
sk
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCP_ACKVEC_STATE_RECEIVED
))
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCPAV_RECEIVED
))
goto
discard
;
dccp_deliver_input_to_ccids
(
sk
,
skb
);
...
...
net/dccp/options.c
View file @
ed1deb70
...
...
@@ -340,6 +340,7 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time)
return
elapsed_time
==
0
?
0
:
elapsed_time
<=
0xFFFF
?
2
:
4
;
}
/* FIXME: This function is currently not used anywhere */
int
dccp_insert_option_elapsed_time
(
struct
sk_buff
*
skb
,
u32
elapsed_time
)
{
const
int
elapsed_time_len
=
dccp_elapsed_time_len
(
elapsed_time
);
...
...
@@ -424,6 +425,67 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
return
0
;
}
static
int
dccp_insert_option_ackvec
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
struct
dccp_ackvec
*
av
=
dp
->
dccps_hc_rx_ackvec
;
const
u16
buflen
=
dccp_ackvec_buflen
(
av
);
/* Figure out how many options do we need to represent the ackvec */
const
u8
nr_opts
=
DIV_ROUND_UP
(
buflen
,
DCCP_SINGLE_OPT_MAXLEN
);
u16
len
=
buflen
+
2
*
nr_opts
;
u8
i
,
nonce
=
0
;
const
unsigned
char
*
tail
,
*
from
;
unsigned
char
*
to
;
if
(
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+
len
>
DCCP_MAX_OPT_LEN
)
return
-
1
;
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+=
len
;
to
=
skb_push
(
skb
,
len
);
len
=
buflen
;
from
=
av
->
av_buf
+
av
->
av_buf_head
;
tail
=
av
->
av_buf
+
DCCPAV_MAX_ACKVEC_LEN
;
for
(
i
=
0
;
i
<
nr_opts
;
++
i
)
{
int
copylen
=
len
;
if
(
len
>
DCCP_SINGLE_OPT_MAXLEN
)
copylen
=
DCCP_SINGLE_OPT_MAXLEN
;
/*
* RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via
* its type; ack_nonce is the sum of all individual buf_nonce's.
*/
nonce
^=
av
->
av_buf_nonce
[
i
];
*
to
++
=
DCCPO_ACK_VECTOR_0
+
av
->
av_buf_nonce
[
i
];
*
to
++
=
copylen
+
2
;
/* Check if buf_head wraps */
if
(
from
+
copylen
>
tail
)
{
const
u16
tailsize
=
tail
-
from
;
memcpy
(
to
,
from
,
tailsize
);
to
+=
tailsize
;
len
-=
tailsize
;
copylen
-=
tailsize
;
from
=
av
->
av_buf
;
}
memcpy
(
to
,
from
,
copylen
);
from
+=
copylen
;
to
+=
copylen
;
len
-=
copylen
;
}
/*
* Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340.
*/
if
(
dccp_ackvec_update_records
(
av
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
nonce
))
return
-
ENOBUFS
;
return
0
;
}
/**
* dccp_insert_option_mandatory - Mandatory option (5.8.2)
* Note that since we are using skb_push, this function needs to be called
...
...
@@ -519,8 +581,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
if
(
dccp_insert_option_timestamp
(
skb
))
return
-
1
;
}
else
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_pending
(
dp
->
dccps_hc_rx_ackvec
)
&&
}
else
if
(
dccp_ackvec_pending
(
sk
)
&&
dccp_insert_option_ackvec
(
sk
,
skb
))
{
return
-
1
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment