Fix LINT build.
[dragonfly.git] / sys / netinet / ip_divert.c
index 16a8241..c714e71 100644 (file)
 #include <sys/socket.h>
 #include <sys/protosw.h>
 #include <sys/socketvar.h>
+#include <sys/socketvar2.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/priv.h>
-#include <sys/thread2.h>
 #include <sys/in_cksum.h>
 #include <sys/lock.h>
 #ifdef SMP
 #include <sys/msgport.h>
 #endif
 
-#include <vm/vm_zone.h>
-
 #include <net/if.h>
 #include <net/route.h>
+
 #ifdef SMP
 #include <net/netmsg2.h>
 #endif
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -126,6 +127,8 @@ static u_long       div_recvspace = DIVRCVQ;        /* XXX sysctl ? */
 
 static struct mbuf *ip_divert(struct mbuf *, int, int);
 
+static struct lwkt_token div_token = LWKT_TOKEN_MP_INITIALIZER(div_token);
+
 /*
  * Initialize divert connection block queue.
  */
@@ -142,8 +145,7 @@ div_init(void)
        divcbinfo.porthashbase = hashinit(1, M_PCB, &divcbinfo.porthashmask);
        divcbinfo.wildcardhashbase = hashinit(1, M_PCB,
                                              &divcbinfo.wildcardhashmask);
-       divcbinfo.ipi_zone = zinit("divcb", sizeof(struct inpcb),
-                                  maxsockets, ZONE_INTERRUPT, 0);
+       divcbinfo.ipi_size = sizeof(struct inpcb);
        ip_divert_p = ip_divert;
 }
 
@@ -159,17 +161,12 @@ div_input(struct mbuf *m, ...)
 }
 
 struct lwkt_port *
-div_soport(struct socket *so, struct sockaddr *nam,
-          struct mbuf **mptr, int req)
+div_soport(struct socket *so, struct sockaddr *nam, struct mbuf **mptr)
 {
        struct sockaddr_in *sin;
        struct mbuf *m;
        int dir;
 
-       /* Except for send(), everything happens on CPU0 */
-       if (req != PRU_SEND)
-               return cpu0_soport(so, nam, mptr, req);
-
        sin = (struct sockaddr_in *)nam;
        m = *mptr;
        M_ASSERTPKTHDR(m);
@@ -221,7 +218,16 @@ div_soport(struct socket *so, struct sockaddr *nam,
                m->m_pkthdr.rcvif = ifa->ifa_ifp;
        }
 
-       return ip_mport(mptr, dir);
+       /*
+        * Recalculate the protocol thread.
+        */
+       ip_cpufn(mptr, 0, dir);
+       m = *mptr;
+       if (m) {
+               KKASSERT(m->m_flags & M_HASH);
+               return(cpu_portfn(m->m_pkthdr.hash));
+       }
+       return(NULL);
 }
 
 /*
@@ -304,7 +310,7 @@ div_packet(struct mbuf *m, int incoming, int port)
         * saving/testing the socket pointer is not MPSAFE.  So we still
         * need to hold BGL here.
         */
-       get_mplock();
+       lwkt_gettoken(&div_token);
        LIST_FOREACH(inp, &divcbinfo.pcblisthead, inp_list) {
                if (inp->inp_flags & INP_PLACEMARKER)
                        continue;
@@ -312,18 +318,18 @@ div_packet(struct mbuf *m, int incoming, int port)
                        sa = inp->inp_socket;
        }
        if (sa) {
-               if (ssb_appendaddr(&sa->so_rcv, (struct sockaddr *)&divsrc, m,
-                                (struct mbuf *)NULL) == 0)
+               lwkt_gettoken(&sa->so_rcv.ssb_token);
+               if (ssb_appendaddr(&sa->so_rcv, (struct sockaddr *)&divsrc, m, NULL) == 0)
                        m_freem(m);
                else
                        sorwakeup(sa);
-               rel_mplock();
+               lwkt_reltoken(&sa->so_rcv.ssb_token);
        } else {
-               rel_mplock();
                m_freem(m);
                ipstat.ips_noproto++;
                ipstat.ips_delivered--;
        }
+       lwkt_reltoken(&div_token);
 }
 
 #ifdef SMP
@@ -374,8 +380,8 @@ divert_packet(struct mbuf *m, int incoming)
                struct lwkt_msg *msg;
 
                nmp = &m->m_hdr.mh_netmsg;
-               netmsg_init(&nmp->nm_netmsg, &netisr_apanic_rport, MSGF_MPSAFE,
-                           div_packet_handler);
+               netmsg_init(&nmp->nm_netmsg, NULL, &netisr_apanic_rport,
+                           0, div_packet_handler);
                nmp->nm_packet = m;
 
                msg = &nmp->nm_netmsg.nm_lmsg;
@@ -473,9 +479,12 @@ div_attach(struct socket *so, int proto, struct pru_attach_info *ai)
        error = soreserve(so, div_sendspace, div_recvspace, ai->sb_rlimit);
        if (error)
                return error;
+       lwkt_gettoken(&div_token);
        error = in_pcballoc(so, &divcbinfo);
-       if (error)
+       if (error) {
+               lwkt_reltoken(&div_token);
                return error;
+       }
        inp = (struct inpcb *)so->so_pcb;
        inp->inp_ip_p = proto;
        inp->inp_vflag |= INP_IPV4;
@@ -484,7 +493,9 @@ div_attach(struct socket *so, int proto, struct pru_attach_info *ai)
         * The socket is always "connected" because
         * we always know "where" to send the packet.
         */
-       so->so_state |= SS_ISCONNECTED;
+       so->so_port = cpu0_soport(so, NULL, NULL);
+       sosetstate(so, SS_ISCONNECTED);
+       lwkt_reltoken(&div_token);
        return 0;
 }
 
@@ -500,19 +511,33 @@ div_detach(struct socket *so)
        return 0;
 }
 
+/*
+ * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort()
+ *      will sofree() it when we return.
+ */
 static int
 div_abort(struct socket *so)
 {
+       int error;
+
        soisdisconnected(so);
-       return div_detach(so);
+       error = div_detach(so);
+
+       return error;
 }
 
 static int
 div_disconnect(struct socket *so)
 {
+       int error;
+
        if (!(so->so_state & SS_ISCONNECTED))
                return ENOTCONN;
-       return div_abort(so);
+       soreference(so);
+       error = div_abort(so);
+       sofree(so);
+
+       return error;
 }
 
 static int
@@ -548,7 +573,7 @@ static int
 div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
         struct mbuf *control, struct thread *td)
 {
-       /* Length check already done in ip_mport() */
+       /* Length check already done in ip_cpufn() */
        KASSERT(m->m_len >= sizeof(struct ip), ("IP header not in one mbuf"));
 
        /* Send packet */
@@ -578,8 +603,7 @@ struct pr_usrreqs div_usrreqs = {
        .pru_shutdown = div_shutdown,
        .pru_sockaddr = in_setsockaddr,
        .pru_sosend = sosend,
-       .pru_soreceive = soreceive,
-       .pru_sopoll = sopoll
+       .pru_soreceive = soreceive
 };
 
 static struct mbuf *