Commit c3cc4b91 authored by Jon Grimm's avatar Jon Grimm

Merge touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5

into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents 8cbcdb66 3d34635b
...@@ -1291,19 +1291,11 @@ struct sctp_association { ...@@ -1291,19 +1291,11 @@ struct sctp_association {
* used in the bulk of the text. This value is hidden * used in the bulk of the text. This value is hidden
* in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn().
*/ */
sctp_tsnmap_t tsn_map; struct sctp_tsnmap tsn_map;
__u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)]; __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)];
/* We record duplicate TSNs here. We clear this after
* every SACK.
* FIXME: We should move this into the tsnmap? --jgrimm
*/
sctp_dup_tsn_t dup_tsns[SCTP_MAX_DUP_TSNS];
int next_dup_tsn;
/* Do we need to sack the peer? */ /* Do we need to sack the peer? */
uint8_t sack_needed; __u8 sack_needed;
/* These are capabilities which our peer advertised. */ /* These are capabilities which our peer advertised. */
__u8 ecn_capable; /* Can peer do ECN? */ __u8 ecn_capable; /* Can peer do ECN? */
__u8 ipv4_address; /* Peer understands IPv4 addresses? */ __u8 ipv4_address; /* Peer understands IPv4 addresses? */
......
...@@ -38,8 +38,6 @@ ...@@ -38,8 +38,6 @@
#ifndef __sctp_tsnmap_h__ #ifndef __sctp_tsnmap_h__
#define __sctp_tsnmap_h__ #define __sctp_tsnmap_h__
/* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB) /* RFC 2960 12.2 Parameters necessary per association (i.e. the TCB)
* Mapping An array of bits or bytes indicating which out of * Mapping An array of bits or bytes indicating which out of
* Array order TSN's have been received (relative to the * Array order TSN's have been received (relative to the
...@@ -48,9 +46,7 @@ ...@@ -48,9 +46,7 @@
* will be set to all zero. This structure may be * will be set to all zero. This structure may be
* in the form of a circular buffer or bit array. * in the form of a circular buffer or bit array.
*/ */
typedef struct sctp_tsnmap { struct sctp_tsnmap {
/* This array counts the number of chunks with each TSN. /* This array counts the number of chunks with each TSN.
* It points at one of the two buffers with which we will * It points at one of the two buffers with which we will
* ping-pong between. * ping-pong between.
...@@ -93,25 +89,30 @@ typedef struct sctp_tsnmap { ...@@ -93,25 +89,30 @@ typedef struct sctp_tsnmap {
/* This is the highest TSN we've marked. */ /* This is the highest TSN we've marked. */
__u32 max_tsn_seen; __u32 max_tsn_seen;
/* No. of data chunks pending receipt. used by SCTP_STATUS sockopt */ /* Data chunks pending receipt. used by SCTP_STATUS sockopt */
__u16 pending_data; __u16 pending_data;
/* We record duplicate TSNs here. We clear this after
* every SACK. Store up to SCTP_MAX_DUP_TSNS worth of
* information.
*/
__u32 dup_tsns[SCTP_MAX_DUP_TSNS];
__u16 num_dup_tsns;
int malloced; int malloced;
__u8 raw_map[0]; __u8 raw_map[0];
} sctp_tsnmap_t; };
typedef struct sctp_tsnmap_iter { struct sctp_tsnmap_iter {
__u32 start; __u32 start;
} sctp_tsnmap_iter_t; };
/* Create a new tsnmap. */ /* Create a new tsnmap. */
sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int priority);
int priority);
/* Dispose of a tsnmap. */ /* Dispose of a tsnmap. */
void sctp_tsnmap_free(sctp_tsnmap_t *map); void sctp_tsnmap_free(struct sctp_tsnmap *);
/* This macro assists in creation of external storage for variable length /* This macro assists in creation of external storage for variable length
* internal buffers. We double allocate so the overflow map works. * internal buffers. We double allocate so the overflow map works.
...@@ -119,9 +120,8 @@ void sctp_tsnmap_free(sctp_tsnmap_t *map); ...@@ -119,9 +120,8 @@ void sctp_tsnmap_free(sctp_tsnmap_t *map);
#define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2) #define sctp_tsnmap_storage_size(count) (sizeof(__u8) * (count) * 2)
/* Initialize a block of memory as a tsnmap. */ /* Initialize a block of memory as a tsnmap. */
sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn); struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *, __u16 len,
__u32 initial_tsn);
/* Test the tracking state of this TSN. /* Test the tracking state of this TSN.
* Returns: * Returns:
...@@ -129,29 +129,51 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn ...@@ -129,29 +129,51 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn
* >0 if the TSN has been seen (duplicate) * >0 if the TSN has been seen (duplicate)
* <0 if the TSN is invalid (too large to track) * <0 if the TSN is invalid (too large to track)
*/ */
int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn); int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn);
/* Mark this TSN as seen. */ /* Mark this TSN as seen. */
void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn); void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn);
/* Retrieve the Cumulative TSN ACK Point. */ /* Retrieve the Cumulative TSN ACK Point. */
__u32 sctp_tsnmap_get_ctsn(const sctp_tsnmap_t *map); __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *);
/* Retrieve the highest TSN we've seen. */ /* Retrieve the highest TSN we've seen. */
__u32 sctp_tsnmap_get_max_tsn_seen(const sctp_tsnmap_t *map); __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *);
/* How many Duplicate TSNs are stored? */
static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map)
{
return map->num_dup_tsns;
}
/* Return pointer to duplicate tsn array as needed by SACK. */
static inline __u32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map)
{
map->num_dup_tsns = 0;
return map->dup_tsns;
}
/* Mark a duplicate TSN. Note: we limit how many we are willing to
* store and consequently report.
*/
static inline void sctp_tsnmap_mark_dup(struct sctp_tsnmap *map, __u32 tsn)
{
if (map->num_dup_tsns < SCTP_MAX_DUP_TSNS)
map->dup_tsns[map->num_dup_tsns++] = tsn;
}
/* Is there a gap in the TSN map? */ /* Is there a gap in the TSN map? */
int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map); int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
/* Initialize a gap ack block interator from user-provided memory. */ /* Initialize a gap ack block interator from user-provided memory. */
void sctp_tsnmap_iter_init(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter); void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
struct sctp_tsnmap_iter *);
/* Get the next gap ack blocks. We return 0 if there are no more /* Get the next gap ack blocks. We return 0 if there are no more
* gap ack blocks. * gap ack blocks.
*/ */
int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter, int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
__u16 *start, __u16 *end); struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
#endif /* __sctp_tsnmap_h__ */ #endif /* __sctp_tsnmap_h__ */
......
...@@ -260,7 +260,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc, ...@@ -260,7 +260,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
/* Set up the tsn tracking. */ /* Set up the tsn tracking. */
sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0); sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0);
asoc->peer.next_dup_tsn = 0;
skb_queue_head_init(&asoc->addip_chunks); skb_queue_head_init(&asoc->addip_chunks);
...@@ -850,7 +849,6 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new) ...@@ -850,7 +849,6 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
/* Copy in new parameters of peer. */ /* Copy in new parameters of peer. */
asoc->c = new->c; asoc->c = new->c;
asoc->peer.rwnd = new->peer.rwnd; asoc->peer.rwnd = new->peer.rwnd;
asoc->peer.next_dup_tsn = new->peer.next_dup_tsn;
asoc->peer.sack_needed = new->peer.sack_needed; asoc->peer.sack_needed = new->peer.sack_needed;
asoc->peer.i = new->peer.i; asoc->peer.i = new->peer.i;
sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE,
...@@ -992,9 +990,9 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len) ...@@ -992,9 +990,9 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
asoc->rwnd += len; asoc->rwnd += len;
} }
SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) - %u\n", SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) "
__FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over, "- %u\n", __FUNCTION__, asoc, len, asoc->rwnd,
asoc->a_rwnd); asoc->rwnd_over, asoc->a_rwnd);
/* Send a window update SACK if the rwnd has increased by at least the /* Send a window update SACK if the rwnd has increased by at least the
* minimum of the association's PMTU and half of the receive buffer. * minimum of the association's PMTU and half of the receive buffer.
...@@ -1016,7 +1014,6 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len) ...@@ -1016,7 +1014,6 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
asoc->a_rwnd = asoc->rwnd; asoc->a_rwnd = asoc->rwnd;
asoc->peer.sack_needed = 0; asoc->peer.sack_needed = 0;
asoc->peer.next_dup_tsn = 0;
sctp_outq_tail(&asoc->outqueue, sack); sctp_outq_tail(&asoc->outqueue, sack);
......
...@@ -222,9 +222,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc, ...@@ -222,9 +222,7 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *asoc,
sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &sat_param); sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &sat_param);
sctp_addto_chunk(retval, sizeof(sat_addr_types), sat_addr_types); sctp_addto_chunk(retval, sizeof(sat_addr_types), sat_addr_types);
sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
nodata: nodata:
if (addrs.v) if (addrs.v)
kfree(addrs.v); kfree(addrs.v);
...@@ -587,14 +585,12 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc) ...@@ -587,14 +585,12 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc)
sctp_gap_ack_block_t gab; sctp_gap_ack_block_t gab;
int length; int length;
__u32 ctsn; __u32 ctsn;
sctp_tsnmap_iter_t iter; struct sctp_tsnmap_iter iter;
__u16 num_gabs; __u16 num_gabs, num_dup_tsns;
__u16 num_dup_tsns = asoc->peer.next_dup_tsn; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
const sctp_tsnmap_t *map = &asoc->peer.tsn_map;
ctsn = sctp_tsnmap_get_ctsn(map); ctsn = sctp_tsnmap_get_ctsn(map);
SCTP_DEBUG_PRINTK("make_sack: sackCTSNAck sent is 0x%x.\n", SCTP_DEBUG_PRINTK("sackCTSNAck sent is 0x%x.\n", ctsn);
ctsn);
/* Count the number of Gap Ack Blocks. */ /* Count the number of Gap Ack Blocks. */
sctp_tsnmap_iter_init(map, &iter); sctp_tsnmap_iter_init(map, &iter);
...@@ -604,6 +600,8 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc) ...@@ -604,6 +600,8 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc)
/* Do nothing. */ /* Do nothing. */
} }
num_dup_tsns = sctp_tsnmap_num_dups(map);
/* Initialize the SACK header. */ /* Initialize the SACK header. */
sack.cum_tsn_ack = htonl(ctsn); sack.cum_tsn_ack = htonl(ctsn);
sack.a_rwnd = htonl(asoc->rwnd); sack.a_rwnd = htonl(asoc->rwnd);
...@@ -612,7 +610,7 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc) ...@@ -612,7 +610,7 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc)
length = sizeof(sack) length = sizeof(sack)
+ sizeof(sctp_gap_ack_block_t) * num_gabs + sizeof(sctp_gap_ack_block_t) * num_gabs
+ sizeof(sctp_dup_tsn_t) * num_dup_tsns; + sizeof(__u32) * num_dup_tsns;
/* Create the chunk. */ /* Create the chunk. */
retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, length); retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, length);
...@@ -659,21 +657,18 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc) ...@@ -659,21 +657,18 @@ sctp_chunk_t *sctp_make_sack(const sctp_association_t *asoc)
while(sctp_tsnmap_next_gap_ack(map, &iter, &gab.start, &gab.end)) { while(sctp_tsnmap_next_gap_ack(map, &iter, &gab.start, &gab.end)) {
gab.start = htons(gab.start); gab.start = htons(gab.start);
gab.end = htons(gab.end); gab.end = htons(gab.end);
sctp_addto_chunk(retval, sctp_addto_chunk(retval, sizeof(sctp_gap_ack_block_t), &gab);
sizeof(sctp_gap_ack_block_t),
&gab);
} }
/* Register the duplicates. */ /* Register the duplicates. */
sctp_addto_chunk(retval, sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
sizeof(sctp_dup_tsn_t) * num_dup_tsns, sctp_tsnmap_get_dups(map));
&asoc->peer.dup_tsns);
nodata: nodata:
return retval; return retval;
} }
/* FIXME: Comments. */ /* Make a SHUTDOWN chunk. */
sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc) sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc)
{ {
sctp_chunk_t *retval; sctp_chunk_t *retval;
...@@ -690,7 +685,6 @@ sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc) ...@@ -690,7 +685,6 @@ sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc)
retval->subh.shutdown_hdr = retval->subh.shutdown_hdr =
sctp_addto_chunk(retval, sizeof(shut), &shut); sctp_addto_chunk(retval, sizeof(shut), &shut);
nodata: nodata:
return retval; return retval;
} }
......
...@@ -527,10 +527,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, ...@@ -527,10 +527,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
break; break;
case SCTP_CMD_REPORT_DUP: case SCTP_CMD_REPORT_DUP:
if (asoc->peer.next_dup_tsn < SCTP_MAX_DUP_TSNS) { sctp_tsnmap_mark_dup(&asoc->peer.tsn_map,
asoc->peer.dup_tsns[asoc->peer.next_dup_tsn++] = ntohl(command->obj.u32));
ntohl(command->obj.u32);
}
break; break;
case SCTP_CMD_REPORT_BIGGAP: case SCTP_CMD_REPORT_BIGGAP:
...@@ -744,7 +742,6 @@ int sctp_gen_sack(sctp_association_t *asoc, int force, sctp_cmd_seq_t *commands) ...@@ -744,7 +742,6 @@ int sctp_gen_sack(sctp_association_t *asoc, int force, sctp_cmd_seq_t *commands)
asoc->a_rwnd = asoc->rwnd; asoc->a_rwnd = asoc->rwnd;
asoc->peer.sack_needed = 0; asoc->peer.sack_needed = 0;
asoc->peer.next_dup_tsn = 0;
error = sctp_outq_tail(&asoc->outqueue, sack); error = sctp_outq_tail(&asoc->outqueue, sack);
......
...@@ -4353,6 +4353,9 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk) ...@@ -4353,6 +4353,9 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
__u16 num_blocks; __u16 num_blocks;
__u16 num_dup_tsns; __u16 num_dup_tsns;
/* FIXME: Protect ourselves from reading too far into
* the skb from a bogus sender.
*/
sack = (sctp_sackhdr_t *) chunk->skb->data; sack = (sctp_sackhdr_t *) chunk->skb->data;
skb_pull(chunk->skb, sizeof(sctp_sackhdr_t)); skb_pull(chunk->skb, sizeof(sctp_sackhdr_t));
......
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
#include <net/sctp/sctp.h> #include <net/sctp/sctp.h>
#include <net/sctp/sm.h> #include <net/sctp/sm.h>
static void _sctp_tsnmap_update(sctp_tsnmap_t *map); static void sctp_tsnmap_update(struct sctp_tsnmap *map);
static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map); static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map);
static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
__u16 len, __u16 base, __u16 len, __u16 base,
int *started, __u16 *start, int *started, __u16 *start,
int *ended, __u16 *end); int *ended, __u16 *end);
...@@ -55,11 +55,11 @@ static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, ...@@ -55,11 +55,11 @@ static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
/* Create a new sctp_tsnmap. /* Create a new sctp_tsnmap.
* Allocate room to store at least 'len' contiguous TSNs. * Allocate room to store at least 'len' contiguous TSNs.
*/ */
sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority) struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority)
{ {
sctp_tsnmap_t *retval; struct sctp_tsnmap *retval;
retval = kmalloc(sizeof(sctp_tsnmap_t) + retval = kmalloc(sizeof(struct sctp_tsnmap) +
sctp_tsnmap_storage_size(len), sctp_tsnmap_storage_size(len),
priority); priority);
if (!retval) if (!retval)
...@@ -72,13 +72,13 @@ sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority) ...@@ -72,13 +72,13 @@ sctp_tsnmap_t *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int priority)
fail_map: fail_map:
kfree(retval); kfree(retval);
fail: fail:
return NULL; return NULL;
} }
/* Initialize a block of memory as a tsnmap. */ /* Initialize a block of memory as a tsnmap. */
sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn) struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
__u32 initial_tsn)
{ {
map->tsn_map = map->raw_map; map->tsn_map = map->raw_map;
map->overflow_map = map->tsn_map + len; map->overflow_map = map->tsn_map + len;
...@@ -94,6 +94,7 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn ...@@ -94,6 +94,7 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn
map->max_tsn_seen = map->cumulative_tsn_ack_point; map->max_tsn_seen = map->cumulative_tsn_ack_point;
map->malloced = 0; map->malloced = 0;
map->pending_data = 0; map->pending_data = 0;
map->num_dup_tsns = 0;
return map; return map;
} }
...@@ -104,7 +105,7 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn ...@@ -104,7 +105,7 @@ sctp_tsnmap_t *sctp_tsnmap_init(sctp_tsnmap_t *map, __u16 len, __u32 initial_tsn
* >0 if the TSN has been seen (duplicate) * >0 if the TSN has been seen (duplicate)
* <0 if the TSN is invalid (too large to track) * <0 if the TSN is invalid (too large to track)
*/ */
int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn) int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
{ {
__s32 gap; __s32 gap;
int dup; int dup;
...@@ -136,7 +137,7 @@ int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn) ...@@ -136,7 +137,7 @@ int sctp_tsnmap_check(const sctp_tsnmap_t *map, __u32 tsn)
} }
/* Is there a gap in the TSN map? */ /* Is there a gap in the TSN map? */
int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map) int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map)
{ {
int has_gap; int has_gap;
...@@ -145,7 +146,7 @@ int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map) ...@@ -145,7 +146,7 @@ int sctp_tsnmap_has_gap(const sctp_tsnmap_t *map)
} }
/* Mark this TSN as seen. */ /* Mark this TSN as seen. */
void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn) void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
{ {
__s32 gap; __s32 gap;
...@@ -173,40 +174,45 @@ void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn) ...@@ -173,40 +174,45 @@ void sctp_tsnmap_mark(sctp_tsnmap_t *map, __u32 tsn)
/* Go fixup any internal TSN mapping variables including /* Go fixup any internal TSN mapping variables including
* cumulative_tsn_ack_point. * cumulative_tsn_ack_point.
*/ */
_sctp_tsnmap_update(map); sctp_tsnmap_update(map);
}
void sctp_tsnmap_report_dup(struct sctp_tsnmap *map, __u32 tsn)
{
} }
/* Retrieve the Cumulative TSN Ack Point. */ /* Retrieve the Cumulative TSN Ack Point. */
__u32 sctp_tsnmap_get_ctsn(const sctp_tsnmap_t *map) __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map)
{ {
return map->cumulative_tsn_ack_point; return map->cumulative_tsn_ack_point;
} }
/* Retrieve the highest TSN we've seen. */ /* Retrieve the highest TSN we've seen. */
__u32 sctp_tsnmap_get_max_tsn_seen(const sctp_tsnmap_t *map) __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map)
{ {
return map->max_tsn_seen; return map->max_tsn_seen;
} }
/* Dispose of a tsnmap. */ /* Dispose of a tsnmap. */
void sctp_tsnmap_free(sctp_tsnmap_t *map) void sctp_tsnmap_free(struct sctp_tsnmap *map)
{ {
if (map->malloced) if (map->malloced)
kfree(map); kfree(map);
} }
/* Initialize a Gap Ack Block iterator from memory being provided. */ /* Initialize a Gap Ack Block iterator from memory being provided. */
void sctp_tsnmap_iter_init(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter) void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
struct sctp_tsnmap_iter *iter)
{ {
/* Only start looking one past the Cumulative TSN Ack Point. */ /* Only start looking one past the Cumulative TSN Ack Point. */
iter->start = map->cumulative_tsn_ack_point + 1; iter->start = map->cumulative_tsn_ack_point + 1;
} }
/* Get the next Gap Ack Blocks. Returns 0 if there was not /* Get the next Gap Ack Blocks. Returns 0 if there was not another block
* another block to get. * to get.
*/ */
int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter, int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
__u16 *start, __u16 *end) struct sctp_tsnmap_iter *iter, __u16 *start, __u16 *end)
{ {
int started, ended; int started, ended;
__u16 _start, _end, offset; __u16 _start, _end, offset;
...@@ -216,12 +222,10 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter, ...@@ -216,12 +222,10 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
/* Search the first mapping array. */ /* Search the first mapping array. */
if (iter->start - map->base_tsn < map->len) { if (iter->start - map->base_tsn < map->len) {
offset = iter->start - map->base_tsn; offset = iter->start - map->base_tsn;
_sctp_tsnmap_find_gap_ack(map->tsn_map, sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len, 0,
offset, &started, &_start, &ended, &_end);
map->len, 0,
&started, &_start,
&ended, &_end);
} }
/* Do we need to check the overflow map? */ /* Do we need to check the overflow map? */
...@@ -235,7 +239,7 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter, ...@@ -235,7 +239,7 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
offset = iter->start - map->base_tsn - map->len; offset = iter->start - map->base_tsn - map->len;
/* Search the overflow map. */ /* Search the overflow map. */
_sctp_tsnmap_find_gap_ack(map->overflow_map, sctp_tsnmap_find_gap_ack(map->overflow_map,
offset, offset,
map->len, map->len,
map->len, map->len,
...@@ -278,7 +282,7 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter, ...@@ -278,7 +282,7 @@ int sctp_tsnmap_next_gap_ack(const sctp_tsnmap_t *map, sctp_tsnmap_iter_t *iter,
/* This private helper function updates the tsnmap buffers and /* This private helper function updates the tsnmap buffers and
* the Cumulative TSN Ack Point. * the Cumulative TSN Ack Point.
*/ */
static void _sctp_tsnmap_update(sctp_tsnmap_t *map) static void sctp_tsnmap_update(struct sctp_tsnmap *map)
{ {
__u32 ctsn; __u32 ctsn;
...@@ -301,10 +305,10 @@ static void _sctp_tsnmap_update(sctp_tsnmap_t *map) ...@@ -301,10 +305,10 @@ static void _sctp_tsnmap_update(sctp_tsnmap_t *map)
} while (map->tsn_map[ctsn - map->base_tsn]); } while (map->tsn_map[ctsn - map->base_tsn]);
map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */ map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */
_sctp_tsnmap_update_pending_data(map); sctp_tsnmap_update_pending_data(map);
} }
static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map) static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map)
{ {
__u32 cum_tsn = map->cumulative_tsn_ack_point; __u32 cum_tsn = map->cumulative_tsn_ack_point;
__u32 max_tsn = map->max_tsn_seen; __u32 max_tsn = map->max_tsn_seen;
...@@ -345,14 +349,14 @@ static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map) ...@@ -345,14 +349,14 @@ static void _sctp_tsnmap_update_pending_data(sctp_tsnmap_t *map)
* The flags "started" and "ended" tell is if we found the beginning * The flags "started" and "ended" tell is if we found the beginning
* or (respectively) the end of a Gap Ack Block. * or (respectively) the end of a Gap Ack Block.
*/ */
static void _sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
__u16 len, __u16 base, __u16 len, __u16 base,
int *started, __u16 *start, int *started, __u16 *start,
int *ended, __u16 *end) int *ended, __u16 *end)
{ {
int i = off; int i = off;
/* Let's look through the entire array, but break out /* Look through the entire array, but break out
* early if we have found the end of the Gap Ack Block. * early if we have found the end of the Gap Ack Block.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment