diff options
author | rrs <rrs@FreeBSD.org> | 2007-06-12 11:21:00 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-06-12 11:21:00 +0000 |
commit | 1cd5c5dd060ed74ed2778ad4f459ed32f0ad4a8a (patch) | |
tree | 8ceb26064a095a4ca496c0d65130e07c6bab67a1 /sys/netinet/sctp_usrreq.c | |
parent | 59136b3a6d401102fb2c9ec125e4155ad39526cf (diff) | |
download | FreeBSD-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.c | 134 |
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: |