summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2013-02-09 17:26:14 +0000
committertuexen <tuexen@FreeBSD.org>2013-02-09 17:26:14 +0000
commit026c1e8b1a1c4bee198b507e5bbd7ecde48cf5af (patch)
tree2cf33d91d2d068193e3685d2edb621e6e132dcd2
parent4c7dca13e4e6734c0970e0f3d3a7b02ff879ae72 (diff)
downloadFreeBSD-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.h2
-rw-r--r--sys/netinet/sctp_asconf.c30
-rw-r--r--sys/netinet/sctp_input.c12
-rw-r--r--sys/netinet/sctp_output.c178
-rw-r--r--sys/netinet/sctp_output.h8
-rw-r--r--sys/netinet/sctp_pcb.c89
-rw-r--r--sys/netinet/sctp_structs.h12
-rw-r--r--sys/netinet/sctp_sysctl.c30
-rw-r--r--sys/netinet/sctp_usrreq.c62
-rw-r--r--sys/netinet/sctputil.c125
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) {
OpenPOWER on IntegriCloud