sctp6_usrreq.c (236087) | sctp6_usrreq.c (237049) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 236087 2012-05-26 09:16:33Z tuexen $"); | 34__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 237049 2012-06-14 06:54:48Z tuexen $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctp_var.h> 41#if defined(INET6) 42#include <netinet6/sctp6_var.h> --- 36 unchanged lines hidden (view full) --- 79 struct inpcb *in6p_ip; 80 81#endif 82 struct sctp_chunkhdr *ch; 83 int length, offset, iphlen; 84 uint8_t ecn_bits; 85 struct sctp_tcb *stcb = NULL; 86 int pkt_len = 0; | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctp_var.h> 41#if defined(INET6) 42#include <netinet6/sctp6_var.h> --- 36 unchanged lines hidden (view full) --- 79 struct inpcb *in6p_ip; 80 81#endif 82 struct sctp_chunkhdr *ch; 83 int length, offset, iphlen; 84 uint8_t ecn_bits; 85 struct sctp_tcb *stcb = NULL; 86 int pkt_len = 0; |
87 uint32_t mflowid; 88 uint8_t use_mflowid; |
|
87 88#if !defined(SCTP_WITH_NO_CSUM) 89 uint32_t check, calc_check; 90 91#endif 92 int off = *offp; 93 uint16_t port = 0; 94 95 /* get the VRF and table id's */ 96 if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { 97 SCTP_RELEASE_PKT(*i_pak); 98 return (-1); 99 } 100 m = SCTP_HEADER_TO_CHAIN(*i_pak); 101 pkt_len = SCTP_HEADER_LEN((*i_pak)); 102 103#ifdef SCTP_PACKET_LOGGING 104 sctp_packet_log(m, pkt_len); 105#endif | 89 90#if !defined(SCTP_WITH_NO_CSUM) 91 uint32_t check, calc_check; 92 93#endif 94 int off = *offp; 95 uint16_t port = 0; 96 97 /* get the VRF and table id's */ 98 if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { 99 SCTP_RELEASE_PKT(*i_pak); 100 return (-1); 101 } 102 m = SCTP_HEADER_TO_CHAIN(*i_pak); 103 pkt_len = SCTP_HEADER_LEN((*i_pak)); 104 105#ifdef SCTP_PACKET_LOGGING 106 sctp_packet_log(m, pkt_len); 107#endif |
108 if (m->m_flags & M_FLOWID) { 109 mflowid = m->m_pkthdr.flowid; 110 use_mflowid = 1; 111 } else { 112 mflowid = 0; 113 use_mflowid = 0; 114 } |
|
106 ip6 = mtod(m, struct ip6_hdr *); 107 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */ 108 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off, 109 (int)(sizeof(*sh) + sizeof(*ch))); 110 if (sh == NULL) { 111 SCTP_STAT_INCR(sctps_hdrops); 112 return (IPPROTO_DONE); 113 } --- 45 unchanged lines hidden (view full) --- 159 stcb = sctp_findassociation_addr(m, offset - sizeof(*ch), 160 sh, ch, &in6p, &net, vrf_id); 161 if ((net) && (port)) { 162 if (net->port == 0) { 163 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 164 } 165 net->port = port; 166 } | 115 ip6 = mtod(m, struct ip6_hdr *); 116 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */ 117 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off, 118 (int)(sizeof(*sh) + sizeof(*ch))); 119 if (sh == NULL) { 120 SCTP_STAT_INCR(sctps_hdrops); 121 return (IPPROTO_DONE); 122 } --- 45 unchanged lines hidden (view full) --- 168 stcb = sctp_findassociation_addr(m, offset - sizeof(*ch), 169 sh, ch, &in6p, &net, vrf_id); 170 if ((net) && (port)) { 171 if (net->port == 0) { 172 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 173 } 174 net->port = port; 175 } |
167 if ((net != NULL) && (m->m_flags & M_FLOWID)) { 168 net->flowid = m->m_pkthdr.flowid; | 176 if ((net != NULL) && (use_mflowid != 0)) { 177 net->flowid = mflowid; |
169#ifdef INVARIANTS 170 net->flowidset = 1; 171#endif 172 } 173 /* in6p's ref-count increased && stcb locked */ 174 if ((in6p) && (stcb)) { 175 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 176 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); --- 16 unchanged lines hidden (view full) --- 193 stcb = sctp_findassociation_addr(m, offset - sizeof(*ch), 194 sh, ch, &in6p, &net, vrf_id); 195 if ((net) && (port)) { 196 if (net->port == 0) { 197 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 198 } 199 net->port = port; 200 } | 178#ifdef INVARIANTS 179 net->flowidset = 1; 180#endif 181 } 182 /* in6p's ref-count increased && stcb locked */ 183 if ((in6p) && (stcb)) { 184 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 185 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); --- 16 unchanged lines hidden (view full) --- 202 stcb = sctp_findassociation_addr(m, offset - sizeof(*ch), 203 sh, ch, &in6p, &net, vrf_id); 204 if ((net) && (port)) { 205 if (net->port == 0) { 206 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 207 } 208 net->port = port; 209 } |
201 if ((net != NULL) && (m->m_flags & M_FLOWID)) { 202 net->flowid = m->m_pkthdr.flowid; | 210 if ((net != NULL) && (use_mflowid != 0)) { 211 net->flowid = mflowid; |
203#ifdef INVARIANTS 204 net->flowidset = 1; 205#endif 206 } 207 /* in6p's ref-count increased */ 208 if (in6p == NULL) { 209 struct sctp_init_chunk *init_chk, chunk_buf; 210 --- 8 unchanged lines hidden (view full) --- 219 iphlen + sizeof(*sh), sizeof(*init_chk), 220 (uint8_t *) & chunk_buf); 221 if (init_chk) 222 sh->v_tag = init_chk->init.initiate_tag; 223 else 224 sh->v_tag = 0; 225 } 226 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { | 212#ifdef INVARIANTS 213 net->flowidset = 1; 214#endif 215 } 216 /* in6p's ref-count increased */ 217 if (in6p == NULL) { 218 struct sctp_init_chunk *init_chk, chunk_buf; 219 --- 8 unchanged lines hidden (view full) --- 228 iphlen + sizeof(*sh), sizeof(*init_chk), 229 (uint8_t *) & chunk_buf); 230 if (init_chk) 231 sh->v_tag = init_chk->init.initiate_tag; 232 else 233 sh->v_tag = 0; 234 } 235 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { |
227 sctp_send_shutdown_complete2(m, sh, vrf_id, port); | 236 sctp_send_shutdown_complete2(m, sh, 237 use_mflowid, mflowid, 238 vrf_id, port); |
228 goto bad; 229 } 230 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 231 goto bad; 232 } 233 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 234 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 235 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 236 (ch->chunk_type != SCTP_INIT))) { | 239 goto bad; 240 } 241 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 242 goto bad; 243 } 244 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 245 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 246 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 247 (ch->chunk_type != SCTP_INIT))) { |
237 sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port); | 248 sctp_send_abort(m, iphlen, sh, 0, NULL, 249 use_mflowid, mflowid, 250 vrf_id, port); |
238 } 239 } 240 goto bad; 241 } else if (stcb == NULL) { 242 refcount_up = 1; 243 } 244#ifdef IPSEC 245 /* --- 13 unchanged lines hidden (view full) --- 259 offset -= sizeof(*ch); 260 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 261 262 /* Length now holds the total packet length payload + iphlen */ 263 length = ntohs(ip6->ip6_plen) + iphlen; 264 265 /* sa_ignore NO_NULL_CHK */ 266 sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, | 251 } 252 } 253 goto bad; 254 } else if (stcb == NULL) { 255 refcount_up = 1; 256 } 257#ifdef IPSEC 258 /* --- 13 unchanged lines hidden (view full) --- 272 offset -= sizeof(*ch); 273 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 274 275 /* Length now holds the total packet length payload + iphlen */ 276 length = ntohs(ip6->ip6_plen) + iphlen; 277 278 /* sa_ignore NO_NULL_CHK */ 279 sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, |
267 in6p, stcb, net, ecn_bits, vrf_id, port); | 280 in6p, stcb, net, ecn_bits, 281 use_mflowid, mflowid, 282 vrf_id, port); |
268 /* inp's ref-count reduced && stcb unlocked */ 269 /* XXX this stuff below gets moved to appropriate parts later... */ 270 if (m) 271 sctp_m_freem(m); 272 if ((in6p) && refcount_up) { 273 /* reduce ref-count */ 274 SCTP_INP_WLOCK(in6p); 275 SCTP_INP_DECR_REF(in6p); --- 1066 unchanged lines hidden --- | 283 /* inp's ref-count reduced && stcb unlocked */ 284 /* XXX this stuff below gets moved to appropriate parts later... */ 285 if (m) 286 sctp_m_freem(m); 287 if ((in6p) && refcount_up) { 288 /* reduce ref-count */ 289 SCTP_INP_WLOCK(in6p); 290 SCTP_INP_DECR_REF(in6p); --- 1066 unchanged lines hidden --- |