summaryrefslogtreecommitdiff
path: root/netinet/sctp_asconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'netinet/sctp_asconf.c')
-rwxr-xr-xnetinet/sctp_asconf.c140
1 files changed, 59 insertions, 81 deletions
diff --git a/netinet/sctp_asconf.c b/netinet/sctp_asconf.c
index 0f35ae1..a0d5cee 100755
--- a/netinet/sctp_asconf.c
+++ b/netinet/sctp_asconf.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 271228 2014-09-07 17:07:19Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -153,7 +153,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
{
struct sctp_nets *net;
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -177,7 +177,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -186,7 +186,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -211,7 +211,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -307,7 +307,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -331,7 +331,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -340,7 +340,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -362,7 +362,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -429,7 +429,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
aparam_length);
} else {
if (response_required) {
- m_reply = sctp_asconf_success_response(aph->correlation_id);
+ m_reply = sctp_asconf_success_response(aph->correlation_id);
}
/* notify upper layer */
sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
@@ -443,7 +443,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -466,7 +466,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -475,7 +475,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -495,7 +495,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -552,11 +552,11 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
are transmitted to the new primary destination. (by micchie)
*/
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
+ SCTP_MOBILITY_BASE) ||
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) &&
+ SCTP_MOBILITY_FASTHANDOFF)) &&
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_PRIM_DELETED) &&
+ SCTP_MOBILITY_PRIM_DELETED) &&
(stcb->asoc.primary_destination->dest_state &
SCTP_ADDR_UNCONFIRMED) == 0) {
@@ -731,13 +731,11 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
}
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_add_ip(src, aph, stcb,
(cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
cnt++;
break;
case SCTP_DEL_IP_ADDRESS:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
error);
break;
@@ -745,7 +743,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
/* not valid in an ASCONF chunk */
break;
case SCTP_SET_PRIM_ADDR:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_set_primary(src, aph,
stcb, error);
break;
@@ -936,8 +933,6 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
void
sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
{
- /* mark peer as ASCONF incapable */
- stcb->asoc.peer_supports_asconf = 0;
/*
* clear out any existing asconfs going out
*/
@@ -1099,7 +1094,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
}
/* Retransmit unacknowledged DATA chunks immediately */
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_net_immediate_retrans(stcb, net);
}
/* also, SET PRIMARY is maybe already sent */
@@ -1157,7 +1152,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
continue;
/* Retransmit unacknowledged DATA chunks immediately */
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_net_immediate_retrans(stcb, net);
}
/* Send SET PRIMARY for this new address */
@@ -1193,9 +1188,9 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
+ SCTP_MOBILITY_BASE) ||
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_path_check_and_react(stcb, addr);
return;
}
@@ -1281,7 +1276,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
+ sin6 = &ifa->address.sin6;
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1296,7 +1291,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1348,7 +1343,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
int pending_delete_queued = 0;
/* see if peer supports ASCONF */
- if (stcb->asoc.peer_supports_asconf == 0) {
+ if (stcb->asoc.asconf_supported == 0) {
return (-1);
}
@@ -1440,7 +1435,7 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
return (-1);
}
/* see if peer supports ASCONF */
- if (stcb->asoc.peer_supports_asconf == 0) {
+ if (stcb->asoc.asconf_supported == 0) {
return (-1);
}
/* make sure the request isn't already in the queue */
@@ -1560,7 +1555,7 @@ sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
* notifications based on the error response
*/
static void
-sctp_asconf_process_error(struct sctp_tcb *stcb,
+sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
struct sctp_asconf_paramhdr *aph)
{
struct sctp_error_cause *eh;
@@ -1598,10 +1593,7 @@ sctp_asconf_process_error(struct sctp_tcb *stcb,
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
case SCTP_DEL_IP_ADDRESS:
- stcb->asoc.peer_supports_asconf = 0;
- break;
case SCTP_SET_PRIM_ADDR:
- stcb->asoc.peer_supports_asconf = 0;
break;
default:
break;
@@ -1637,8 +1629,6 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_param_ack: set primary IP address\n");
/* nothing to do... peer may start using this addr */
- if (flag == 0)
- stcb->asoc.peer_supports_asconf = 0;
break;
default:
/* should NEVER happen */
@@ -1656,11 +1646,11 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
* cleanup from a bad asconf ack parameter
*/
static void
-sctp_asconf_ack_clear(struct sctp_tcb *stcb)
+sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
{
/* assume peer doesn't really know how to do asconfs */
- stcb->asoc.peer_supports_asconf = 0;
/* XXX we could free the pending queue here */
+
}
void
@@ -1950,7 +1940,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
return;
@@ -1983,7 +1973,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
SCTP_IPV6_V6ONLY(inp6))
return;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
return;
@@ -2003,7 +1993,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* queue an asconf for this address add/delete */
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
/* does the peer do asconf? */
- if (stcb->asoc.peer_supports_asconf) {
+ if (stcb->asoc.asconf_supported) {
/* queue an asconf for this addr */
status = sctp_asconf_queue_add(stcb, ifa, type);
@@ -2141,7 +2131,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
else
continue;
}
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
continue;
@@ -2177,7 +2167,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
SCTP_IPV6_V6ONLY(inp6))
continue;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
continue;
@@ -2257,7 +2247,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
/* queue an asconf for this address add/delete */
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
- stcb->asoc.peer_supports_asconf) {
+ stcb->asoc.asconf_supported == 1) {
/* queue an asconf for this addr */
status = sctp_asconf_queue_add(stcb, ifa, type);
/*
@@ -2308,7 +2298,7 @@ sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
int32_t
sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
{
- uint32_t vrf_id;
+ uint32_t vrf_id;
struct sctp_ifa *ifa;
/* find the ifa for the desired set primary */
@@ -2496,7 +2486,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
if (stcb->asoc.scope.ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* skip unspecifed addresses */
continue;
@@ -2530,7 +2520,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
continue;
}
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
continue;
@@ -2798,15 +2788,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
struct sctp_paramhdr tmp_param, *ph;
uint16_t plen, ptype;
struct sctp_ifa *sctp_ifa;
+ union sctp_sockstore store;
#ifdef INET6
struct sctp_ipv6addr_param addr6_store;
- struct sockaddr_in6 sin6;
#endif
#ifdef INET
struct sctp_ipv4addr_param addr4_store;
- struct sockaddr_in sin;
#endif
- struct sockaddr *sa;
uint32_t vrf_id;
SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
@@ -2819,25 +2807,6 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
if ((offset + sizeof(struct sctp_paramhdr)) > length) {
return;
}
- /* init the addresses */
-#ifdef INET6
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
-#ifdef HAVE_SIN6_LEN
- sin6.sin6_len = sizeof(sin6);
-#endif
- sin6.sin6_port = stcb->rport;
-#endif
-
-#ifdef INET
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
-#ifdef HAVE_SIN_LEN
- sin.sin_len = sizeof(sin);
-#endif
- sin.sin_port = stcb->rport;
-#endif
-
/* go through the addresses in the init-ack */
ph = (struct sctp_paramhdr *)
sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
@@ -2860,9 +2829,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
a6p == NULL) {
return;
}
- memcpy(&sin6.sin6_addr, a6p->addr,
- sizeof(struct in6_addr));
- sa = (struct sockaddr *)&sin6;
+ memset(&store, 0, sizeof(union sctp_sockstore));
+ store.sin6.sin6_family = AF_INET6;
+#ifdef HAVE_SIN6_LEN
+ store.sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ store.sin6.sin6_port = stcb->rport;
+ memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
break;
}
#endif
@@ -2879,8 +2852,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
a4p == NULL) {
return;
}
- sin.sin_addr.s_addr = a4p->addr;
- sa = (struct sockaddr *)&sin;
+ memset(&store, 0, sizeof(union sctp_sockstore));
+ store.sin.sin_family = AF_INET;
+#ifdef HAVE_SIN_LEN
+ store.sin.sin_len = sizeof(struct sockaddr_in);
+#endif
+ store.sin.sin_port = stcb->rport;
+ store.sin.sin_addr.s_addr = a4p->addr;
break;
}
#endif
@@ -2894,7 +2872,7 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
} else {
vrf_id = SCTP_DEFAULT_VRFID;
}
- sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
+ sctp_ifa = sctp_find_ifa_by_addr(&store.sa, vrf_id,
SCTP_ADDR_NOT_LOCKED);
if (sctp_ifa == NULL) {
/* address doesn't exist anymore */
@@ -2903,9 +2881,9 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
/* are ASCONFs allowed ? */
if ((sctp_is_feature_on(stcb->sctp_ep,
SCTP_PCB_FLAGS_DO_ASCONF)) &&
- stcb->asoc.peer_supports_asconf) {
+ stcb->asoc.asconf_supported) {
/* queue an ASCONF DEL_IP_ADDRESS */
- status = sctp_asconf_queue_sa_delete(stcb, sa);
+ status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
/*
* if queued ok, and in correct state, send
* out the ASCONF.
@@ -2939,7 +2917,7 @@ next_addr:
if ((offset + sizeof(struct sctp_paramhdr)) > length)
return;
ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
- sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
+ sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
} /* while */
}
@@ -3151,7 +3129,7 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
- sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
+ sin = &sctp_ifa->address.sin;
#if defined(__FreeBSD__)
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
&sin->sin_addr) != 0) {
@@ -3167,7 +3145,7 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
#endif
#ifdef INET6
case AF_INET6:
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
+ sin6 = &sctp_ifa->address.sin6;
#if defined(__FreeBSD__)
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
&sin6->sin6_addr) != 0) {
@@ -3250,7 +3228,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
#endif
if (sctp_ifap) {
ifa = sctp_ifap;
- } else if (type == SCTP_ADD_IP_ADDRESS) {
+ } else if (type == SCTP_ADD_IP_ADDRESS) {
/* For an add the address MUST be on the system */
ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
} else if (type == SCTP_DEL_IP_ADDRESS) {