diff options
author | tuexen <tuexen@FreeBSD.org> | 2013-02-09 17:26:14 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2013-02-09 17:26:14 +0000 |
commit | 026c1e8b1a1c4bee198b507e5bbd7ecde48cf5af (patch) | |
tree | 2cf33d91d2d068193e3685d2edb621e6e132dcd2 | |
parent | 4c7dca13e4e6734c0970e0f3d3a7b02ff879ae72 (diff) | |
download | FreeBSD-src-026c1e8b1a1c4bee198b507e5bbd7ecde48cf5af.zip FreeBSD-src-026c1e8b1a1c4bee198b507e5bbd7ecde48cf5af.tar.gz |
Cleanup the handling of address scopes. Announce in the INIT/INIT-ACK
only the supported address types. While there, do some whitespace
cleanups.
MFC after: 1 week
-rw-r--r-- | sys/netinet/sctp.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_asconf.c | 30 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 12 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 178 | ||||
-rw-r--r-- | sys/netinet/sctp_output.h | 8 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 89 | ||||
-rw-r--r-- | sys/netinet/sctp_structs.h | 12 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.c | 30 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 62 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 125 |
10 files changed, 228 insertions, 320 deletions
diff --git a/sys/netinet/sctp.h b/sys/netinet/sctp.h index 669b02a..493e085 100644 --- a/sys/netinet/sctp.h +++ b/sys/netinet/sctp.h @@ -500,12 +500,12 @@ struct sctp_error_unrecognized_chunk { #define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000 #define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000 #define SCTP_PCB_FLAGS_SOCKET_CANT_READ 0x40000000 + /* flags to copy to new PCB */ #define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\ SCTP_PCB_FLAGS_WAKEINPUT|\ SCTP_PCB_FLAGS_BOUND_V6) - /* * PCB Features (in sctp_features bitmask) */ diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index 0b15cd4..32226d5 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -1916,7 +1916,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, return; } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - if (stcb->asoc.local_scope == 0) { + if (stcb->asoc.scope.local_scope == 0) { return; } /* is it the right link local scope? */ @@ -1924,7 +1924,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, return; } } - if (stcb->asoc.site_scope == 0 && + if (stcb->asoc.scope.site_scope == 0 && IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { return; } @@ -1948,7 +1948,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ return; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { return; } @@ -2106,7 +2106,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, continue; } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - if (stcb->asoc.local_scope == 0) { + if (stcb->asoc.scope.local_scope == 0) { continue; } /* is it the right link local scope? */ @@ -2135,7 +2135,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* we skip unspecifed addresses */ continue; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; } @@ -2198,13 +2198,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } } else { /* Need to check scopes for this guy */ - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } } @@ -2437,7 +2431,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) return (NULL); } LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { - if (stcb->asoc.loopback_scope == 0 && + if (stcb->asoc.scope.loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { /* Skip if loopback_scope not set */ continue; @@ -2446,7 +2440,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) switch (sctp_ifa->address.sa.sa_family) { #ifdef INET case AF_INET: - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&sctp_ifa->address.sa; @@ -2454,7 +2448,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) /* skip unspecifed addresses */ continue; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) continue; @@ -2473,7 +2467,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) #endif #ifdef INET6 case AF_INET6: - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { struct sockaddr_in6 *sin6; if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { @@ -2487,10 +2481,10 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked) */ continue; } - if (stcb->asoc.local_scope == 0 && + if (stcb->asoc.scope.local_scope == 0 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) continue; - if (stcb->asoc.site_scope == 0 && + if (stcb->asoc.scope.site_scope == 0 && IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) continue; diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 511c1e2..0528d3d 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -2130,13 +2130,13 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, asoc = &stcb->asoc; /* get scope variables out of cookie */ - asoc->ipv4_local_scope = cookie->ipv4_scope; - asoc->site_scope = cookie->site_scope; - asoc->local_scope = cookie->local_scope; - asoc->loopback_scope = cookie->loopback_scope; + asoc->scope.ipv4_local_scope = cookie->ipv4_scope; + asoc->scope.site_scope = cookie->site_scope; + asoc->scope.local_scope = cookie->local_scope; + asoc->scope.loopback_scope = cookie->loopback_scope; - if ((asoc->ipv4_addr_legal != cookie->ipv4_addr_legal) || - (asoc->ipv6_addr_legal != cookie->ipv6_addr_legal)) { + if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) || + (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) { struct mbuf *op_err; /* diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index a5a3e5a..2221532 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -1863,15 +1863,10 @@ struct sack_track sack_array[256] = { int sctp_is_address_in_scope(struct sctp_ifa *ifa, - int ipv4_addr_legal, - int ipv6_addr_legal, - int loopback_scope, - int ipv4_local_scope, - int local_scope SCTP_UNUSED,/* XXX */ - int site_scope, + struct sctp_scoping *scope, int do_update) { - if ((loopback_scope == 0) && + if ((scope->loopback_scope == 0) && (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) { /* * skip loopback if not in scope * @@ -1881,7 +1876,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa, switch (ifa->address.sa.sa_family) { #ifdef INET case AF_INET: - if (ipv4_addr_legal) { + if (scope->ipv4_addr_legal) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ifa->address.sin; @@ -1889,7 +1884,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa, /* not in scope , unspecified */ return (0); } - if ((ipv4_local_scope == 0) && + if ((scope->ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { /* private address not in scope */ return (0); @@ -1901,7 +1896,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa, #endif #ifdef INET6 case AF_INET6: - if (ipv6_addr_legal) { + if (scope->ipv6_addr_legal) { struct sockaddr_in6 *sin6; /* @@ -1924,7 +1919,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa, (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { return (0); } - if ((site_scope == 0) && + if ((scope->site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { return (0); } @@ -2063,13 +2058,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } - if (sctp_is_address_in_scope(sctp_ifap, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 1) == 0) { + if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) { continue; } cnt++; @@ -2099,12 +2088,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(sctp_ifap, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 0) == 0) { + scope, 0) == 0) { continue; } if ((chunk_len != NULL) && @@ -2157,12 +2141,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(laddr->ifa, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 1) == 0) { + scope, 1) == 0) { continue; } cnt++; @@ -2182,12 +2161,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(laddr->ifa, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 0) == 0) { + scope, 0) == 0) { continue; } if ((chunk_len != NULL) && @@ -2801,13 +2775,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, } #endif if (stcb) { - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -2853,13 +2821,7 @@ sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, continue; } if (stcb) { - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -3055,13 +3017,7 @@ again_with_private_addresses_allowed: continue; } if (stcb) { - if (sctp_is_address_in_scope(sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) { SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n"); sifa = NULL; continue; @@ -3108,13 +3064,7 @@ plan_d: if (sifa == NULL) continue; if (stcb) { - if (sctp_is_address_in_scope(sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) { sifa = NULL; continue; } @@ -3135,12 +3085,12 @@ plan_d: } } #ifdef INET - if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) { - stcb->asoc.ipv4_local_scope = 1; + if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) { + stcb->asoc.scope.ipv4_local_scope = 1; retried = 1; goto again_with_private_addresses_allowed; } else if (retried == 1) { - stcb->asoc.ipv4_local_scope = 0; + stcb->asoc.scope.ipv4_local_scope = 0; } #endif out: @@ -3169,12 +3119,7 @@ out: } if (stcb) { if (sctp_is_address_in_scope(tmp_sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -4595,7 +4540,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked #endif ) { - struct sctp_scoping scp; struct mbuf *m; struct sctp_nets *net; struct sctp_init_chunk *init; @@ -4675,37 +4619,29 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams); init->init.initial_tsn = htonl(stcb->asoc.init_seq_number); -#if defined(INET) || defined(INET6) - /* now the address restriction */ - /* XXX Should we take the address family of the socket into account? */ - sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len); - sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE); -#ifdef INET6 -#ifdef INET - /* we support 2 types: IPv4/IPv6 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + 2 * sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS); - sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS); - padding_len = 0; -#else - /* we support 1 type: IPv6 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS); - sup_addr->addr_type[1] = htons(0); /* this is the padding */ - padding_len = (uint16_t) sizeof(uint16_t); -#endif -#else - /* we support 1 type: IPv4 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS); - sup_addr->addr_type[1] = htons(0); /* this is the padding */ - padding_len = (uint16_t) sizeof(uint16_t); -#endif - chunk_len += parameter_len; -#endif + if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) { + uint8_t i; + + parameter_len = (uint16_t) sizeof(struct sctp_paramhdr); + if (stcb->asoc.scope.ipv4_addr_legal) { + parameter_len += (uint16_t) sizeof(uint16_t); + } + if (stcb->asoc.scope.ipv6_addr_legal) { + parameter_len += (uint16_t) sizeof(uint16_t); + } + sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len); + sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE); + sup_addr->ph.param_length = htons(parameter_len); + i = 0; + if (stcb->asoc.scope.ipv4_addr_legal) { + sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS); + } + if (stcb->asoc.scope.ipv6_addr_legal) { + sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS); + } + padding_len = 4 - 2 * i; + chunk_len += parameter_len; + } /* Adaptation layer indication parameter */ /* XXX: Should we include this always? */ if (padding_len > 0) { @@ -4860,13 +4796,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked * we could just sifa in the address within the stcb. But for now * this is a quick hack to get the address stuff teased apart. */ - scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal; - scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal; - scp.loopback_scope = stcb->asoc.loopback_scope; - scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope; - scp.local_scope = stcb->asoc.local_scope; - scp.site_scope = stcb->asoc.site_scope; - sctp_add_addresses_to_i_ia(inp, stcb, &scp, m, cnt_inits_to, &padding_len, &chunk_len); + sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len); init->ch.chunk_length = htons(chunk_len); if (padding_len > 0) { @@ -5507,24 +5437,16 @@ do_a_abort: */ stc.site_scope = stc.local_scope = stc.loopback_scope = 0; if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - struct inpcb *in_inp; - - /* Its a V6 socket */ - in_inp = (struct inpcb *)inp; stc.ipv6_addr_legal = 1; - /* Now look at the binding flag to see if V4 will be legal */ - if (SCTP_IPV6_V6ONLY(in_inp) == 0) { - stc.ipv4_addr_legal = 1; - } else { - /* V4 addresses are NOT legal on the association */ + if (SCTP_IPV6_V6ONLY(inp)) { stc.ipv4_addr_legal = 0; + } else { + stc.ipv4_addr_legal = 1; } } else { - /* Its a V4 socket, no - V6 */ - stc.ipv4_addr_legal = 1; stc.ipv6_addr_legal = 0; + stc.ipv4_addr_legal = 1; } - #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE stc.ipv4_scope = 1; #else @@ -5629,10 +5551,10 @@ do_a_abort: #endif - stc.loopback_scope = asoc->loopback_scope; - stc.ipv4_scope = asoc->ipv4_local_scope; - stc.site_scope = asoc->site_scope; - stc.local_scope = asoc->local_scope; + stc.loopback_scope = asoc->scope.loopback_scope; + stc.ipv4_scope = asoc->scope.ipv4_local_scope; + stc.site_scope = asoc->scope.site_scope; + stc.local_scope = asoc->scope.local_scope; #ifdef INET6 /* Why do we not consider IPv4 LL addresses? */ TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) { diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index b62271b..59af5af 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -55,13 +55,9 @@ int sctp_is_addr_restricted(struct sctp_tcb *, struct sctp_ifa *); int sctp_is_address_in_scope(struct sctp_ifa *ifa, - int ipv4_addr_legal, - int ipv6_addr_legal, - int loopback_scope, - int ipv4_local_scope, - int local_scope, - int site_scope, + struct sctp_scoping *scope, int do_update); + int sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 9f817a3..4d01756 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -94,11 +94,10 @@ sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb) spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq); spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq); spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks); - SCTP_INP_INFO_RUNLOCK(); } -/* +/*- * Addresses are added to VRF's (Virtual Router's). For BSD we * have only the default VRF 0. We maintain a hash list of * VRF's. Each VRF has its own list of sctp_ifn's. Each of @@ -214,7 +213,6 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index) } - struct sctp_vrf * sctp_find_vrf(uint32_t vrf_id) { @@ -230,6 +228,7 @@ sctp_find_vrf(uint32_t vrf_id) return (NULL); } + void sctp_free_vrf(struct sctp_vrf *vrf) { @@ -245,6 +244,7 @@ sctp_free_vrf(struct sctp_vrf *vrf) } } + void sctp_free_ifn(struct sctp_ifn *sctp_ifnp) { @@ -258,6 +258,7 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp) } } + void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu) { @@ -283,6 +284,7 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap) } } + static void sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) { @@ -305,12 +307,13 @@ sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) sctp_free_ifn(sctp_ifnp); } + void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(vrf_id); @@ -348,12 +351,13 @@ out: SCTP_IPI_ADDR_RUNLOCK(); } + void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(vrf_id); @@ -391,6 +395,7 @@ out: SCTP_IPI_ADDR_RUNLOCK(); } + /*- * Add an ifa to an ifn. * Register the interface as necessary. @@ -428,6 +433,7 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap) } } + /*- * Remove an ifa from its ifn. * If no more addresses exist, remove the ifn too. Otherwise, re-register @@ -479,6 +485,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap) } } + struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, uint32_t ifn_type, const char *if_name, void *ifa, @@ -1027,6 +1034,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, return (NULL); } + static int sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) { @@ -1036,19 +1044,12 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) struct sctp_ifn *sctp_ifn; struct sctp_ifa *sctp_ifa; - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; - ipv4_addr_legal = ipv6_addr_legal = 0; - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) { - ipv4_addr_legal = 1; - } - } else { - ipv4_addr_legal = 1; - } + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(stcb->asoc.vrf_id); @@ -1183,6 +1184,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) return (0); } + /* * rules for use * @@ -1471,11 +1473,11 @@ null_return: return (NULL); } + /* * Find an association for a specific endpoint using the association id given * out in the COMM_UP notification */ - struct sctp_tcb * sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock) { @@ -1536,6 +1538,9 @@ sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int } +/* + * Endpoint probe expects that the INP_INFO is locked. + */ static struct sctp_inpcb * sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, uint16_t lport, uint32_t vrf_id) @@ -1552,12 +1557,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, struct sockaddr_in6 *intf_addr6; #endif - int fnd; - /* - * Endpoint probe expects that the INP_INFO is locked. - */ #ifdef INET sin = NULL; #endif @@ -1893,6 +1894,7 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, return (inp); } + /* * Find an association for an endpoint with the pointer to whom you want to * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may @@ -2144,6 +2146,7 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag return (NULL); } + /* * Find an association with the pointer to the inbound IP packet. This can be * a IPv4 or IPv6 packet. @@ -3743,13 +3746,13 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, stcb->ipv4_local_scope = 1; #else if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { - stcb->asoc.ipv4_local_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; } #endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ } else { /* Validate the address is in scope */ if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) && - (stcb->asoc.ipv4_local_scope == 0)) { + (stcb->asoc.scope.ipv4_local_scope == 0)) { addr_inscope = 0; } } @@ -3770,10 +3773,10 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, sin6->sin6_len = sizeof(struct sockaddr_in6); if (set_scope) { if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) { - stcb->asoc.loopback_scope = 1; - stcb->asoc.local_scope = 0; - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.loopback_scope = 1; + stcb->asoc.scope.local_scope = 0; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.site_scope = 1; } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { /* * If the new destination is a @@ -3785,26 +3788,26 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, * also be on our private network * for v4 too. */ - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.site_scope = 1; } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { /* * If the new destination is * SITE_LOCAL then we must have site * scope in common. */ - stcb->asoc.site_scope = 1; + stcb->asoc.scope.site_scope = 1; } } else { /* Validate the address is in scope */ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && - (stcb->asoc.loopback_scope == 0)) { + (stcb->asoc.scope.loopback_scope == 0)) { addr_inscope = 0; } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && - (stcb->asoc.local_scope == 0)) { + (stcb->asoc.scope.local_scope == 0)) { addr_inscope = 0; } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && - (stcb->asoc.site_scope == 0)) { + (stcb->asoc.scope.site_scope == 0)) { addr_inscope = 0; } } @@ -3839,10 +3842,10 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, } net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id); if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) { - stcb->asoc.loopback_scope = 1; - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.local_scope = 0; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.loopback_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.local_scope = 0; + stcb->asoc.scope.site_scope = 1; addr_inscope = 1; } net->failure_threshold = stcb->asoc.def_net_failure; @@ -6071,7 +6074,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, switch (sa->sa_family) { #ifdef INET case AF_INET: - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) { return (-1); } @@ -6080,7 +6083,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, #endif #ifdef INET6 case AF_INET6: - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) { return (-2); } @@ -6127,7 +6130,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, } #ifdef INET if (ptype == SCTP_IPV4_ADDRESS) { - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { struct sctp_ipv4addr_param *p4, p4_buf; /* ok get the v4 address and check/add */ @@ -6213,7 +6216,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, #endif #ifdef INET6 if (ptype == SCTP_IPV6_ADDRESS) { - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { /* ok get the v6 address and check/add */ struct sctp_ipv6addr_param *p6, p6_buf; diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 05d5fd1..bc18f0e 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -1177,17 +1177,7 @@ struct sctp_association { */ uint8_t peer_supports_pktdrop; - /* Do we allow V6/V4? */ - uint8_t ipv4_addr_legal; - uint8_t ipv6_addr_legal; - /* Address scoping flags */ - /* scope value for IPv4 */ - uint8_t ipv4_local_scope; - /* scope values for IPv6 */ - uint8_t local_scope; - uint8_t site_scope; - /* loopback scope */ - uint8_t loopback_scope; + struct sctp_scoping scope; /* flags to handle send alternate net tracking */ uint8_t used_alt_onsack; uint8_t used_alt_asconfack; diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index 14372bb..debb8cc 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -197,29 +197,29 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s /* Turn on all the appropriate scope */ if (stcb) { /* use association specific values */ - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; } else { - /* use generic values for endpoints */ + /* Use generic values for endpoints. */ loopback_scope = 1; ipv4_local_scope = 1; local_scope = 1; site_scope = 1; - } - - /* use only address families of interest */ - if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(inp)) { - ipv4_addr_legal = 0; + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { + ipv6_addr_legal = 1; + if (SCTP_IPV6_V6ONLY(inp)) { + ipv4_addr_legal = 0; + } else { + ipv4_addr_legal = 1; + } } else { + ipv6_addr_legal = 0; ipv4_addr_legal = 1; } - } else { - ipv4_addr_legal = 1; - ipv6_addr_legal = 0; } /* neither Mac OS X nor FreeBSD support mulitple routing functions */ diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 383ff0b..2b3bf79 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -1143,23 +1143,29 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, if (stcb) { /* Turn on all the appropriate scope */ - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; } else { - /* Turn on ALL scope, since we look at the EP */ - loopback_scope = ipv4_local_scope = local_scope = - site_scope = 1; - } - ipv4_addr_legal = ipv6_addr_legal = 0; - if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(inp) == 0) { + /* Use generic values for endpoints. */ + loopback_scope = 1; + ipv4_local_scope = 1; + local_scope = 1; + site_scope = 1; + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { + ipv6_addr_legal = 1; + if (SCTP_IPV6_V6ONLY(inp)) { + ipv4_addr_legal = 0; + } else { + ipv4_addr_legal = 1; + } + } else { + ipv6_addr_legal = 0; ipv4_addr_legal = 1; } - } else { - ipv4_addr_legal = 1; } vrf = sctp_find_vrf(vrf_id); if (vrf == NULL) { @@ -1298,8 +1304,21 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, } if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) continue; - - ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; + switch (laddr->ifa->address.sa.sa_family) { +#ifdef INET + case AF_INET: + ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; + break; +#endif +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; + break; +#endif + default: + /* TSNH */ + break; + } sas = (struct sockaddr_storage *)((caddr_t)sas + laddr->ifa->address.sa.sa_len); actual += laddr->ifa->address.sa.sa_len; @@ -5948,7 +5967,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) error = EINVAL; goto out_now; } -#endif /* INET6 */ +#endif if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == SCTP_PCB_FLAGS_UNBOUND) { /* Bind a ephemeral port */ @@ -6242,8 +6261,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr) return (ENOMEM); sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); - sin->sin_port = ((struct sockaddr_in *)&store)->sin_port; - sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr; + sin->sin_port = store.sin.sin_port; + sin->sin_addr = store.sin.sin_addr; *addr = (struct sockaddr *)sin; break; } @@ -6258,9 +6277,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr) return (ENOMEM); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(*sin6); - sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port; - - sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr; + sin6->sin6_port = store.sin6.sin6_port; + sin6->sin6_addr = store.sin6.sin6_addr; if ((error = sa6_recoverscope(sin6)) != 0) { SCTP_FREE_SONAME(sin6); return (error); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 1fadf6b..fe2b945 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -878,7 +878,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int ch } int -sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, +sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint32_t override_tag, uint32_t vrf_id) { struct sctp_association *asoc; @@ -899,23 +899,23 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, asoc = &stcb->asoc; /* init all variables to a known value. */ SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE); - asoc->max_burst = m->sctp_ep.max_burst; - asoc->fr_max_burst = m->sctp_ep.fr_max_burst; - asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); - asoc->cookie_life = m->sctp_ep.def_cookie_life; - asoc->sctp_cmt_on_off = m->sctp_cmt_on_off; - asoc->ecn_allowed = m->sctp_ecn_enable; + asoc->max_burst = inp->sctp_ep.max_burst; + asoc->fr_max_burst = inp->sctp_ep.fr_max_burst; + asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); + asoc->cookie_life = inp->sctp_ep.def_cookie_life; + asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off; + asoc->ecn_allowed = inp->sctp_ecn_enable; asoc->sctp_nr_sack_on_off = (uint8_t) SCTP_BASE_SYSCTL(sctp_nr_sack_on_off); asoc->sctp_cmt_pf = (uint8_t) 0; - asoc->sctp_frag_point = m->sctp_frag_point; - asoc->sctp_features = m->sctp_features; - asoc->default_dscp = m->sctp_ep.default_dscp; + asoc->sctp_frag_point = inp->sctp_frag_point; + asoc->sctp_features = inp->sctp_features; + asoc->default_dscp = inp->sctp_ep.default_dscp; #ifdef INET6 - if (m->sctp_ep.default_flowlabel) { - asoc->default_flowlabel = m->sctp_ep.default_flowlabel; + if (inp->sctp_ep.default_flowlabel) { + asoc->default_flowlabel = inp->sctp_ep.default_flowlabel; } else { - if (m->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) { - asoc->default_flowlabel = sctp_select_initial_TSN(&m->sctp_ep); + if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) { + asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep); asoc->default_flowlabel &= 0x000fffff; asoc->default_flowlabel |= 0x80000000; } else { @@ -927,11 +927,11 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, if (override_tag) { asoc->my_vtag = override_tag; } else { - asoc->my_vtag = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 1); + asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1); } /* Get the nonce tags */ - asoc->my_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0); - asoc->peer_vtag_nonce = sctp_select_a_tag(m, stcb->sctp_ep->sctp_lport, stcb->rport, 0); + asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); + asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); asoc->vrf_id = vrf_id; #ifdef SCTP_ASOCLOG_OF_TSNS @@ -948,7 +948,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, asoc->refcnt = 0; asoc->assoc_up_sent = 0; asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq = - sctp_select_initial_TSN(&m->sctp_ep); + sctp_select_initial_TSN(&inp->sctp_ep); asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1; /* we are optimisitic here */ asoc->peer_supports_pktdrop = 1; @@ -966,49 +966,42 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, /* here we are different, we hold the next one we expect */ asoc->str_reset_seq_in = asoc->last_acked_seq + 1; - asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max; - asoc->initial_rto = m->sctp_ep.initial_rto; + asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max; + asoc->initial_rto = inp->sctp_ep.initial_rto; - asoc->max_init_times = m->sctp_ep.max_init_times; - asoc->max_send_times = m->sctp_ep.max_send_times; - asoc->def_net_failure = m->sctp_ep.def_net_failure; - asoc->def_net_pf_threshold = m->sctp_ep.def_net_pf_threshold; + asoc->max_init_times = inp->sctp_ep.max_init_times; + asoc->max_send_times = inp->sctp_ep.max_send_times; + asoc->def_net_failure = inp->sctp_ep.def_net_failure; + asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold; asoc->free_chunk_cnt = 0; asoc->iam_blocking = 0; - asoc->context = m->sctp_context; - asoc->local_strreset_support = m->local_strreset_support; - asoc->def_send = m->def_send; - asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); - asoc->sack_freq = m->sctp_ep.sctp_sack_freq; + asoc->context = inp->sctp_context; + asoc->local_strreset_support = inp->local_strreset_support; + asoc->def_send = inp->def_send; + asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); + asoc->sack_freq = inp->sctp_ep.sctp_sack_freq; asoc->pr_sctp_cnt = 0; asoc->total_output_queue_size = 0; - if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - struct in6pcb *inp6; - - /* Its a V6 socket */ - inp6 = (struct in6pcb *)m; - asoc->ipv6_addr_legal = 1; - /* Now look at the binding flag to see if V4 will be legal */ - if (SCTP_IPV6_V6ONLY(inp6) == 0) { - asoc->ipv4_addr_legal = 1; + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { + asoc->scope.ipv6_addr_legal = 1; + if (SCTP_IPV6_V6ONLY(inp) == 0) { + asoc->scope.ipv4_addr_legal = 1; } else { - /* V4 addresses are NOT legal on the association */ - asoc->ipv4_addr_legal = 0; + asoc->scope.ipv4_addr_legal = 0; } } else { - /* Its a V4 socket, no - V6 */ - asoc->ipv4_addr_legal = 1; - asoc->ipv6_addr_legal = 0; + asoc->scope.ipv6_addr_legal = 0; + asoc->scope.ipv4_addr_legal = 1; } - asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(m->sctp_socket), SCTP_MINIMAL_RWND); - asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(m->sctp_socket); + asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND); + asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket); - asoc->smallest_mtu = m->sctp_frag_point; - asoc->minrto = m->sctp_ep.sctp_minrto; - asoc->maxrto = m->sctp_ep.sctp_maxrto; + asoc->smallest_mtu = inp->sctp_frag_point; + asoc->minrto = inp->sctp_ep.sctp_minrto; + asoc->maxrto = inp->sctp_ep.sctp_maxrto; asoc->locked_on_sending = NULL; asoc->stream_locked_on = 0; @@ -1025,20 +1018,20 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, /* Setup to fill the hb random cache at first HB */ asoc->hb_random_idx = 4; - asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time; + asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time; - stcb->asoc.congestion_control_module = m->sctp_ep.sctp_default_cc_module; - stcb->asoc.cc_functions = sctp_cc_functions[m->sctp_ep.sctp_default_cc_module]; + stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module; + stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module]; - stcb->asoc.stream_scheduling_module = m->sctp_ep.sctp_default_ss_module; - stcb->asoc.ss_functions = sctp_ss_functions[m->sctp_ep.sctp_default_ss_module]; + stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module; + stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module]; /* * Now the stream parameters, here we allocate space for all streams * that we request by default. */ asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams = - m->sctp_ep.pre_open_stream_count; + inp->sctp_ep.pre_open_stream_count; SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *, asoc->streamoutcnt * sizeof(struct sctp_stream_out), SCTP_M_STRMO); @@ -1093,7 +1086,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, TAILQ_INIT(&asoc->sent_queue); TAILQ_INIT(&asoc->reasmqueue); TAILQ_INIT(&asoc->resetHead); - asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome; + asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome; TAILQ_INIT(&asoc->asconf_queue); /* authentication fields */ asoc->authinfo.random = NULL; @@ -1104,7 +1097,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, asoc->authinfo.recv_keyid = 0; LIST_INIT(&asoc->shared_keys); asoc->marked_retrans = 0; - asoc->port = m->sctp_ep.port; + asoc->port = inp->sctp_ep.port; asoc->timoinit = 0; asoc->timodata = 0; asoc->timosack = 0; @@ -6621,20 +6614,12 @@ sctp_local_addr_count(struct sctp_tcb *stcb) int count = 0; /* Turn on all the appropriate scopes */ - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; - ipv4_addr_legal = ipv6_addr_legal = 0; - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) { - ipv4_addr_legal = 1; - } - } else { - ipv4_addr_legal = 1; - } - + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(stcb->asoc.vrf_id); if (vrf == NULL) { |