+ * Exported (private) routine, indirection of net_add_proto.
+ */
+int
+net_add_proto_old(struct protosw_old *opp, struct domain_old *odp)
+{
+ struct pr_usrreqs_old *opru;
+ struct pr_usrreqs *pru = NULL;
+ struct protosw *pp = NULL, *pp1;
+ int error = 0;
+ struct domain *dp;
+ domain_guard_t guard;
+
+ /*
+ * This could be called as part of initializing the domain,
+ * and thus DOM_INITIALIZED may not be set (yet).
+ */
+ guard = domain_guard_deploy();
+
+ /* Make sure the domain has been added via net_add_domain */
+ TAILQ_FOREACH(dp, &domains, dom_entry) {
+ if (!(dp->dom_flags & DOM_OLD)) {
+ continue;
+ }
+ if (dp->dom_old == odp) {
+ break;
+ }
+ }
+ if (dp == NULL) {
+ error = EINVAL;
+ goto done;
+ }
+
+ TAILQ_FOREACH(pp1, &dp->dom_protosw, pr_entry) {
+ if (pp1->pr_type == opp->pr_type &&
+ pp1->pr_protocol == opp->pr_protocol) {
+ error = EEXIST;
+ goto done;
+ }
+ }
+
+ if ((opru = opp->pr_usrreqs) == NULL) {
+ panic("%s: domain (%d,%s), proto %d has no usrreqs!\n",
+ __func__, odp->dom_family, odp->dom_name, opp->pr_protocol);
+ /* NOTREACHED */
+ }
+
+ pru = _MALLOC(sizeof(*pru), M_TEMP, M_WAITOK | M_ZERO);
+ if (pru == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+
+ pru->pru_flags = PRUF_OLD;
+ pru->pru_abort = opru->pru_abort;
+ pru->pru_accept = opru->pru_accept;
+ pru->pru_attach = opru->pru_attach;
+ pru->pru_bind = opru->pru_bind;
+ pru->pru_connect = opru->pru_connect;
+ pru->pru_connect2 = opru->pru_connect2;
+ pru->pru_control = opru->pru_control;
+ pru->pru_detach = opru->pru_detach;
+ pru->pru_disconnect = opru->pru_disconnect;
+ pru->pru_listen = opru->pru_listen;
+ pru->pru_peeraddr = opru->pru_peeraddr;
+ pru->pru_rcvd = opru->pru_rcvd;
+ pru->pru_rcvoob = opru->pru_rcvoob;
+ pru->pru_send = opru->pru_send;
+ pru->pru_sense = opru->pru_sense;
+ pru->pru_shutdown = opru->pru_shutdown;
+ pru->pru_sockaddr = opru->pru_sockaddr;
+ pru->pru_sosend = opru->pru_sosend;
+ pru->pru_soreceive = opru->pru_soreceive;
+ pru->pru_sopoll = opru->pru_sopoll;
+
+ pp = _MALLOC(sizeof(*pp), M_TEMP, M_WAITOK | M_ZERO);
+ if (pp == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+
+ /*
+ * Protocol fast and slow timers are now deprecated.
+ */
+ if (opp->pr_unused != NULL) {
+ printf("%s: domain (%d,%s), proto %d: pr_fasttimo is "
+ "deprecated and won't be called\n", __func__,
+ odp->dom_family, odp->dom_name, opp->pr_protocol);
+ }
+ if (opp->pr_unused2 != NULL) {
+ printf("%s: domain (%d,%s), proto %d: pr_slowtimo is "
+ "deprecated and won't be called\n", __func__,
+ odp->dom_family, odp->dom_name, opp->pr_protocol);
+ }
+
+ /* Copy everything but pr_init, pr_next, pr_domain, pr_protosw */
+ pp->pr_type = opp->pr_type;
+ pp->pr_protocol = opp->pr_protocol;
+ pp->pr_flags = (opp->pr_flags & PRF_USERFLAGS) | PR_OLD;
+ pp->pr_input = opp->pr_input;
+ pp->pr_output = opp->pr_output;
+ pp->pr_ctlinput = opp->pr_ctlinput;
+ pp->pr_ctloutput = opp->pr_ctloutput;
+ pp->pr_usrreqs = pru;
+ pp->pr_init = pr_init_old;
+ pp->pr_drain = opp->pr_drain;
+ pp->pr_sysctl = opp->pr_sysctl;
+ pp->pr_lock = opp->pr_lock;
+ pp->pr_unlock = opp->pr_unlock;
+ pp->pr_getlock = opp->pr_getlock;
+ pp->pr_old = opp;
+
+ /* attach as well as initialize */
+ attach_proto(pp, dp);
+ net_init_proto(pp, dp);
+done:
+ if (error != 0) {
+ printf("%s: domain (%d,%s), proto %d: failed to attach, "
+ "error %d\n", __func__, odp->dom_family,
+ odp->dom_name, opp->pr_protocol, error);
+
+ if (pru != NULL) {
+ FREE(pru, M_TEMP);
+ }
+ if (pp != NULL) {
+ FREE(pp, M_TEMP);
+ }
+ }
+
+ domain_guard_release(guard);
+ return error;
+}
+
+/*
+ * Internal routine, not exported.
+ *