summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2011-02-07 15:04:23 +0000
committertuexen <tuexen@FreeBSD.org>2011-02-07 15:04:23 +0000
commit9ccaf288c9178d6dbdbb001ffec81fa6f7139f57 (patch)
tree3793c883577d61272e38191fd7538afba95a6038
parent8ea2135428216d0aa78aa73b0611a2b0afeb4aa5 (diff)
downloadFreeBSD-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.c10
-rw-r--r--sys/netinet/sctp_output.c14
-rw-r--r--sys/netinet/sctp_pcb.c12
-rw-r--r--sys/netinet/sctp_structs.h2
-rw-r--r--sys/netinet6/sctp6_usrreq.c12
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;
OpenPOWER on IntegriCloud