summaryrefslogtreecommitdiff
path: root/sys/netinet/sctp_output.c
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2013-02-09 17:26:14 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2013-02-09 17:26:14 +0000
commita1cb341b5d8d84403ce327a15ac4cef64178a472 (patch)
tree2cf33d91d2d068193e3685d2edb621e6e132dcd2 /sys/netinet/sctp_output.c
parent8b3cc7155e60afc67f7bb576a63ded7b4318d762 (diff)
downloadsrc-test2-a1cb341b5d8d84403ce327a15ac4cef64178a472.tar.gz
src-test2-a1cb341b5d8d84403ce327a15ac4cef64178a472.zip
Notes
Diffstat (limited to 'sys/netinet/sctp_output.c')
-rw-r--r--sys/netinet/sctp_output.c178
1 files changed, 50 insertions, 128 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index a5a3e5a13002..222153219811 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) {