diff options
author | Andrea Bittau <a.bittau@cs.ucl.ac.uk> | 2006-11-24 10:02:42 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:30:32 -0500 |
commit | bdf13d208dee4ada6d2b422536a12b45d5831aa3 (patch) | |
tree | ce8c076cce9f8c1bb70d5d6c0f05da2767df3a3f /net/dccp/ackvec.c | |
parent | 0bd4ff1b1528a39b07aab6c744ac37e053740ad0 (diff) |
[DCCP] ackvec: infrastructure for sending more than one ackvec per packet
Commiter note:
This was split from Andrea's original patch, in the process I changed the type
of the ackvec index fields to u16 instead of to int and haven't folded
dccp_ackvec_parse with dccp_ackvec_check_rcv_ackno.
Next patch will actually do the insertion of more than one ackvec per packet,
using, initially, up to a max of 2 ackvecs as per Andrea's original patch, then
I'll work on support for larger ackvecs, be it using a sysctl or using
setsockopt.
Signed-off-by: Andrea Bittau <a.bittau@cs.ucl.ac.uk>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/dccp/ackvec.c')
-rw-r--r-- | net/dccp/ackvec.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 215355d993de..41d34d1babc1 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c | |||
@@ -169,13 +169,13 @@ void dccp_ackvec_free(struct dccp_ackvec *av) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, | 171 | static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, |
172 | const u8 index) | 172 | const u32 index) |
173 | { | 173 | { |
174 | return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK; | 174 | return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK; |
175 | } | 175 | } |
176 | 176 | ||
177 | static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, | 177 | static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, |
178 | const u8 index) | 178 | const u32 index) |
179 | { | 179 | { |
180 | return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK; | 180 | return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK; |
181 | } | 181 | } |
@@ -275,7 +275,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | |||
275 | * could reduce the complexity of this scan.) | 275 | * could reduce the complexity of this scan.) |
276 | */ | 276 | */ |
277 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); | 277 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); |
278 | u8 index = av->dccpav_buf_head; | 278 | u32 index = av->dccpav_buf_head; |
279 | 279 | ||
280 | while (1) { | 280 | while (1) { |
281 | const u8 len = dccp_ackvec_len(av, index); | 281 | const u8 len = dccp_ackvec_len(av, index); |
@@ -385,7 +385,7 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, | 387 | static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, |
388 | struct sock *sk, u64 ackno, | 388 | struct sock *sk, u64 *ackno, |
389 | const unsigned char len, | 389 | const unsigned char len, |
390 | const unsigned char *vector) | 390 | const unsigned char *vector) |
391 | { | 391 | { |
@@ -408,7 +408,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, | |||
408 | const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; | 408 | const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; |
409 | u64 ackno_end_rl; | 409 | u64 ackno_end_rl; |
410 | 410 | ||
411 | dccp_set_seqno(&ackno_end_rl, ackno - rl); | 411 | dccp_set_seqno(&ackno_end_rl, *ackno - rl); |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * If our AVR sequence number is greater than the ack, go | 414 | * If our AVR sequence number is greater than the ack, go |
@@ -416,13 +416,13 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, | |||
416 | */ | 416 | */ |
417 | list_for_each_entry_from(avr, &av->dccpav_records, | 417 | list_for_each_entry_from(avr, &av->dccpav_records, |
418 | dccpavr_node) { | 418 | dccpavr_node) { |
419 | if (!after48(avr->dccpavr_ack_seqno, ackno)) | 419 | if (!after48(avr->dccpavr_ack_seqno, *ackno)) |
420 | goto found; | 420 | goto found; |
421 | } | 421 | } |
422 | /* End of the dccpav_records list, not found, exit */ | 422 | /* End of the dccpav_records list, not found, exit */ |
423 | break; | 423 | break; |
424 | found: | 424 | found: |
425 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { | 425 | if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, *ackno)) { |
426 | const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; | 426 | const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; |
427 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { | 427 | if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { |
428 | dccp_pr_debug("%s ACK vector 0, len=%d, " | 428 | dccp_pr_debug("%s ACK vector 0, len=%d, " |
@@ -442,21 +442,20 @@ found: | |||
442 | */ | 442 | */ |
443 | } | 443 | } |
444 | 444 | ||
445 | dccp_set_seqno(&ackno, ackno_end_rl - 1); | 445 | dccp_set_seqno(ackno, ackno_end_rl - 1); |
446 | ++vector; | 446 | ++vector; |
447 | } | 447 | } |
448 | } | 448 | } |
449 | 449 | ||
450 | int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, | 450 | int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, |
451 | const u8 opt, const u8 *value, const u8 len) | 451 | u64 *ackno, const u8 opt, const u8 *value, const u8 len) |
452 | { | 452 | { |
453 | if (len > DCCP_MAX_ACKVEC_LEN) | 453 | if (len > DCCP_MAX_ACKVEC_OPT_LEN) |
454 | return -1; | 454 | return -1; |
455 | 455 | ||
456 | /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */ | 456 | /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */ |
457 | dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk, | 457 | dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk, |
458 | DCCP_SKB_CB(skb)->dccpd_ack_seq, | 458 | ackno, len, value); |
459 | len, value); | ||
460 | return 0; | 459 | return 0; |
461 | } | 460 | } |
462 | 461 | ||