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
98e684bd
Commit
98e684bd
authored
Sep 21, 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
e254c274
536bb20b
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
73 additions
and
106 deletions
+73
-106
include/linux/dccp.h
include/linux/dccp.h
+4
-2
net/dccp/ccid.h
net/dccp/ccid.h
+23
-23
net/dccp/ccids/ccid3.c
net/dccp/ccids/ccid3.c
+26
-52
net/dccp/ccids/ccid3.h
net/dccp/ccids/ccid3.h
+0
-9
net/dccp/ccids/lib/tfrc.h
net/dccp/ccids/lib/tfrc.h
+1
-0
net/dccp/ccids/lib/tfrc_equation.c
net/dccp/ccids/lib/tfrc_equation.c
+14
-0
net/dccp/options.c
net/dccp/options.c
+5
-20
No files found.
include/linux/dccp.h
View file @
98e684bd
...
...
@@ -165,8 +165,10 @@ enum {
DCCPO_TIMESTAMP_ECHO
=
42
,
DCCPO_ELAPSED_TIME
=
43
,
DCCPO_MAX
=
45
,
DCCPO_MIN_CCID_SPECIFIC
=
128
,
DCCPO_MAX_CCID_SPECIFIC
=
255
,
DCCPO_MIN_RX_CCID_SPECIFIC
=
128
,
/* from sender to receiver */
DCCPO_MAX_RX_CCID_SPECIFIC
=
191
,
DCCPO_MIN_TX_CCID_SPECIFIC
=
192
,
/* from receiver to sender */
DCCPO_MAX_TX_CCID_SPECIFIC
=
255
,
};
/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
#define DCCP_SINGLE_OPT_MAXLEN 253
...
...
net/dccp/ccid.h
View file @
98e684bd
...
...
@@ -62,18 +62,14 @@ struct ccid_operations {
void
(
*
ccid_hc_tx_exit
)(
struct
sock
*
sk
);
void
(
*
ccid_hc_rx_packet_recv
)(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
(
*
ccid_hc_rx_parse_options
)(
struct
sock
*
sk
,
unsigned
char
option
,
unsigned
char
len
,
u16
idx
,
unsigned
char
*
value
);
int
(
*
ccid_hc_rx_parse_options
)(
struct
sock
*
sk
,
u8
pkt
,
u8
opt
,
u8
*
val
,
u8
len
);
int
(
*
ccid_hc_rx_insert_options
)(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
void
(
*
ccid_hc_tx_packet_recv
)(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
int
(
*
ccid_hc_tx_parse_options
)(
struct
sock
*
sk
,
unsigned
char
option
,
unsigned
char
len
,
u16
idx
,
unsigned
char
*
value
);
int
(
*
ccid_hc_tx_parse_options
)(
struct
sock
*
sk
,
u8
pkt
,
u8
opt
,
u8
*
val
,
u8
len
);
int
(
*
ccid_hc_tx_send_packet
)(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
void
(
*
ccid_hc_tx_packet_sent
)(
struct
sock
*
sk
,
...
...
@@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
ccid
->
ccid_ops
->
ccid_hc_tx_packet_recv
(
sk
,
skb
);
}
/**
* ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver
* @pkt: type of packet that @opt appears on (RFC 4340, 5.1)
* @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3)
* @val: value of @opt
* @len: length of @val in bytes
*/
static
inline
int
ccid_hc_tx_parse_options
(
struct
ccid
*
ccid
,
struct
sock
*
sk
,
unsigned
char
option
,
unsigned
char
len
,
u16
idx
,
unsigned
char
*
value
)
u8
pkt
,
u8
opt
,
u8
*
val
,
u8
len
)
{
int
rc
=
0
;
if
(
ccid
->
ccid_ops
->
ccid_hc_tx_parse_options
!=
NULL
)
rc
=
ccid
->
ccid_ops
->
ccid_hc_tx_parse_options
(
sk
,
option
,
len
,
idx
,
value
);
return
rc
;
if
(
ccid
->
ccid_ops
->
ccid_hc_tx_parse_options
==
NULL
)
return
0
;
return
ccid
->
ccid_ops
->
ccid_hc_tx_parse_options
(
sk
,
pkt
,
opt
,
val
,
len
);
}
/**
* ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender
* Arguments are analogous to ccid_hc_tx_parse_options()
*/
static
inline
int
ccid_hc_rx_parse_options
(
struct
ccid
*
ccid
,
struct
sock
*
sk
,
unsigned
char
option
,
unsigned
char
len
,
u16
idx
,
unsigned
char
*
value
)
u8
pkt
,
u8
opt
,
u8
*
val
,
u8
len
)
{
int
rc
=
0
;
if
(
ccid
->
ccid_ops
->
ccid_hc_rx_parse_options
!=
NULL
)
rc
=
ccid
->
ccid_ops
->
ccid_hc_rx_parse_options
(
sk
,
option
,
len
,
idx
,
value
);
return
rc
;
if
(
ccid
->
ccid_ops
->
ccid_hc_rx_parse_options
==
NULL
)
return
0
;
return
ccid
->
ccid_ops
->
ccid_hc_rx_parse_options
(
sk
,
pkt
,
opt
,
val
,
len
);
}
static
inline
int
ccid_hc_rx_insert_options
(
struct
ccid
*
ccid
,
struct
sock
*
sk
,
...
...
net/dccp/ccids/ccid3.c
View file @
98e684bd
...
...
@@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
[
TFRC_SSTATE_NO_SENT
]
=
"NO_SENT"
,
[
TFRC_SSTATE_NO_FBACK
]
=
"NO_FBACK"
,
[
TFRC_SSTATE_FBACK
]
=
"FBACK"
,
[
TFRC_SSTATE_TERM
]
=
"TERM"
,
};
return
ccid3_state_names
[
state
];
...
...
@@ -208,10 +207,13 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
ccid3_pr_debug
(
"%s(%p, state=%s) - entry
\n
"
,
dccp_role
(
sk
),
sk
,
ccid3_tx_state_name
(
hc
->
tx_state
));
/* Ignore and do not restart after leaving the established state */
if
((
1
<<
sk
->
sk_state
)
&
~
(
DCCPF_OPEN
|
DCCPF_PARTOPEN
))
goto
out
;
/* Reset feedback state to "no feedback received" */
if
(
hc
->
tx_state
==
TFRC_SSTATE_FBACK
)
ccid3_hc_tx_set_state
(
sk
,
TFRC_SSTATE_NO_FBACK
);
else
if
(
hc
->
tx_state
!=
TFRC_SSTATE_NO_FBACK
)
goto
out
;
/*
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
...
...
@@ -287,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
if
(
unlikely
(
skb
->
len
==
0
))
return
-
EBADMSG
;
switch
(
hc
->
tx_state
)
{
case
TFRC_SSTATE_NO_SENT
:
if
(
hc
->
tx_state
==
TFRC_SSTATE_NO_SENT
)
{
sk_reset_timer
(
sk
,
&
hc
->
tx_no_feedback_timer
,
(
jiffies
+
usecs_to_jiffies
(
TFRC_INITIAL_TIMEOUT
)));
hc
->
tx_last_win_count
=
0
;
...
...
@@ -323,9 +324,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
ccid3_update_send_interval
(
hc
);
ccid3_hc_tx_set_state
(
sk
,
TFRC_SSTATE_NO_FBACK
);
break
;
case
TFRC_SSTATE_NO_FBACK
:
case
TFRC_SSTATE_FBACK
:
}
else
{
delay
=
ktime_us_delta
(
hc
->
tx_t_nom
,
now
);
ccid3_pr_debug
(
"delay=%ld
\n
"
,
(
long
)
delay
);
/*
...
...
@@ -340,10 +340,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
return
(
u32
)
delay
/
USEC_PER_MSEC
;
ccid3_hc_tx_update_win_count
(
hc
,
now
);
break
;
case
TFRC_SSTATE_TERM
:
DCCP_BUG
(
"%s(%p) - Illegal state TERM"
,
dccp_role
(
sk
),
sk
);
return
-
EINVAL
;
}
/* prepare to send now (add options etc.) */
...
...
@@ -369,21 +365,15 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
static
void
ccid3_hc_tx_packet_recv
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
ccid3_hc_tx_sock
*
hc
=
ccid3_hc_tx_sk
(
sk
);
struct
ccid3_options_received
*
opt_recv
=
&
hc
->
tx_options_received
;
struct
tfrc_tx_hist_entry
*
acked
;
ktime_t
now
;
unsigned
long
t_nfb
;
u32
pinv
,
r_sample
;
u32
r_sample
;
/* we are only interested in ACKs */
if
(
!
(
DCCP_SKB_CB
(
skb
)
->
dccpd_type
==
DCCP_PKT_ACK
||
DCCP_SKB_CB
(
skb
)
->
dccpd_type
==
DCCP_PKT_DATAACK
))
return
;
/* ... and only in the established state */
if
(
hc
->
tx_state
!=
TFRC_SSTATE_FBACK
&&
hc
->
tx_state
!=
TFRC_SSTATE_NO_FBACK
)
return
;
/*
* Locate the acknowledged packet in the TX history.
*
...
...
@@ -403,17 +393,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
r_sample
=
dccp_sample_rtt
(
sk
,
ktime_us_delta
(
now
,
acked
->
stamp
));
hc
->
tx_rtt
=
tfrc_ewma
(
hc
->
tx_rtt
,
r_sample
,
9
);
/* Update receive rate in units of 64 * bytes/second */
hc
->
tx_x_recv
=
opt_recv
->
ccid3or_receive_rate
;
hc
->
tx_x_recv
<<=
6
;
/* Update loss event rate (which is scaled by 1e6) */
pinv
=
opt_recv
->
ccid3or_loss_event_rate
;
if
(
pinv
==
~
0U
||
pinv
==
0
)
/* see RFC 4342, 8.5 */
hc
->
tx_p
=
0
;
else
/* can not exceed 100% */
hc
->
tx_p
=
scaled_div
(
1
,
pinv
);
/*
* Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
*/
...
...
@@ -481,30 +460,36 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
jiffies
+
usecs_to_jiffies
(
t_nfb
));
}
static
int
ccid3_hc_tx_parse_options
(
struct
sock
*
sk
,
unsigned
char
option
,
unsigned
char
len
,
u16
idx
,
unsigned
char
*
value
)
static
int
ccid3_hc_tx_parse_options
(
struct
sock
*
sk
,
u8
packet_type
,
u8
option
,
u8
*
optval
,
u8
optlen
)
{
struct
ccid3_hc_tx_sock
*
hc
=
ccid3_hc_tx_sk
(
sk
);
struct
ccid3_options_received
*
opt_recv
=
&
hc
->
tx_options_received
;
__be32
opt_val
;
switch
(
option
)
{
case
TFRC_OPT_RECEIVE_RATE
:
case
TFRC_OPT_LOSS_EVENT_RATE
:
if
(
unlikely
(
len
!=
4
))
{
/* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */
if
(
packet_type
==
DCCP_PKT_DATA
)
break
;
if
(
unlikely
(
optlen
!=
4
))
{
DCCP_WARN
(
"%s(%p), invalid len %d for %u
\n
"
,
dccp_role
(
sk
),
sk
,
len
,
option
);
dccp_role
(
sk
),
sk
,
opt
len
,
option
);
return
-
EINVAL
;
}
opt_val
=
ntohl
(
get_unaligned
((
__be32
*
)
value
));
opt_val
=
ntohl
(
get_unaligned
((
__be32
*
)
optval
));
if
(
option
==
TFRC_OPT_RECEIVE_RATE
)
{
opt_recv
->
ccid3or_receive_rate
=
opt_val
;
/* Receive Rate is kept in units of 64 bytes/second */
hc
->
tx_x_recv
=
opt_val
;
hc
->
tx_x_recv
<<=
6
;
ccid3_pr_debug
(
"%s(%p), RECEIVE_RATE=%u
\n
"
,
dccp_role
(
sk
),
sk
,
opt_val
);
}
else
{
opt_recv
->
ccid3or_loss_event_rate
=
opt_val
;
/* Update the fixpoint Loss Event Rate fraction */
hc
->
tx_p
=
tfrc_invert_loss_event_rate
(
opt_val
);
ccid3_pr_debug
(
"%s(%p), LOSS_EVENT_RATE=%u
\n
"
,
dccp_role
(
sk
),
sk
,
opt_val
);
}
...
...
@@ -527,9 +512,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
{
struct
ccid3_hc_tx_sock
*
hc
=
ccid3_hc_tx_sk
(
sk
);
ccid3_hc_tx_set_state
(
sk
,
TFRC_SSTATE_TERM
);
sk_stop_timer
(
sk
,
&
hc
->
tx_no_feedback_timer
);
tfrc_tx_hist_purge
(
&
hc
->
tx_hist
);
}
...
...
@@ -588,7 +571,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
static
const
char
*
const
ccid3_rx_state_names
[]
=
{
[
TFRC_RSTATE_NO_DATA
]
=
"NO_DATA"
,
[
TFRC_RSTATE_DATA
]
=
"DATA"
,
[
TFRC_RSTATE_TERM
]
=
"TERM"
,
};
return
ccid3_rx_state_names
[
state
];
...
...
@@ -614,14 +596,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
{
struct
ccid3_hc_rx_sock
*
hc
=
ccid3_hc_rx_sk
(
sk
);
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
ktime_t
now
;
ktime_t
now
=
ktime_get_real
()
;
s64
delta
=
0
;
if
(
unlikely
(
hc
->
rx_state
==
TFRC_RSTATE_TERM
))
return
;
now
=
ktime_get_real
();
switch
(
fbtype
)
{
case
CCID3_FBACK_INITIAL
:
hc
->
rx_x_recv
=
0
;
...
...
@@ -825,8 +802,6 @@ static void ccid3_hc_rx_exit(struct sock *sk)
{
struct
ccid3_hc_rx_sock
*
hc
=
ccid3_hc_rx_sk
(
sk
);
ccid3_hc_rx_set_state
(
sk
,
TFRC_RSTATE_TERM
);
tfrc_rx_hist_purge
(
&
hc
->
rx_hist
);
tfrc_lh_cleanup
(
&
hc
->
rx_li_hist
);
}
...
...
@@ -851,8 +826,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
return
-
EINVAL
;
rx_info
.
tfrcrx_x_recv
=
hc
->
rx_x_recv
;
rx_info
.
tfrcrx_rtt
=
hc
->
rx_rtt
;
rx_info
.
tfrcrx_p
=
hc
->
rx_pinv
==
0
?
~
0U
:
scaled_div
(
1
,
hc
->
rx_pinv
);
rx_info
.
tfrcrx_p
=
tfrc_invert_loss_event_rate
(
hc
->
rx_pinv
);
len
=
sizeof
(
rx_info
);
val
=
&
rx_info
;
break
;
...
...
net/dccp/ccids/ccid3.h
View file @
98e684bd
...
...
@@ -67,17 +67,11 @@ enum ccid3_options {
TFRC_OPT_RECEIVE_RATE
=
194
,
};
struct
ccid3_options_received
{
u32
ccid3or_loss_event_rate
;
u32
ccid3or_receive_rate
;
};
/* TFRC sender states */
enum
ccid3_hc_tx_states
{
TFRC_SSTATE_NO_SENT
=
1
,
TFRC_SSTATE_NO_FBACK
,
TFRC_SSTATE_FBACK
,
TFRC_SSTATE_TERM
,
};
/**
...
...
@@ -98,7 +92,6 @@ enum ccid3_hc_tx_states {
* @tx_t_ld: Time last doubled during slow start
* @tx_t_nom: Nominal send time of next packet
* @tx_hist: Packet history
* @tx_options_received: Parsed set of retrieved options
*/
struct
ccid3_hc_tx_sock
{
u64
tx_x
;
...
...
@@ -116,7 +109,6 @@ struct ccid3_hc_tx_sock {
ktime_t
tx_t_ld
;
ktime_t
tx_t_nom
;
struct
tfrc_tx_hist_entry
*
tx_hist
;
struct
ccid3_options_received
tx_options_received
;
};
static
inline
struct
ccid3_hc_tx_sock
*
ccid3_hc_tx_sk
(
const
struct
sock
*
sk
)
...
...
@@ -130,7 +122,6 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
enum
ccid3_hc_rx_states
{
TFRC_RSTATE_NO_DATA
=
1
,
TFRC_RSTATE_DATA
,
TFRC_RSTATE_TERM
=
127
,
};
/**
...
...
net/dccp/ccids/lib/tfrc.h
View file @
98e684bd
...
...
@@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
extern
u32
tfrc_calc_x
(
u16
s
,
u32
R
,
u32
p
);
extern
u32
tfrc_calc_x_reverse_lookup
(
u32
fvalue
);
extern
u32
tfrc_invert_loss_event_rate
(
u32
loss_event_rate
);
extern
int
tfrc_tx_packet_history_init
(
void
);
extern
void
tfrc_tx_packet_history_exit
(
void
);
...
...
net/dccp/ccids/lib/tfrc_equation.c
View file @
98e684bd
...
...
@@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
index
=
tfrc_binsearch
(
fvalue
,
0
);
return
(
index
+
1
)
*
1000000
/
TFRC_CALC_X_ARRSIZE
;
}
/**
* tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100%
* When @loss_event_rate is large, there is a chance that p is truncated to 0.
* To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0.
*/
u32
tfrc_invert_loss_event_rate
(
u32
loss_event_rate
)
{
if
(
loss_event_rate
==
UINT_MAX
)
/* see RFC 4342, 8.5 */
return
0
;
if
(
unlikely
(
loss_event_rate
==
0
))
/* map 1/0 into 100% */
return
1000000
;
return
max_t
(
u32
,
scaled_div
(
1
,
loss_event_rate
),
TFRC_SMALLEST_P
);
}
net/dccp/options.c
View file @
98e684bd
...
...
@@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
}
/*
* CCID-Specific Options (from RFC 4340, sec. 10.3):
*
* Option numbers 128 through 191 are for options sent from the
* HC-Sender to the HC-Receiver; option numbers 192 through 255
* are for options sent from the HC-Receiver to the HC-Sender.
*
* CCID-specific options are ignored during connection setup, as
* negotiation may still be in progress (see RFC 4340, 10.3).
* The same applies to Ack Vectors, as these depend on the CCID.
*
*/
if
(
dreq
!=
NULL
&&
(
opt
>=
128
||
if
(
dreq
!=
NULL
&&
(
opt
>=
DCCPO_MIN_RX_CCID_SPECIFIC
||
opt
==
DCCPO_ACK_VECTOR_0
||
opt
==
DCCPO_ACK_VECTOR_1
))
goto
ignore_option
;
...
...
@@ -226,23 +219,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
dccp_pr_debug
(
"%s rx opt: ELAPSED_TIME=%d
\n
"
,
dccp_role
(
sk
),
elapsed_time
);
break
;
case
128
...
191
:
{
const
u16
idx
=
value
-
options
;
case
DCCPO_MIN_RX_CCID_SPECIFIC
...
DCCPO_MAX_RX_CCID_SPECIFIC
:
if
(
ccid_hc_rx_parse_options
(
dp
->
dccps_hc_rx_ccid
,
sk
,
opt
,
len
,
idx
,
value
)
!=
0
)
pkt_type
,
opt
,
value
,
len
))
goto
out_invalid_option
;
}
break
;
case
192
...
255
:
{
const
u16
idx
=
value
-
options
;
case
DCCPO_MIN_TX_CCID_SPECIFIC
...
DCCPO_MAX_TX_CCID_SPECIFIC
:
if
(
ccid_hc_tx_parse_options
(
dp
->
dccps_hc_tx_ccid
,
sk
,
opt
,
len
,
idx
,
value
)
!=
0
)
pkt_type
,
opt
,
value
,
len
))
goto
out_invalid_option
;
}
break
;
default:
DCCP_CRIT
(
"DCCP(%p): option %d(len=%d) not "
...
...
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