summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_usrreq.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-06-12 11:21:00 +0000
committerrrs <rrs@FreeBSD.org>2007-06-12 11:21:00 +0000
commit1cd5c5dd060ed74ed2778ad4f459ed32f0ad4a8a (patch)
tree8ceb26064a095a4ca496c0d65130e07c6bab67a1 /sys/netinet/sctp_usrreq.c
parent59136b3a6d401102fb2c9ec125e4155ad39526cf (diff)
downloadFreeBSD-src-1cd5c5dd060ed74ed2778ad4f459ed32f0ad4a8a.zip
FreeBSD-src-1cd5c5dd060ed74ed2778ad4f459ed32f0ad4a8a.tar.gz
- Restructure so bindx functions are not done inline to socket option
but are a seperate call that can be re-used if needed. - 64 bit issues o re-arrange cookie so it is better 64 bit aligned o For wire level things we need the packed attribute.
Diffstat (limited to 'sys/netinet/sctp_usrreq.c')
-rw-r--r--sys/netinet/sctp_usrreq.c134
1 files changed, 8 insertions, 126 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 0bd92b3..bd26286 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -3498,140 +3498,22 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
case SCTP_BINDX_ADD_ADDR:
{
struct sctp_getaddresses *addrs;
- struct sockaddr *addr_touse;
- struct sockaddr_in sin;
- SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize);
-
- /* see if we're bound all already! */
- if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
- error = EINVAL;
- break;
- }
- /* Is the VRF one we have */
- addr_touse = addrs->addr;
-#if defined(INET6)
- if (addrs->addr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
-
- if (addrs->addr->sa_len != sizeof(struct sockaddr_in6)) {
- error = EINVAL;
- break;
- }
- sin6 = (struct sockaddr_in6 *)addr_touse;
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- in6_sin6_2_sin(&sin, sin6);
- addr_touse = (struct sockaddr *)&sin;
- }
- }
-#endif
- if (addrs->addr->sa_family == AF_INET) {
- if (addrs->addr->sa_len != sizeof(struct sockaddr_in)) {
- error = EINVAL;
- break;
- }
- }
- if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
-
- if (p == NULL) {
- /* Can't get proc for Net/Open BSD */
- error = EINVAL;
- break;
- }
- error = sctp_inpcb_bind(so, addr_touse, p);
- break;
- }
- /*
- * No locks required here since bind and mgmt_ep_sa
- * all do their own locking. If we do something for
- * the FIX: below we may need to lock in that case.
- */
- if (addrs->sget_assoc_id == 0) {
- /* add the address */
- struct sctp_inpcb *lep;
-
- ((struct sockaddr_in *)addr_touse)->sin_port = inp->sctp_lport;
- lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id);
- if (lep != NULL) {
- /*
- * We must decrement the refcount
- * since we have the ep already and
- * are binding. No remove going on
- * here.
- */
- SCTP_INP_DECR_REF(inp);
- }
- if (lep == inp) {
- /* already bound to it.. ok */
- break;
- } else if (lep == NULL) {
- ((struct sockaddr_in *)addr_touse)->sin_port = 0;
- error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
- SCTP_ADD_IP_ADDRESS, vrf_id);
- } else {
- error = EADDRINUSE;
- }
- if (error)
- break;
-
- } else {
- /*
- * FIX: decide whether we allow assoc based
- * bindx
- */
- }
+ SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses,
+ optsize);
+ sctp_bindx_add_address(so, inp, addrs->addr,
+ addrs->sget_assoc_id, vrf_id,
+ &error, p);
}
break;
case SCTP_BINDX_REM_ADDR:
{
struct sctp_getaddresses *addrs;
- struct sockaddr *addr_touse;
- struct sockaddr_in sin;
SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize);
- /* see if we're bound all already! */
- if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
- error = EINVAL;
- break;
- }
- addr_touse = addrs->addr;
-#if defined(INET6)
- if (addrs->addr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
-
- if (addrs->addr->sa_len != sizeof(struct sockaddr_in6)) {
- error = EINVAL;
- break;
- }
- sin6 = (struct sockaddr_in6 *)addr_touse;
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- in6_sin6_2_sin(&sin, sin6);
- addr_touse = (struct sockaddr *)&sin;
- }
- }
-#endif
- if (addrs->addr->sa_family == AF_INET) {
- if (addrs->addr->sa_len != sizeof(struct sockaddr_in)) {
- error = EINVAL;
- break;
- }
- }
- /*
- * No lock required mgmt_ep_sa does its own locking.
- * If the FIX: below is ever changed we may need to
- * lock before calling association level binding.
- */
- if (addrs->sget_assoc_id == 0) {
- /* delete the address */
- error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
- SCTP_DEL_IP_ADDRESS,
- vrf_id);
- } else {
- /*
- * FIX: decide whether we allow assoc based
- * bindx
- */
- }
+ sctp_bindx_delete_address(so, inp, addrs->addr,
+ addrs->sget_assoc_id, vrf_id,
+ &error);
}
break;
default:
OpenPOWER on IntegriCloud