From 8274c19a77ee6af22ded106e272937904224aad1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Aug 2007 14:25:32 -0700 Subject: [PATCH] --- yaml --- r: 64612 b: refs/heads/master c: 6e69d6068cc2aa545544189a1ee4d2e1a32ad591 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/sparc64/kernel/irq.c | 2 +- trunk/drivers/net/bnx2.c | 10 ++- trunk/include/asm-sparc64/irq.h | 22 +++--- trunk/include/linux/rtnetlink.h | 2 - trunk/include/net/sctp/sm.h | 2 +- trunk/include/net/sctp/structs.h | 1 - trunk/include/net/sctp/ulpqueue.h | 1 - trunk/net/bridge/br_fdb.c | 5 -- trunk/net/bridge/br_if.c | 16 ++--- trunk/net/bridge/br_input.c | 3 +- trunk/net/core/pktgen.c | 8 ++- trunk/net/ipv4/tcp_input.c | 14 +--- trunk/net/netfilter/xt_tcpudp.c | 2 +- trunk/net/sched/sch_prio.c | 2 +- trunk/net/sctp/associola.c | 7 +- trunk/net/sctp/outqueue.c | 7 -- trunk/net/sctp/sm_make_chunk.c | 112 ++++++++++-------------------- trunk/net/sctp/sm_sideeffect.c | 8 +-- trunk/net/sctp/sm_statefuns.c | 51 +++++++------- trunk/net/sctp/socket.c | 3 - trunk/net/sctp/ulpqueue.c | 75 ++++---------------- 22 files changed, 113 insertions(+), 242 deletions(-) diff --git a/[refs] b/[refs] index 5d103bb4775a..bdee9c8f3f18 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0ee13079906f0e0b185b13a1fbdaf24d853baa8d +refs/heads/master: 6e69d6068cc2aa545544189a1ee4d2e1a32ad591 diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index 384abf410cf0..51b8875a13a8 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -308,7 +308,7 @@ static void sun4u_irq_disable(unsigned int virt_irq) if (likely(data)) { unsigned long imap = data->imap; - u32 tmp = upa_readq(imap); + unsigned long tmp = upa_readq(imap); tmp &= ~IMAP_VALID; upa_writeq(tmp, imap); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 854d80c330ec..24e7f9ab3f5a 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -3934,13 +3934,11 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) /* Chip reset. */ REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); - /* Reading back any register after chip reset will hang the - * bus on 5706 A0 and A1. The msleep below provides plenty - * of margin for write posting. - */ if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || - (CHIP_ID(bp) == CHIP_ID_5706_A1)) - msleep(20); + (CHIP_ID(bp) == CHIP_ID_5706_A1)) { + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ / 50); + } /* Reset takes approximate 30 usec */ for (i = 0; i < 10; i++) { diff --git a/trunk/include/asm-sparc64/irq.h b/trunk/include/asm-sparc64/irq.h index e6c436ef9356..c041e10ae7df 100644 --- a/trunk/include/asm-sparc64/irq.h +++ b/trunk/include/asm-sparc64/irq.h @@ -16,21 +16,21 @@ #include /* IMAP/ICLR register defines */ -#define IMAP_VALID 0x80000000 /* IRQ Enabled */ -#define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ -#define IMAP_TID_JBUS 0x7c000000 /* JBUS TargetID */ +#define IMAP_VALID 0x80000000UL /* IRQ Enabled */ +#define IMAP_TID_UPA 0x7c000000UL /* UPA TargetID */ +#define IMAP_TID_JBUS 0x7c000000UL /* JBUS TargetID */ #define IMAP_TID_SHIFT 26 -#define IMAP_AID_SAFARI 0x7c000000 /* Safari AgentID */ +#define IMAP_AID_SAFARI 0x7c000000UL /* Safari AgentID */ #define IMAP_AID_SHIFT 26 -#define IMAP_NID_SAFARI 0x03e00000 /* Safari NodeID */ +#define IMAP_NID_SAFARI 0x03e00000UL /* Safari NodeID */ #define IMAP_NID_SHIFT 21 -#define IMAP_IGN 0x000007c0 /* IRQ Group Number */ -#define IMAP_INO 0x0000003f /* IRQ Number */ -#define IMAP_INR 0x000007ff /* Full interrupt number*/ +#define IMAP_IGN 0x000007c0UL /* IRQ Group Number */ +#define IMAP_INO 0x0000003fUL /* IRQ Number */ +#define IMAP_INR 0x000007ffUL /* Full interrupt number*/ -#define ICLR_IDLE 0x00000000 /* Idle state */ -#define ICLR_TRANSMIT 0x00000001 /* Transmit state */ -#define ICLR_PENDING 0x00000003 /* Pending state */ +#define ICLR_IDLE 0x00000000UL /* Idle state */ +#define ICLR_TRANSMIT 0x00000001UL /* Transmit state */ +#define ICLR_PENDING 0x00000003UL /* Pending state */ /* The largest number of unique interrupt sources we support. * If this needs to ever be larger than 255, you need to change diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h index dff3192374f8..c91476ce314a 100644 --- a/trunk/include/linux/rtnetlink.h +++ b/trunk/include/linux/rtnetlink.h @@ -351,8 +351,6 @@ enum #define RTAX_INITCWND RTAX_INITCWND RTAX_FEATURES, #define RTAX_FEATURES RTAX_FEATURES - RTAX_RTO_MIN, -#define RTAX_RTO_MIN RTAX_RTO_MIN __RTAX_MAX }; diff --git a/trunk/include/net/sctp/sm.h b/trunk/include/net/sctp/sm.h index 991c85bb9e36..73cb9943c8a8 100644 --- a/trunk/include/net/sctp/sm.h +++ b/trunk/include/net/sctp/sm.h @@ -214,7 +214,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, const struct sctp_chunk *); struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, const struct sctp_chunk *); -void sctp_init_cause(struct sctp_chunk *, __be16 cause, size_t); +void sctp_init_cause(struct sctp_chunk *, __be16 cause, const void *, size_t); struct sctp_chunk *sctp_make_abort(const struct sctp_association *, const struct sctp_chunk *, const size_t hint); diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index c0d5848c33dc..ee4559b11302 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -726,7 +726,6 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, struct iovec *data); void sctp_chunk_free(struct sctp_chunk *); void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); -void *sctp_addto_param(struct sctp_chunk *, int len, const void *data); struct sctp_chunk *sctp_chunkify(struct sk_buff *, const struct sctp_association *, struct sock *); diff --git a/trunk/include/net/sctp/ulpqueue.h b/trunk/include/net/sctp/ulpqueue.h index cd33270e86dd..39ea3f442b47 100644 --- a/trunk/include/net/sctp/ulpqueue.h +++ b/trunk/include/net/sctp/ulpqueue.h @@ -83,7 +83,6 @@ int sctp_clear_pd(struct sock *sk, struct sctp_association *asoc); /* Skip over an SSN. */ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn); -void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *, __u32); #endif /* __sctp_ulpqueue_h__ */ diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index eb57502bb264..69b70977f000 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -384,11 +384,6 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (hold_time(br) == 0) return; - /* ignore packets unless we are using this port */ - if (!(source->state == BR_STATE_LEARNING || - source->state == BR_STATE_FORWARDING)) - return; - fdb = fdb_find(head, addr); if (likely(fdb)) { /* attempt to update an entry for a local interface */ diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 9272f12f664c..749f0e8f541d 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -33,17 +33,17 @@ */ static int port_cost(struct net_device *dev) { - if (dev->ethtool_ops && dev->ethtool_ops->get_settings) { - struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, }; - - if (!dev->ethtool_ops->get_settings(dev, &ecmd)) { + if (dev->ethtool_ops->get_settings) { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + int err = dev->ethtool_ops->get_settings(dev, &ecmd); + if (!err) { switch(ecmd.speed) { - case SPEED_10000: - return 2; - case SPEED_1000: - return 4; case SPEED_100: return 19; + case SPEED_1000: + return 4; + case SPEED_10000: + return 2; case SPEED_10: return 100; } diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index 6f468fc3357a..5c18595b7616 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -101,8 +101,9 @@ static int br_handle_local_finish(struct sk_buff *skb) { struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); - if (p) + if (p && p->state != BR_STATE_DISABLED) br_fdb_update(p->br, p, eth_hdr(skb)->h_source); + return 0; /* process further */ } diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 36fdea71d742..7bae576ac115 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -380,6 +380,7 @@ struct pktgen_thread { /* Field for thread to receive "posted" events terminate, stop ifs etc. */ u32 control; + int pid; int cpu; wait_queue_head_t queue; @@ -3330,9 +3331,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev) } if ((netif_queue_stopped(odev) || - (pkt_dev->skb && - netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping))) || - need_resched()) { + netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) || + need_resched()) { idle_start = getCurUs(); if (!netif_running(odev)) { @@ -3462,6 +3462,8 @@ static int pktgen_thread_worker(void *arg) init_waitqueue_head(&t->queue); + t->pid = current->pid; + pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid); max_before_softirq = t->max_before_softirq; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 1ee72127462b..9785df37a65f 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -555,16 +555,6 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb) tcp_grow_window(sk, skb); } -static u32 tcp_rto_min(struct sock *sk) -{ - struct dst_entry *dst = __sk_dst_get(sk); - u32 rto_min = TCP_RTO_MIN; - - if (dst_metric_locked(dst, RTAX_RTO_MIN)) - rto_min = dst->metrics[RTAX_RTO_MIN-1]; - return rto_min; -} - /* Called to compute a smoothed rtt estimate. The data fed to this * routine either comes from timestamps, or from segments that were * known _not_ to have been retransmitted [see Karn/Partridge @@ -626,13 +616,13 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt) if (tp->mdev_max < tp->rttvar) tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2; tp->rtt_seq = tp->snd_nxt; - tp->mdev_max = tcp_rto_min(sk); + tp->mdev_max = TCP_RTO_MIN; } } else { /* no previous measure. */ tp->srtt = m<<3; /* take the measured time to be rtt */ tp->mdev = m<<1; /* make sure rto = 3*rtt */ - tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); + tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); tp->rtt_seq = tp->snd_nxt; } } diff --git a/trunk/net/netfilter/xt_tcpudp.c b/trunk/net/netfilter/xt_tcpudp.c index 223f9bded672..ab7d845224fc 100644 --- a/trunk/net/netfilter/xt_tcpudp.c +++ b/trunk/net/netfilter/xt_tcpudp.c @@ -188,7 +188,7 @@ udp_checkentry(const char *tablename, void *matchinfo, unsigned int hook_mask) { - const struct xt_udp *udpinfo = matchinfo; + const struct xt_tcp *udpinfo = matchinfo; /* Must specify no unknown invflags */ return !(udpinfo->invflags & ~XT_UDP_INV_MASK); diff --git a/trunk/net/sched/sch_prio.c b/trunk/net/sched/sch_prio.c index abd82fc3ec60..4a49db65772e 100644 --- a/trunk/net/sched/sch_prio.c +++ b/trunk/net/sched/sch_prio.c @@ -44,7 +44,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) if (TC_H_MAJ(skb->priority) != sch->handle) { err = tc_classify(skb, q->filter_list, &res); #ifdef CONFIG_NET_CLS_ACT - switch (err) { + switch (tc_classify(skb, q->filter_list, &res)) { case TC_ACT_STOLEN: case TC_ACT_QUEUED: *qerr = NET_XMIT_SUCCESS; diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 2ad1caf1ea42..498edb0cd4e5 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -727,12 +727,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, break; case SCTP_TRANSPORT_DOWN: - /* if the transort was never confirmed, do not transition it - * to inactive state. - */ - if (transport->state != SCTP_UNCONFIRMED) - transport->state = SCTP_INACTIVE; - + transport->state = SCTP_INACTIVE; spc_state = SCTP_ADDR_UNREACHABLE; break; diff --git a/trunk/net/sctp/outqueue.c b/trunk/net/sctp/outqueue.c index 28f4fe77ceee..992f361084b7 100644 --- a/trunk/net/sctp/outqueue.c +++ b/trunk/net/sctp/outqueue.c @@ -421,13 +421,6 @@ void sctp_retransmit_mark(struct sctp_outq *q, */ if ((fast_retransmit && (chunk->fast_retransmit > 0)) || (!fast_retransmit && !chunk->tsn_gap_acked)) { - /* If this chunk was sent less then 1 rto ago, do not - * retransmit this chunk, but give the peer time - * to acknowlege it. - */ - if ((jiffies - chunk->sent_at) < transport->rto) - continue; - /* RFC 2960 6.2.1 Processing a Received SACK * * C) Any time a DATA chunk is marked for diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 79856c924525..51c4d7fef1d2 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -110,7 +110,7 @@ static const struct sctp_paramhdr prsctp_param = { * abort chunk. */ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, - size_t paylen) + const void *payload, size_t paylen) { sctp_errhdr_t err; __u16 len; @@ -120,6 +120,7 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, len = sizeof(sctp_errhdr_t) + paylen; err.length = htons(len); chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); + sctp_addto_chunk(chunk, paylen, payload); } /* 3.3.2 Initiation (INIT) (1) @@ -779,8 +780,8 @@ struct sctp_chunk *sctp_make_abort_no_data( /* Put the tsn back into network byte order. */ payload = htonl(tsn); - sctp_init_cause(retval, SCTP_ERROR_NO_DATA, sizeof(payload)); - sctp_addto_chunk(retval, sizeof(payload), (const void *)&payload); + sctp_init_cause(retval, SCTP_ERROR_NO_DATA, (const void *)&payload, + sizeof(payload)); /* RFC 2960 6.4 Multi-homed SCTP Endpoints * @@ -822,8 +823,7 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, goto err_copy; } - sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, paylen); - sctp_addto_chunk(retval, paylen, payload); + sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen); if (paylen) kfree(payload); @@ -850,17 +850,15 @@ struct sctp_chunk *sctp_make_abort_violation( struct sctp_paramhdr phdr; retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen - + sizeof(sctp_paramhdr_t)); + + sizeof(sctp_chunkhdr_t)); if (!retval) goto end; - sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, paylen - + sizeof(sctp_paramhdr_t)); + sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, payload, paylen); phdr.type = htons(chunk->chunk_hdr->type); phdr.length = chunk->chunk_hdr->length; - sctp_addto_chunk(retval, paylen, payload); - sctp_addto_param(retval, sizeof(sctp_paramhdr_t), &phdr); + sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &phdr); end: return retval; @@ -957,8 +955,7 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, if (!retval) goto nodata; - sctp_init_cause(retval, cause_code, paylen); - sctp_addto_chunk(retval, paylen, payload); + sctp_init_cause(retval, cause_code, payload, paylen); nodata: return retval; @@ -1131,7 +1128,7 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) void *target; void *padding; int chunklen = ntohs(chunk->chunk_hdr->length); - int padlen = WORD_ROUND(chunklen) - chunklen; + int padlen = chunklen % 4; padding = skb_put(chunk->skb, padlen); target = skb_put(chunk->skb, len); @@ -1146,25 +1143,6 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data) return target; } -/* Append bytes to the end of a parameter. Will panic if chunk is not big - * enough. - */ -void *sctp_addto_param(struct sctp_chunk *chunk, int len, const void *data) -{ - void *target; - int chunklen = ntohs(chunk->chunk_hdr->length); - - target = skb_put(chunk->skb, len); - - memcpy(target, data, len); - - /* Adjust the chunk length field. */ - chunk->chunk_hdr->length = htons(chunklen + len); - chunk->chunk_end = skb_tail_pointer(chunk->skb); - - return target; -} - /* Append bytes from user space to the end of a chunk. Will panic if * chunk is not big enough. * Returns a kernel err value. @@ -1196,36 +1174,25 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len, */ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk) { - struct sctp_datamsg *msg; - struct sctp_chunk *lchunk; - struct sctp_stream *stream; __u16 ssn; __u16 sid; if (chunk->has_ssn) return; - /* All fragments will be on the same stream */ - sid = ntohs(chunk->subh.data_hdr->stream); - stream = &chunk->asoc->ssnmap->out; - - /* Now assign the sequence number to the entire message. - * All fragments must have the same stream sequence number. - */ - msg = chunk->msg; - list_for_each_entry(lchunk, &msg->chunks, frag_list) { - if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { - ssn = 0; - } else { - if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG) - ssn = sctp_ssn_next(stream, sid); - else - ssn = sctp_ssn_peek(stream, sid); - } - - lchunk->subh.data_hdr->ssn = htons(ssn); - lchunk->has_ssn = 1; + /* This is the last possible instant to assign a SSN. */ + if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { + ssn = 0; + } else { + sid = ntohs(chunk->subh.data_hdr->stream); + if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG) + ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid); + else + ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid); } + + chunk->subh.data_hdr->ssn = htons(ssn); + chunk->has_ssn = 1; } /* Helper function to assign a TSN if needed. This assumes that both @@ -1499,8 +1466,7 @@ struct sctp_association *sctp_unpack_cookie( __be32 n = htonl(usecs); sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE, - sizeof(n)); - sctp_addto_chunk(*errp, sizeof(n), &n); + &n, sizeof(n)); *error = -SCTP_IERROR_STALE_COOKIE; } else *error = -SCTP_IERROR_NOMEM; @@ -1590,8 +1556,7 @@ static int sctp_process_missing_param(const struct sctp_association *asoc, report.num_missing = htonl(1); report.type = paramtype; sctp_init_cause(*errp, SCTP_ERROR_MISS_PARAM, - sizeof(report)); - sctp_addto_chunk(*errp, sizeof(report), &report); + &report, sizeof(report)); } /* Stop processing this chunk. */ @@ -1609,7 +1574,7 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc, *errp = sctp_make_op_error_space(asoc, chunk, 0); if (*errp) - sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, 0); + sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, NULL, 0); /* Stop processing this chunk. */ return 0; @@ -1630,10 +1595,9 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc, *errp = sctp_make_op_error_space(asoc, chunk, payload_len); if (*errp) { - sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, - sizeof(error) + sizeof(sctp_paramhdr_t)); - sctp_addto_chunk(*errp, sizeof(error), error); - sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param); + sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, error, + sizeof(error)); + sctp_addto_chunk(*errp, sizeof(sctp_paramhdr_t), param); } return 0; @@ -1654,10 +1618,9 @@ static int sctp_process_hn_param(const struct sctp_association *asoc, if (!*errp) *errp = sctp_make_op_error_space(asoc, chunk, len); - if (*errp) { - sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len); - sctp_addto_chunk(*errp, len, param.v); - } + if (*errp) + sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, + param.v, len); /* Stop processing this chunk. */ return 0; @@ -1709,13 +1672,10 @@ static int sctp_process_unk_param(const struct sctp_association *asoc, *errp = sctp_make_op_error_space(asoc, chunk, ntohs(chunk->chunk_hdr->length)); - if (*errp) { + if (*errp) sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, + param.v, WORD_ROUND(ntohs(param.p->length))); - sctp_addto_chunk(*errp, - WORD_ROUND(ntohs(param.p->length)), - param.v); - } break; case SCTP_PARAM_ACTION_SKIP: @@ -1730,10 +1690,8 @@ static int sctp_process_unk_param(const struct sctp_association *asoc, if (*errp) { sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, + param.v, WORD_ROUND(ntohs(param.p->length))); - sctp_addto_chunk(*errp, - WORD_ROUND(ntohs(param.p->length)), - param.v); } else { /* If there is no memory for generating the ERROR * report as specified, an ABORT will be triggered @@ -1833,7 +1791,7 @@ int sctp_verify_init(const struct sctp_association *asoc, * VIOLATION error. We build the ERROR chunk here and let the normal * error handling code build and send the packet. */ - if (param.v != (void*)chunk->chunk_end) { + if (param.v < (void*)chunk->chunk_end - sizeof(sctp_paramhdr_t)) { sctp_process_inv_paramlength(asoc, param.p, chunk, errp); return 0; } diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index 8d7890083493..d9fad4f6ffc3 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -1013,9 +1013,8 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, break; case SCTP_DISPOSITION_VIOLATION: - if (net_ratelimit()) - printk(KERN_ERR "sctp protocol violation state %d " - "chunkid %d\n", state, subtype.chunk); + printk(KERN_ERR "sctp protocol violation state %d " + "chunkid %d\n", state, subtype.chunk); break; case SCTP_DISPOSITION_NOT_IMPL: @@ -1131,9 +1130,6 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, /* Move the Cumulattive TSN Ack ahead. */ sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32); - /* purge the fragmentation queue */ - sctp_ulpq_reasm_flushtsn(&asoc->ulpq, cmd->obj.u32); - /* Abort any in progress partial delivery. */ sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); break; diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 177528ed3e1b..71cad56dd73f 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -264,6 +264,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, struct sctp_chunk *err_chunk; struct sctp_packet *packet; sctp_unrecognized_param_t *unk_param; + struct sock *sk; int len; /* 6.10 Bundling @@ -284,6 +285,16 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); + sk = ep->base.sk; + /* If the endpoint is not listening or if the number of associations + * on the TCP-style socket exceed the max backlog, respond with an + * ABORT. + */ + if (!sctp_sstate(sk, LISTENING) || + (sctp_style(sk, TCP) && + sk_acceptq_is_full(sk))) + return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); + /* 3.1 A packet containing an INIT chunk MUST have a zero Verification * Tag. */ @@ -579,7 +590,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, struct sctp_ulpevent *ev, *ai_ev = NULL; int error = 0; struct sctp_chunk *err_chk_p; - struct sock *sk; /* If the packet is an OOTB packet which is temporarily on the * control endpoint, respond with an ABORT. @@ -595,15 +605,6 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) return sctp_sf_pdiscard(ep, asoc, type, arg, commands); - /* If the endpoint is not listening or if the number of associations - * on the TCP-style socket exceed the max backlog, respond with an - * ABORT. - */ - sk = ep->base.sk; - if (!sctp_sstate(sk, LISTENING) || - (sctp_style(sk, TCP) && sk_acceptq_is_full(sk))) - return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); - /* "Decode" the chunk. We have no optional parameters so we * are in good shape. */ @@ -1031,21 +1032,19 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, /* This should never happen, but lets log it if so. */ if (unlikely(!link)) { if (from_addr.sa.sa_family == AF_INET6) { - if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address " - NIP6_FMT "\n", - __FUNCTION__, - asoc, - NIP6(from_addr.v6.sin6_addr)); + printk(KERN_WARNING + "%s association %p could not find address " + NIP6_FMT "\n", + __FUNCTION__, + asoc, + NIP6(from_addr.v6.sin6_addr)); } else { - if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address " - NIPQUAD_FMT "\n", - __FUNCTION__, - asoc, - NIPQUAD(from_addr.v4.sin_addr.s_addr)); + printk(KERN_WARNING + "%s association %p could not find address " + NIPQUAD_FMT "\n", + __FUNCTION__, + asoc, + NIPQUAD(from_addr.v4.sin_addr.s_addr)); } return SCTP_DISPOSITION_DISCARD; } @@ -3363,7 +3362,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, abort = sctp_make_abort(asoc, asconf_ack, sizeof(sctp_errhdr_t)); if (abort) { - sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0); + sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, NULL, 0); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); } @@ -3393,7 +3392,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, abort = sctp_make_abort(asoc, asconf_ack, sizeof(sctp_errhdr_t)); if (abort) { - sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0); + sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, NULL, 0); sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 33354602ae86..01c6364245b7 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -353,7 +353,6 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) * The function sctp_get_port_local() does duplicate address * detection. */ - addr->v4.sin_port = htons(snum); if ((ret = sctp_get_port_local(sk, addr))) { if (ret == (long) sk) { /* This endpoint has a conflicting address. */ @@ -5203,7 +5202,6 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) sctp_unhash_endpoint(ep); sk->sk_state = SCTP_SS_CLOSED; - return 0; } /* Return if we are already listening. */ @@ -5251,7 +5249,6 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog) sctp_unhash_endpoint(ep); sk->sk_state = SCTP_SS_CLOSED; - return 0; } if (sctp_sstate(sk, LISTENING)) diff --git a/trunk/net/sctp/ulpqueue.c b/trunk/net/sctp/ulpqueue.c index fa0ba2a5564e..34eb977a204d 100644 --- a/trunk/net/sctp/ulpqueue.c +++ b/trunk/net/sctp/ulpqueue.c @@ -659,46 +659,6 @@ static inline struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *u return retval; } -/* - * Flush out stale fragments from the reassembly queue when processing - * a Forward TSN. - * - * RFC 3758, Section 3.6 - * - * After receiving and processing a FORWARD TSN, the data receiver MUST - * take cautions in updating its re-assembly queue. The receiver MUST - * remove any partially reassembled message, which is still missing one - * or more TSNs earlier than or equal to the new cumulative TSN point. - * In the event that the receiver has invoked the partial delivery API, - * a notification SHOULD also be generated to inform the upper layer API - * that the message being partially delivered will NOT be completed. - */ -void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 fwd_tsn) -{ - struct sk_buff *pos, *tmp; - struct sctp_ulpevent *event; - __u32 tsn; - - if (skb_queue_empty(&ulpq->reasm)) - return; - - skb_queue_walk_safe(&ulpq->reasm, pos, tmp) { - event = sctp_skb2event(pos); - tsn = event->tsn; - - /* Since the entire message must be abandoned by the - * sender (item A3 in Section 3.5, RFC 3758), we can - * free all fragments on the list that are less then - * or equal to ctsn_point - */ - if (TSN_lte(tsn, fwd_tsn)) { - __skb_unlink(pos, &ulpq->reasm); - sctp_ulpevent_free(event); - } else - break; - } -} - /* Helper function to gather skbs that have possibly become * ordered by an an incoming chunk. */ @@ -834,7 +794,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq, /* Helper function to gather skbs that have possibly become * ordered by forward tsn skipping their dependencies. */ -static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid) +static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq) { struct sk_buff *pos, *tmp; struct sctp_ulpevent *cevent; @@ -853,40 +813,31 @@ static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid) csid = cevent->stream; cssn = cevent->ssn; - /* Have we gone too far? */ - if (csid > sid) + if (cssn != sctp_ssn_peek(in, csid)) break; - /* Have we not gone far enough? */ - if (csid < sid) - continue; - - /* see if this ssn has been marked by skipping */ - if (!SSN_lt(cssn, sctp_ssn_peek(in, csid))) - break; + /* Found it, so mark in the ssnmap. */ + sctp_ssn_next(in, csid); __skb_unlink(pos, &ulpq->lobby); - if (!event) + if (!event) { /* Create a temporary list to collect chunks on. */ event = sctp_skb2event(pos); - - /* Attach all gathered skbs to the event. */ - __skb_queue_tail(&temp, pos); + __skb_queue_tail(&temp, sctp_event2skb(event)); + } else { + /* Attach all gathered skbs to the event. */ + __skb_queue_tail(&temp, pos); + } } /* Send event to the ULP. 'event' is the sctp_ulpevent for * very first SKB on the 'temp' list. */ - if (event) { - /* see if we have more ordered that we can deliver */ - sctp_ulpq_retrieve_ordered(ulpq, event); + if (event) sctp_ulpq_tail_event(ulpq, event); - } } -/* Skip over an SSN. This is used during the processing of - * Forwared TSN chunk to skip over the abandoned ordered data - */ +/* Skip over an SSN. */ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn) { struct sctp_stream *in; @@ -904,7 +855,7 @@ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn) /* Go find any other chunks that were waiting for * ordering and deliver them if needed. */ - sctp_ulpq_reap_ordered(ulpq, sid); + sctp_ulpq_reap_ordered(ulpq); return; }