Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
0c4c8cae
Commit
0c4c8cae
authored
Jul 14, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://eden-feed.erg.abdn.ac.uk/net-next-2.6
parents
2aec609f
2eeea7ba
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
92 additions
and
100 deletions
+92
-100
include/linux/dccp.h
include/linux/dccp.h
+2
-4
net/dccp/ccids/ccid3.c
net/dccp/ccids/ccid3.c
+6
-8
net/dccp/ccids/lib/loss_interval.c
net/dccp/ccids/lib/loss_interval.c
+5
-5
net/dccp/ccids/lib/packet_history.c
net/dccp/ccids/lib/packet_history.c
+51
-52
net/dccp/ccids/lib/packet_history.h
net/dccp/ccids/lib/packet_history.h
+5
-25
net/dccp/dccp.h
net/dccp/dccp.h
+15
-0
net/dccp/options.c
net/dccp/options.c
+8
-6
No files found.
include/linux/dccp.h
View file @
0c4c8cae
...
...
@@ -364,8 +364,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
/* FIXME: for now we're default to 1 but it should really be 0 */
#define DCCPF_INITIAL_SEND_NDP_COUNT 1
#define DCCP_NDP_LIMIT 0xFFFFFF
/**
* struct dccp_minisock - Minimal DCCP connection representation
*
...
...
@@ -437,7 +435,7 @@ extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
struct
sk_buff
*
skb
);
struct
dccp_options_received
{
u
32
dccpor_ndp
;
/* only 24 bits */
u
64
dccpor_ndp
:
48
;
u32
dccpor_timestamp
;
u32
dccpor_timestamp_echo
;
u32
dccpor_elapsed_time
;
...
...
@@ -533,7 +531,7 @@ struct dccp_sock {
__u16
dccps_r_ack_ratio
;
__u16
dccps_pcslen
;
__u16
dccps_pcrlen
;
unsigned
long
dccps_ndp_count
;
__u64
dccps_ndp_count
:
48
;
unsigned
long
dccps_rate_last
;
struct
dccp_minisock
dccps_minisock
;
struct
dccp_ackvec
*
dccps_hc_rx_ackvec
;
...
...
net/dccp/ccids/ccid3.c
View file @
0c4c8cae
...
...
@@ -794,7 +794,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
struct
ccid3_hc_rx_sock
*
hcrx
=
ccid3_hc_rx_sk
(
sk
);
enum
ccid3_fback_type
do_feedback
=
CCID3_FBACK_NONE
;
const
u
32
ndp
=
dccp_sk
(
sk
)
->
dccps_options_received
.
dccpor_ndp
;
const
u
64
ndp
=
dccp_sk
(
sk
)
->
dccps_options_received
.
dccpor_ndp
;
const
bool
is_data_packet
=
dccp_data_packet
(
skb
);
if
(
unlikely
(
hcrx
->
ccid3hcrx_state
==
TFRC_RSTATE_NO_DATA
))
{
...
...
@@ -825,18 +825,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
}
/*
*
Handle pending losses and otherwise check for new los
s
*
Perform loss detection and handle pending losse
s
*/
if
(
tfrc_rx_hist_loss_pending
(
&
hcrx
->
ccid3hcrx_hist
)
&&
tfrc_rx_handle_loss
(
&
hcrx
->
ccid3hcrx_hist
,
&
hcrx
->
ccid3hcrx_li_hist
,
skb
,
ndp
,
ccid3_first_li
,
sk
)
)
{
if
(
tfrc_rx_handle_loss
(
&
hcrx
->
ccid3hcrx_hist
,
&
hcrx
->
ccid3hcrx_li_hist
,
skb
,
ndp
,
ccid3_first_li
,
sk
))
{
do_feedback
=
CCID3_FBACK_PARAM_CHANGE
;
goto
done_receiving
;
}
if
(
tfrc_rx_hist_
new_loss_indicated
(
&
hcrx
->
ccid3hcrx_hist
,
skb
,
ndp
))
goto
update_records
;
if
(
tfrc_rx_hist_
loss_pending
(
&
hcrx
->
ccid3hcrx_hist
))
return
;
/* done receiving */
/*
* Handle data packets: RTT sampling and monitoring p
...
...
net/dccp/ccids/lib/loss_interval.c
View file @
0c4c8cae
...
...
@@ -90,14 +90,14 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
{
struct
tfrc_loss_interval
*
cur
=
tfrc_lh_peek
(
lh
);
u32
old_i_mean
=
lh
->
i_mean
;
s64
len
gth
;
s64
len
;
if
(
cur
==
NULL
)
/* not initialised */
return
0
;
len
gth
=
dccp_delta_seqno
(
cur
->
li_seqno
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
)
;
len
=
dccp_delta_seqno
(
cur
->
li_seqno
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
)
+
1
;
if
(
len
gth
-
cur
->
li_length
<=
0
)
/* duplicate or reordered */
if
(
len
-
(
s64
)
cur
->
li_length
<=
0
)
/* duplicate or reordered */
return
0
;
if
(
SUB16
(
dccp_hdr
(
skb
)
->
dccph_ccval
,
cur
->
li_ccval
)
>
4
)
...
...
@@ -114,7 +114,7 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
if
(
tfrc_lh_length
(
lh
)
==
1
)
/* due to RFC 3448, 6.3.1 */
return
0
;
cur
->
li_length
=
len
gth
;
cur
->
li_length
=
len
;
tfrc_lh_calc_i_mean
(
lh
);
return
(
lh
->
i_mean
<
old_i_mean
);
...
...
@@ -159,7 +159,7 @@ int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
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
);
tfrc_rx_hist_last_rcv
(
rh
)
->
tfrchrx_seqno
)
+
1
;
if
(
lh
->
counter
>
(
2
*
LIH_SIZE
))
lh
->
counter
-=
LIH_SIZE
;
...
...
net/dccp/ccids/lib/packet_history.c
View file @
0c4c8cae
...
...
@@ -153,7 +153,7 @@ void tfrc_rx_packet_history_exit(void)
static
inline
void
tfrc_rx_hist_entry_from_skb
(
struct
tfrc_rx_hist_entry
*
entry
,
const
struct
sk_buff
*
skb
,
const
u
32
ndp
)
const
u
64
ndp
)
{
const
struct
dccp_hdr
*
dh
=
dccp_hdr
(
skb
);
...
...
@@ -166,7 +166,7 @@ static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *entry,
void
tfrc_rx_hist_add_packet
(
struct
tfrc_rx_hist
*
h
,
const
struct
sk_buff
*
skb
,
const
u
32
ndp
)
const
u
64
ndp
)
{
struct
tfrc_rx_hist_entry
*
entry
=
tfrc_rx_hist_last_rcv
(
h
);
...
...
@@ -206,31 +206,39 @@ static void tfrc_rx_hist_swap(struct tfrc_rx_hist *h, const u8 a, const u8 b)
*
* In the descriptions, `Si' refers to the sequence number of entry number i,
* whose NDP count is `Ni' (lower case is used for variables).
* Note: All __
after_loss functions expect that a test against duplicates has
*
been performed already: the seqno of the skb must not be less than the
*
seqno of loss_prev; and it must not equal that of any valid hist_
entry.
* Note: All __
xxx_loss functions expect that a test against duplicates has been
*
performed already: the seqno of the skb must not be less than the seqno
*
of loss_prev; and it must not equal that of any valid history
entry.
*/
static
void
__do_track_loss
(
struct
tfrc_rx_hist
*
h
,
struct
sk_buff
*
skb
,
u64
n1
)
{
u64
s0
=
tfrc_rx_hist_loss_prev
(
h
)
->
tfrchrx_seqno
,
s1
=
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
;
if
(
!
dccp_loss_free
(
s0
,
s1
,
n1
))
{
/* gap between S0 and S1 */
h
->
loss_count
=
1
;
tfrc_rx_hist_entry_from_skb
(
tfrc_rx_hist_entry
(
h
,
1
),
skb
,
n1
);
}
}
static
void
__one_after_loss
(
struct
tfrc_rx_hist
*
h
,
struct
sk_buff
*
skb
,
u32
n2
)
{
u64
s0
=
tfrc_rx_hist_loss_prev
(
h
)
->
tfrchrx_seqno
,
s1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_seqno
,
s2
=
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
;
int
n1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_ndp
,
d12
=
dccp_delta_seqno
(
s1
,
s2
),
d2
;
if
(
d12
>
0
)
{
/* S1 < S2 */
if
(
likely
(
dccp_delta_seqno
(
s1
,
s2
)
>
0
))
{
/* S1 < S2 */
h
->
loss_count
=
2
;
tfrc_rx_hist_entry_from_skb
(
tfrc_rx_hist_entry
(
h
,
2
),
skb
,
n2
);
return
;
}
/* S0 < S2 < S1 */
d2
=
dccp_delta_seqno
(
s0
,
s2
);
if
(
d
2
==
1
||
n2
>=
d2
)
{
/* S2 is direct successor of S0 */
int
d21
=
-
d12
;
if
(
d
ccp_loss_free
(
s0
,
s2
,
n2
))
{
u64
n1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_ndp
;
if
(
d
21
==
1
||
n1
>=
d21
)
{
if
(
d
ccp_loss_free
(
s2
,
s1
,
n1
)
)
{
/* hole is filled: S0, S2, and S1 are consecutive */
h
->
loss_count
=
0
;
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
1
);
...
...
@@ -238,9 +246,9 @@ static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2
/* gap between S2 and S1: just update loss_prev */
tfrc_rx_hist_entry_from_skb
(
tfrc_rx_hist_loss_prev
(
h
),
skb
,
n2
);
}
else
{
/* hole
between S0 and S2 */
}
else
{
/* gap
between S0 and S2 */
/*
* Reorder history to insert S2 between S0 and
s
1
* Reorder history to insert S2 between S0 and
S
1
*/
tfrc_rx_hist_swap
(
h
,
0
,
3
);
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
3
);
...
...
@@ -256,22 +264,18 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
s1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_seqno
,
s2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_seqno
,
s3
=
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
;
int
n1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_ndp
,
d23
=
dccp_delta_seqno
(
s2
,
s3
),
d13
,
d3
,
d31
;
if
(
d23
>
0
)
{
/* S2 < S3 */
if
(
likely
(
dccp_delta_seqno
(
s2
,
s3
)
>
0
))
{
/* S2 < S3 */
h
->
loss_count
=
3
;
tfrc_rx_hist_entry_from_skb
(
tfrc_rx_hist_entry
(
h
,
3
),
skb
,
n3
);
return
1
;
}
/* S3 < S2 */
d13
=
dccp_delta_seqno
(
s1
,
s3
);
if
(
d
13
>
0
)
{
if
(
d
ccp_delta_seqno
(
s1
,
s3
)
>
0
)
{
/* S1 < S3 < S2 */
/*
* The sequence number order is S1, S3, S2
* Reorder history to insert entry between S1 and S2
* Reorder history to insert S3 between S1 and S2
*/
tfrc_rx_hist_swap
(
h
,
2
,
3
);
tfrc_rx_hist_entry_from_skb
(
tfrc_rx_hist_entry
(
h
,
2
),
skb
,
n3
);
...
...
@@ -280,17 +284,15 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
}
/* S0 < S3 < S1 */
d31
=
-
d13
;
d3
=
dccp_delta_seqno
(
s0
,
s3
);
if
(
d3
==
1
||
n3
>=
d3
)
{
/* S3 is a successor of S0 */
if
(
dccp_loss_free
(
s0
,
s3
,
n3
))
{
u64
n1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_ndp
;
if
(
d
31
==
1
||
n1
>=
d31
)
{
if
(
d
ccp_loss_free
(
s3
,
s1
,
n1
)
)
{
/* hole between S0 and S1 filled by S3 */
int
d2
=
dccp_delta_seqno
(
s1
,
s2
),
n2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_ndp
;
u64
n2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_ndp
;
if
(
d
2
==
1
||
n2
>=
d2
)
{
if
(
d
ccp_loss_free
(
s1
,
s2
,
n2
)
)
{
/* entire hole filled by S0, S3, S1, S2 */
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
2
);
h
->
loss_count
=
0
;
...
...
@@ -307,8 +309,8 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
}
/*
* The remaining case:
S3 is not a successor of S0.
*
Sequence order is S0, S3, S1, S2; reorder to insert between S0 and S1
* The remaining case:
S0 < S3 < S1 < S2; gap between S0 and S3
*
Reorder history to insert S3 between S0 and S1.
*/
tfrc_rx_hist_swap
(
h
,
0
,
3
);
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
3
);
...
...
@@ -318,33 +320,25 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
return
1
;
}
/* return the signed modulo-2^48 sequence number distance from entry e1 to e2 */
static
s64
tfrc_rx_hist_delta_seqno
(
struct
tfrc_rx_hist
*
h
,
u8
e1
,
u8
e2
)
{
DCCP_BUG_ON
(
e1
>
h
->
loss_count
||
e2
>
h
->
loss_count
);
return
dccp_delta_seqno
(
tfrc_rx_hist_entry
(
h
,
e1
)
->
tfrchrx_seqno
,
tfrc_rx_hist_entry
(
h
,
e2
)
->
tfrchrx_seqno
);
}
/* recycle RX history records to continue loss detection if necessary */
static
void
__three_after_loss
(
struct
tfrc_rx_hist
*
h
)
{
/*
*
The distance between S0 and S1 is always greater than 1 and the NDP
*
count of S1 is smaller than this distance. Otherwise there would
*
have been no loss. Hence it is only necessary to see whether there
*
are further missing data packets between S1/S2 and
S2/S3.
*
At this stage we know already that there is a gap between S0 and S1
*
(since S0 was the highest sequence number received before detecting
*
the loss). To recycle the loss record, it is thus only necessary to
*
check for other possible gaps between S1/S2 and between
S2/S3.
*/
int
d2
=
tfrc_rx_hist_delta_seqno
(
h
,
1
,
2
),
d3
=
tfrc_rx_hist_delta_seqno
(
h
,
2
,
3
),
n2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_ndp
,
u64
s1
=
tfrc_rx_hist_entry
(
h
,
1
)
->
tfrchrx_seqno
,
s2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_seqno
,
s3
=
tfrc_rx_hist_entry
(
h
,
3
)
->
tfrchrx_seqno
;
u64
n2
=
tfrc_rx_hist_entry
(
h
,
2
)
->
tfrchrx_ndp
,
n3
=
tfrc_rx_hist_entry
(
h
,
3
)
->
tfrchrx_ndp
;
if
(
d
2
==
1
||
n2
>=
d2
)
{
/* S2 is successor to S1 */
if
(
d
ccp_loss_free
(
s1
,
s2
,
n2
))
{
if
(
d
3
==
1
||
n3
>=
d3
)
{
/*
S3 is successor of S2
: entire hole is filled */
if
(
d
ccp_loss_free
(
s2
,
s3
,
n3
)
)
{
/*
no gap between S2 and S3
: entire hole is filled */
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
3
);
h
->
loss_count
=
0
;
}
else
{
...
...
@@ -353,7 +347,7 @@ static void __three_after_loss(struct tfrc_rx_hist *h)
h
->
loss_count
=
1
;
}
}
else
{
/* gap between S1 and S2 */
}
else
{
/* gap between S1 and S2 */
h
->
loss_start
=
tfrc_rx_hist_index
(
h
,
1
);
h
->
loss_count
=
2
;
}
...
...
@@ -370,15 +364,20 @@ static void __three_after_loss(struct tfrc_rx_hist *h)
* Chooses action according to pending loss, updates LI database when a new
* loss was detected, and does required post-processing. Returns 1 when caller
* should send feedback, 0 otherwise.
* Since it also takes care of reordering during loss detection and updates the
* records accordingly, the caller should not perform any more RX history
* operations when loss_count is greater than 0 after calling this function.
*/
int
tfrc_rx_handle_loss
(
struct
tfrc_rx_hist
*
h
,
struct
tfrc_loss_hist
*
lh
,
struct
sk_buff
*
skb
,
u32
ndp
,
struct
sk_buff
*
skb
,
const
u64
ndp
,
u32
(
*
calc_first_li
)(
struct
sock
*
),
struct
sock
*
sk
)
{
int
is_new_loss
=
0
;
if
(
h
->
loss_count
==
1
)
{
if
(
h
->
loss_count
==
0
)
{
__do_track_loss
(
h
,
skb
,
ndp
);
}
else
if
(
h
->
loss_count
==
1
)
{
__one_after_loss
(
h
,
skb
,
ndp
);
}
else
if
(
h
->
loss_count
!=
2
)
{
DCCP_BUG
(
"invalid loss_count %d"
,
h
->
loss_count
);
...
...
net/dccp/ccids/lib/packet_history.h
View file @
0c4c8cae
...
...
@@ -64,7 +64,7 @@ struct tfrc_rx_hist_entry {
u64
tfrchrx_seqno
:
48
,
tfrchrx_ccval:
4
,
tfrchrx_type:
4
;
u
32
tfrchrx_ndp
;
/* In fact it is from 8 to 24 bits */
u
64
tfrchrx_ndp
:
48
;
ktime_t
tfrchrx_tstamp
;
};
...
...
@@ -118,41 +118,21 @@ static inline struct tfrc_rx_hist_entry *
return
h
->
ring
[
h
->
loss_start
];
}
/* initialise loss detection and disable RTT sampling */
static
inline
void
tfrc_rx_hist_loss_indicated
(
struct
tfrc_rx_hist
*
h
)
{
h
->
loss_count
=
1
;
}
/* indicate whether previously a packet was detected missing */
static
inline
int
tfrc_rx_hist_loss_pending
(
const
struct
tfrc_rx_hist
*
h
)
{
return
h
->
loss_count
;
}
/* any data packets missing between last reception and skb ? */
static
inline
int
tfrc_rx_hist_new_loss_indicated
(
struct
tfrc_rx_hist
*
h
,
const
struct
sk_buff
*
skb
,
u32
ndp
)
static
inline
bool
tfrc_rx_hist_loss_pending
(
const
struct
tfrc_rx_hist
*
h
)
{
int
delta
=
dccp_delta_seqno
(
tfrc_rx_hist_last_rcv
(
h
)
->
tfrchrx_seqno
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
);
if
(
delta
>
1
&&
ndp
<
delta
)
tfrc_rx_hist_loss_indicated
(
h
);
return
tfrc_rx_hist_loss_pending
(
h
);
return
h
->
loss_count
>
0
;
}
extern
void
tfrc_rx_hist_add_packet
(
struct
tfrc_rx_hist
*
h
,
const
struct
sk_buff
*
skb
,
const
u
32
ndp
);
const
struct
sk_buff
*
skb
,
const
u
64
ndp
);
extern
int
tfrc_rx_hist_duplicate
(
struct
tfrc_rx_hist
*
h
,
struct
sk_buff
*
skb
);
struct
tfrc_loss_hist
;
extern
int
tfrc_rx_handle_loss
(
struct
tfrc_rx_hist
*
h
,
struct
tfrc_loss_hist
*
lh
,
struct
sk_buff
*
skb
,
u32
ndp
,
struct
sk_buff
*
skb
,
const
u64
ndp
,
u32
(
*
first_li
)(
struct
sock
*
sk
),
struct
sock
*
sk
);
extern
u32
tfrc_rx_hist_sample_rtt
(
struct
tfrc_rx_hist
*
h
,
...
...
net/dccp/dccp.h
View file @
0c4c8cae
...
...
@@ -153,6 +153,21 @@ static inline u64 max48(const u64 seq1, const u64 seq2)
return
after48
(
seq1
,
seq2
)
?
seq1
:
seq2
;
}
/**
* dccp_loss_free - Evaluates condition for data loss from RFC 4340, 7.7.1
* @s1: start sequence number
* @s2: end sequence number
* @ndp: NDP count on packet with sequence number @s2
* Returns true if the sequence range s1...s2 has no data loss.
*/
static
inline
bool
dccp_loss_free
(
const
u64
s1
,
const
u64
s2
,
const
u64
ndp
)
{
s64
delta
=
dccp_delta_seqno
(
s1
,
s2
);
BUG_TRAP
(
delta
>=
0
);
return
(
u64
)
delta
<=
ndp
+
1
;
}
enum
{
DCCP_MIB_NUM
=
0
,
DCCP_MIB_ACTIVEOPENS
,
/* ActiveOpens */
...
...
net/dccp/options.c
View file @
0c4c8cae
...
...
@@ -124,12 +124,12 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
mandatory
=
1
;
break
;
case
DCCPO_NDP_COUNT
:
if
(
len
>
3
)
if
(
len
>
6
)
goto
out_invalid_option
;
opt_recv
->
dccpor_ndp
=
dccp_decode_value_var
(
value
,
len
);
dccp_pr_debug
(
"%s
rx opt: NDP count=%d
\n
"
,
dccp_role
(
sk
),
opt_recv
->
dccpor_ndp
);
dccp_pr_debug
(
"%s
opt: NDP count=%llu
\n
"
,
dccp_role
(
sk
),
(
unsigned
long
long
)
opt_recv
->
dccpor_ndp
);
break
;
case
DCCPO_CHANGE_L
:
/* fall through */
...
...
@@ -307,9 +307,11 @@ static void dccp_encode_value_var(const u32 value, unsigned char *to,
*
to
++
=
(
value
&
0xFF
);
}
static
inline
int
dccp_ndp_len
(
const
int
ndp
)
static
inline
u8
dccp_ndp_len
(
const
u64
ndp
)
{
return
likely
(
ndp
<=
0xFF
)
?
1
:
ndp
<=
0xFFFF
?
2
:
3
;
if
(
likely
(
ndp
<=
0xFF
))
return
1
;
return
likely
(
ndp
<=
USHORT_MAX
)
?
2
:
(
ndp
<=
UINT_MAX
?
4
:
6
);
}
int
dccp_insert_option
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
...
...
@@ -336,7 +338,7 @@ EXPORT_SYMBOL_GPL(dccp_insert_option);
static
int
dccp_insert_option_ndp
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
int
ndp
=
dp
->
dccps_ndp_count
;
u64
ndp
=
dp
->
dccps_ndp_count
;
if
(
dccp_non_data_packet
(
skb
))
++
dp
->
dccps_ndp_count
;
...
...
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