diff options
author | tuexen <tuexen@FreeBSD.org> | 2011-02-07 15:04:23 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2011-02-07 15:04:23 +0000 |
commit | 9ccaf288c9178d6dbdbb001ffec81fa6f7139f57 (patch) | |
tree | 3793c883577d61272e38191fd7538afba95a6038 | |
parent | 8ea2135428216d0aa78aa73b0611a2b0afeb4aa5 (diff) | |
download | FreeBSD-src-9ccaf288c9178d6dbdbb001ffec81fa6f7139f57.zip FreeBSD-src-9ccaf288c9178d6dbdbb001ffec81fa6f7139f57.tar.gz |
Fix bugs related to M_FLOWID:
* Store the flowid when receiving an SCTP/IPv6 packet.
* Store the flowid when receiving an SCTP packet with wrong CRC.
* Initilize flowid correctly.
* Put test code under INVARIANTS.
MFC after: 3 months.
-rw-r--r-- | sys/netinet/sctp_input.c | 10 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 14 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 12 | ||||
-rw-r--r-- | sys/netinet/sctp_structs.h | 2 | ||||
-rw-r--r-- | sys/netinet6/sctp6_usrreq.c | 12 |
5 files changed, 37 insertions, 13 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 8801a3f..016218b 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -2617,7 +2617,9 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, } if ((*netp != NULL) && (m->m_flags & M_FLOWID)) { (*netp)->flowid = m->m_pkthdr.flowid; +#ifdef INVARIANTS (*netp)->flowidset = 1; +#endif } /* * Ok, we built an association so confirm the address we sent the @@ -5815,6 +5817,12 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port) } net->port = port; } + if ((net != NULL) && (m->m_flags & M_FLOWID)) { + net->flowid = m->m_pkthdr.flowid; +#ifdef INVARIANTS + net->flowidset = 1; +#endif + } if ((inp) && (stcb)) { sctp_send_packet_dropped(stcb, net, m, iphlen, 1); sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); @@ -5846,7 +5854,9 @@ sctp_skip_csum_4: } if ((net != NULL) && (m->m_flags & M_FLOWID)) { net->flowid = m->m_pkthdr.flowid; +#ifdef INVARIANTS net->flowidset = 1; +#endif } /* inp's ref-count increased && stcb locked */ if (inp == NULL) { diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index fc04190..96c0393 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3485,12 +3485,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_BUF_NEXT(newm) = m; m = newm; if (net != NULL) { +#ifdef INVARIANTS if (net->flowidset == 0) { - net->flowid = stcb->asoc.my_vtag ^ - ntohs(stcb->rport) ^ - ntohs(stcb->sctp_ep->sctp_lport); - net->flowidset = 1; + panic("Flow ID not set"); } +#endif m->m_pkthdr.flowid = net->flowid; m->m_flags |= M_FLOWID; } else { @@ -3821,12 +3820,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTP_BUF_NEXT(newm) = m; m = newm; if (net != NULL) { +#ifdef INVARIANTS if (net->flowidset == 0) { - net->flowid = stcb->asoc.my_vtag ^ - ntohs(stcb->rport) ^ - ntohs(stcb->sctp_ep->sctp_lport); - net->flowidset = 1; + panic("Flow ID not set"); } +#endif m->m_pkthdr.flowid = net->flowid; m->m_flags |= M_FLOWID; } else { diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 60a9656..b06e87d 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -3962,6 +3962,13 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, net->find_pseudo_cumack = 1; net->find_rtx_pseudo_cumack = 1; net->src_addr_selected = 0; + /* Choose an initial flowid. */ + net->flowid = stcb->asoc.my_vtag ^ + ntohs(stcb->rport) ^ + ntohs(stcb->sctp_ep->sctp_lport); +#ifdef INVARIANTS + net->flowidset = 1; +#endif netfirst = TAILQ_FIRST(&stcb->asoc.nets); if (net->ro.ro_rt == NULL) { /* Since we have no route put it at the back */ @@ -4035,11 +4042,6 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next); } - /* Choose an initial flowid. */ - net->flowid = stcb->asoc.my_vtag ^ - ntohs(stcb->rport) ^ - ntohs(stcb->sctp_ep->sctp_lport); - net->flowidset = 1; return (0); } diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 09aba90..d5cade7 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -351,7 +351,9 @@ struct sctp_nets { /* JRS - struct used in HTCP algorithm */ struct htcp htcp_ca; uint32_t flowid; +#ifdef INVARIANTS uint8_t flowidset; +#endif }; diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index ecfcb63..fd71dec 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -170,6 +170,12 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto) } net->port = port; } + if ((net != NULL) && (m->m_flags & M_FLOWID)) { + net->flowid = m->m_pkthdr.flowid; +#ifdef INVARIANTS + net->flowidset = 1; +#endif + } /* in6p's ref-count increased && stcb locked */ if ((in6p) && (stcb)) { sctp_send_packet_dropped(stcb, net, m, iphlen, 1); @@ -198,6 +204,12 @@ sctp_skip_csum: } net->port = port; } + if ((net != NULL) && (m->m_flags & M_FLOWID)) { + net->flowid = m->m_pkthdr.flowid; +#ifdef INVARIANTS + net->flowidset = 1; +#endif + } /* in6p's ref-count increased */ if (in6p == NULL) { struct sctp_init_chunk *init_chk, chunk_buf; |