aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/feat.h14
-rw-r--r--net/dccp/options.c21
2 files changed, 28 insertions, 7 deletions
diff --git a/net/dccp/feat.h b/net/dccp/feat.h
index 093af1610d11..a8ab9e1e8b17 100644
--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -125,4 +125,18 @@ extern int dccp_feat_clone(struct sock *oldsk, struct sock *newsk);
125extern int dccp_feat_clone_list(struct list_head const *, struct list_head *); 125extern int dccp_feat_clone_list(struct list_head const *, struct list_head *);
126extern int dccp_feat_init(struct sock *sk); 126extern int dccp_feat_init(struct sock *sk);
127 127
128/*
129 * Encoding variable-length options and their maximum length.
130 *
131 * This affects NN options (SP options are all u8) and other variable-length
132 * options (see table 3 in RFC 4340). The limit is currently given the Sequence
133 * Window NN value (sec. 7.5.2) and the NDP count (sec. 7.7) option, all other
134 * options consume less than 6 bytes (timestamps are 4 bytes).
135 * When updating this constant (e.g. due to new internet drafts / RFCs), make
136 * sure that you also update all code which refers to it.
137 */
138#define DCCP_OPTVAL_MAXLEN 6
139
140extern void dccp_encode_value_var(const u64 value, u8 *to, const u8 len);
141extern u64 dccp_decode_value_var(const u8 *bf, const u8 len);
128#endif /* _DCCP_FEAT_H */ 142#endif /* _DCCP_FEAT_H */
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 515ad45013ad..9cb0ff894052 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -29,16 +29,20 @@ int sysctl_dccp_feat_tx_ccid = DCCPF_INITIAL_CCID;
29int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR; 29int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
30int sysctl_dccp_feat_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT; 30int sysctl_dccp_feat_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT;
31 31
32static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) 32u64 dccp_decode_value_var(const u8 *bf, const u8 len)
33{ 33{
34 u32 value = 0; 34 u64 value = 0;
35 35
36 if (len >= DCCP_OPTVAL_MAXLEN)
37 value += ((u64)*bf++) << 40;
38 if (len > 4)
39 value += ((u64)*bf++) << 32;
36 if (len > 3) 40 if (len > 3)
37 value += *bf++ << 24; 41 value += ((u64)*bf++) << 24;
38 if (len > 2) 42 if (len > 2)
39 value += *bf++ << 16; 43 value += ((u64)*bf++) << 16;
40 if (len > 1) 44 if (len > 1)
41 value += *bf++ << 8; 45 value += ((u64)*bf++) << 8;
42 if (len > 0) 46 if (len > 0)
43 value += *bf; 47 value += *bf;
44 48
@@ -298,9 +302,12 @@ out_invalid_option:
298 302
299EXPORT_SYMBOL_GPL(dccp_parse_options); 303EXPORT_SYMBOL_GPL(dccp_parse_options);
300 304
301static void dccp_encode_value_var(const u32 value, unsigned char *to, 305void dccp_encode_value_var(const u64 value, u8 *to, const u8 len)
302 const unsigned int len)
303{ 306{
307 if (len >= DCCP_OPTVAL_MAXLEN)
308 *to++ = (value & 0xFF0000000000ull) >> 40;
309 if (len > 4)
310 *to++ = (value & 0xFF00000000ull) >> 32;
304 if (len > 3) 311 if (len > 3)
305 *to++ = (value & 0xFF000000) >> 24; 312 *to++ = (value & 0xFF000000) >> 24;
306 if (len > 2) 313 if (len > 2)