-/*
- * User-protocol pru_peeloff callback.
- */
-static int
-mptcp_usr_peeloff(struct socket *mp_so, sae_associd_t aid, struct socket **psop)
-{
- struct mppcb *mpp = sotomppcb(mp_so);
- struct mptses *mpte;
- int error = 0;
-
- VERIFY(psop != NULL);
-
- if (mpp == NULL || mpp->mpp_state == MPPCB_STATE_DEAD) {
- error = EINVAL;
- goto out;
- }
- mpte = mptompte(mpp);
- VERIFY(mpte != NULL);
-
- error = mptcp_peeloff(mpte, aid, psop);
-out:
- return (error);
-}
-
-/*
- * Transform a previously connected TCP subflow connection which has
- * failed to negotiate MPTCP to its own socket which can be externalized
- * with a file descriptor. Valid only when the MPTCP socket is not
- * yet associated (MPTCP-level connection has not been established.)
- */
-static int
-mptcp_peeloff(struct mptses *mpte, sae_associd_t aid, struct socket **psop)
-{
- struct socket *so = NULL, *mp_so;
- struct mptsub *mpts;
- int error = 0;
-
- MPTE_LOCK_ASSERT_HELD(mpte); /* same as MP socket lock */
- mp_so = mpte->mpte_mppcb->mpp_socket;
-
- VERIFY(psop != NULL);
- *psop = NULL;
-
- DTRACE_MPTCP3(peeloff, struct mptses *, mpte, sae_associd_t, aid,
- struct socket *, mp_so);
-
- /* peeloff cannot happen after an association is established */
- if (mpte->mpte_associd != SAE_ASSOCID_ANY) {
- error = EINVAL;
- goto out;
- }
-
- if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
- error = EINVAL;
- goto out;
- }
-
- TAILQ_FOREACH(mpts, &mpte->mpte_subflows, mpts_entry) {
- MPTS_LOCK(mpts);
- if (mpts->mpts_flags & MPTSF_MP_CAPABLE) {
- panic("%s: so %p is MPTCP capable but mp_so %p "
- "aid is %d\n", __func__, so, mp_so,
- mpte->mpte_associd);
- /* NOTREACHED */
- }
- MPTS_ADDREF_LOCKED(mpts); /* for us */
- so = mpts->mpts_socket;
- VERIFY(so != NULL);
- /*
- * This subflow socket is about to be externalized; make it
- * appear as if it has the same properties as the MPTCP socket,
- * undo what's done earlier in mptcp_subflow_add().
- */
- mptcp_subflow_sopeeloff(mpte, mpts, so);
- MPTS_UNLOCK(mpts);
-
- mptcp_subflow_del(mpte, mpts, FALSE);
- MPTS_REMREF(mpts); /* ours */
- /*
- * XXX adi@apple.com
- *
- * Here we need to make sure the subflow socket is not
- * flow controlled; need to clear both INP_FLOW_CONTROLLED
- * and INP_FLOW_SUSPENDED on the subflow socket, since
- * we will no longer be monitoring its events.
- */
- break;
- }
-
- if (so == NULL) {
- error = EINVAL;
- goto out;
- }
- *psop = so;
-
- mptcplog((LOG_DEBUG, "MPTCP Socket: "
- "%s: mp_so 0x%llx\n", __func__,
- (u_int64_t)VM_KERNEL_ADDRPERM(mp_so)),
- MPTCP_SOCKET_DBG, MPTCP_LOGLVL_LOG);
-
-out:
- return (error);
-}
-