Make divert(4) socket dispatch mbuf to correct the lwkt port for further
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 19 Dec 2007 11:00:23 +0000 (11:00 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 19 Dec 2007 11:00:23 +0000 (11:00 +0000)
processing (ip_{input,output}):
- Add mbuf** function parameter to protosw.pr_mport()
- Pass 'addr' to pr_mport() in so_pru_send(); udp_soport() is adjusted
  accordingly
- Add additional parameter to ip_mport(), so it could be called with both
  incoming and outgoing packets.  And the processing for outgoing UDP packets
  matches udp_soport()
- Add div_soport() as IPPROTO_DIVERT's pr_mport()
  o  Delegate non-PRU_SEND operation to cpu0_soport()
  o  Move receiving interface setting up code from div_output() into this
     function, so ip_mport() could be called
  o  Use ip_mport() to find the target lwkt port

13 files changed:
sys/kern/uipc_msg.c
sys/kern/uipc_syscalls.c
sys/net/netisr.c
sys/net/rtsock.c
sys/netinet/in_proto.c
sys/netinet/ip_demux.c
sys/netinet/ip_divert.c
sys/netinet/ip_input.c
sys/netinet/ip_var.h
sys/netinet/tcp_var.h
sys/netinet/udp_var.h
sys/netinet6/ip6protosw.h
sys/sys/protosw.h

index aab2fe0..fde4c93 100644 (file)
@@ -30,7 +30,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/uipc_msg.c,v 1.19 2007/07/04 23:36:26 dillon Exp $
+ * $DragonFly: src/sys/kern/uipc_msg.c,v 1.20 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -55,7 +55,7 @@ so_pru_abort(struct socket *so)
        struct netmsg_pru_abort msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_ABORT);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_abort);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
@@ -75,7 +75,7 @@ so_pru_accept(struct socket *so, struct sockaddr **nam)
        struct netmsg_pru_accept msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_ACCEPT);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_accept);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept;
@@ -93,7 +93,7 @@ so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
        struct netmsg_pru_attach msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(NULL, NULL, PRU_ATTACH);
+       port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_attach);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach;
@@ -112,7 +112,7 @@ so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
        lwkt_port_t port;
 
        /* Send mesg to thread for new address. */
-       port = so->so_proto->pr_mport(NULL, nam, PRU_BIND);
+       port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_bind);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind;
@@ -130,7 +130,7 @@ so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
        struct netmsg_pru_connect msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, nam, PRU_CONNECT);
+       port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_connect);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect;
@@ -148,7 +148,7 @@ so_pru_connect2(struct socket *so1, struct socket *so2)
        struct netmsg_pru_connect2 msg;
        lwkt_port_t port;
 
-       port = so1->so_proto->pr_mport(so1, NULL, PRU_CONNECT2);
+       port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_connect2);
        msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2;
@@ -168,7 +168,7 @@ so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
        struct netmsg_pru_control msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_CONTROL);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_control);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
@@ -189,7 +189,7 @@ so_pru_detach(struct socket *so)
        struct netmsg_pru_detach msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_DETACH);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_detach);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
@@ -205,7 +205,7 @@ so_pru_disconnect(struct socket *so)
        struct netmsg_pru_disconnect msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_DISCONNECT);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_disconnect);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
@@ -221,7 +221,7 @@ so_pru_listen(struct socket *so, struct thread *td)
        struct netmsg_pru_listen msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_LISTEN);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_listen);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
@@ -238,7 +238,7 @@ so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
        struct netmsg_pru_peeraddr msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_PEERADDR);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_peeraddr);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
@@ -255,7 +255,7 @@ so_pru_rcvd(struct socket *so, int flags)
        struct netmsg_pru_rcvd msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_RCVD);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_rcvd);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
@@ -272,7 +272,7 @@ so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
        struct netmsg_pru_rcvoob msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_RCVOOB);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_rcvoob);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
@@ -291,7 +291,12 @@ so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
        struct netmsg_pru_send msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_SEND);
+       port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND);
+       if (port == NULL) {
+               KKASSERT(m == NULL);
+               return EINVAL;
+       }
+
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_send);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
@@ -312,7 +317,7 @@ so_pru_sense(struct socket *so, struct stat *sb)
        struct netmsg_pru_sense msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_SENSE);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_sense);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
@@ -329,7 +334,7 @@ so_pru_shutdown(struct socket *so)
        struct netmsg_pru_shutdown msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_SHUTDOWN);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_shutdown);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
@@ -345,7 +350,7 @@ so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
        struct netmsg_pru_sockaddr msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_SOCKADDR);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_sockaddr);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
@@ -362,7 +367,7 @@ so_pru_sopoll(struct socket *so, int events, struct ucred *cred)
        struct netmsg_pru_sopoll msg;
        lwkt_port_t port;
 
-       port = so->so_proto->pr_mport(so, NULL, PRU_SOPOLL);
+       port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL);
        netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
                    netmsg_pru_sopoll);
        msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
index 5f061c6..1768fc4 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)uipc_syscalls.c     8.4 (Berkeley) 2/21/94
  * $FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.65.2.17 2003/04/04 17:11:16 tegge Exp $
- * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.83 2007/11/07 18:24:06 dillon Exp $
+ * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.84 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include "opt_ktrace.h"
@@ -288,7 +288,7 @@ kern_accept(int s, int fflags, struct sockaddr **name, int *namelen, int *res)
                fflags = lfp->f_flag;
 
        /* optimize for uniprocessor case later XXX JH */
-       port = head->so_proto->pr_mport(head, NULL, PRU_PRED);
+       port = head->so_proto->pr_mport(head, NULL, NULL, PRU_PRED);
        netmsg_init_abortable(&msg.nm_netmsg, &curthread->td_msgport,
                              0,
                              netmsg_so_notify,
@@ -482,7 +482,7 @@ kern_connect(int s, int fflags, struct sockaddr *sa)
                struct netmsg_so_notify msg;
                lwkt_port_t port;
 
-               port = so->so_proto->pr_mport(so, sa, PRU_PRED);
+               port = so->so_proto->pr_mport(so, sa, NULL, PRU_PRED);
                netmsg_init_abortable(&msg.nm_netmsg, 
                                      &curthread->td_msgport,
                                      0,
index de73540..359096a 100644 (file)
@@ -35,7 +35,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/net/netisr.c,v 1.35 2007/07/10 20:24:57 dillon Exp $
+ * $DragonFly: src/sys/net/netisr.c,v 1.36 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include <sys/param.h>
@@ -325,14 +325,14 @@ cpu_portfn(int cpu)
 /* ARGSUSED */
 lwkt_port_t
 cpu0_soport(struct socket *so __unused, struct sockaddr *nam __unused,
-           int req __unused)
+           struct mbuf **dummy __unused, int req __unused)
 {
     return (&netisr_cpu[0].td_msgport);
 }
 
 lwkt_port_t
 sync_soport(struct socket *so __unused, struct sockaddr *nam __unused,
-           int req __unused)
+           struct mbuf **dummy __unused, int req __unused)
 {
     return (&netisr_sync_port);
 }
index 12a22b5..81e456f 100644 (file)
@@ -64,7 +64,7 @@
  *
  *     @(#)rtsock.c    8.7 (Berkeley) 10/12/95
  * $FreeBSD: src/sys/net/rtsock.c,v 1.44.2.11 2002/12/04 14:05:41 ru Exp $
- * $DragonFly: src/sys/net/rtsock.c,v 1.40 2007/08/09 01:10:05 dillon Exp $
+ * $DragonFly: src/sys/net/rtsock.c,v 1.41 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include "opt_sctp.h"
@@ -367,7 +367,7 @@ rts_input(struct mbuf *m, sa_family_t family)
        struct netmsg_packet *pmsg;
        lwkt_port_t port;
 
-       port = cpu0_soport(NULL, NULL, 0);
+       port = cpu0_soport(NULL, NULL, NULL, 0);
        pmsg = &m->m_hdr.mh_netmsg;
        netmsg_init(&pmsg->nm_netmsg, &netisr_apanic_rport, 
                    0, rts_input_handler);
index 6ca0b74..d6f4df1 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)in_proto.c  8.2 (Berkeley) 2/9/95
  * $FreeBSD: src/sys/netinet/in_proto.c,v 1.53.2.7 2003/08/24 08:24:38 hsu Exp $
- * $DragonFly: src/sys/netinet/in_proto.c,v 1.14 2007/08/16 20:03:57 dillon Exp $
+ * $DragonFly: src/sys/netinet/in_proto.c,v 1.15 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include "opt_ipdivert.h"
@@ -255,7 +255,7 @@ struct protosw inetsw[] = {
 #ifdef IPDIVERT
 { SOCK_RAW,    &inetdomain,    IPPROTO_DIVERT, PR_ATOMIC|PR_ADDR,
   div_input,   0,              0,              ip_ctloutput,
-  cpu0_soport,
+  div_soport,
   div_init,    0,              0,              0,
   &div_usrreqs,
 },
index 04597d9..d808e8b 100644 (file)
@@ -30,7 +30,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/netinet/ip_demux.c,v 1.36 2007/11/26 11:43:09 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_demux.c,v 1.37 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -210,7 +210,7 @@ fail:
  * may be modified and a port pointer will be returned.
  */
 lwkt_port_t
-ip_mport(struct mbuf **mptr)
+ip_mport(struct mbuf **mptr, int dir)
 {
        struct ip *ip;
        int iphlen;
@@ -246,7 +246,8 @@ ip_mport(struct mbuf **mptr)
                uh = (struct udphdr *)((caddr_t)ip + iphlen);
 
                if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
-                   in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
+                   (dir == IP_MPORT_IN &&
+                    in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) {
                        cpu = 0;
                } else {
                        cpu = INP_MPORT_HASH(ip->ip_src.s_addr,
@@ -262,11 +263,18 @@ ip_mport(struct mbuf **mptr)
        return (port);
 }
 
+lwkt_port_t
+ip_mport_in(struct mbuf **mptr)
+{
+       return ip_mport(mptr, IP_MPORT_IN);
+}
+
 /*
  * Map a TCP socket to a protocol processing thread.
  */
 lwkt_port_t
-tcp_soport(struct socket *so, struct sockaddr *nam, int req)
+tcp_soport(struct socket *so, struct sockaddr *nam __unused,
+          struct mbuf **dummy __unused, int req)
 {
        struct inpcb *inp;
 
@@ -304,17 +312,18 @@ tcp_addrport(in_addr_t faddr, in_port_t fport, in_addr_t laddr, in_port_t lport)
  * Map a UDP socket to a protocol processing thread.
  */
 lwkt_port_t
-udp_soport(struct socket *so, struct sockaddr *nam, int req)
+udp_soport(struct socket *so, struct sockaddr *nam __unused,
+          struct mbuf **dummy __unused, int req)
 {
        struct inpcb *inp;
 
        /*
         * The following processing all take place on Protocol Thread 0:
-        *   only bind() and connect() have a non-null nam parameter
+        *   bind() and connect()
         *   attach() has a null socket parameter
-        *   Fast and slow timeouts pass in two NULLs
+        *   Fast and slow timeouts pass in null socket parameter
         */
-       if (nam != NULL || so == NULL)
+       if (req == PRU_CONNECT || req == PRU_BIND || so == NULL)
                return (&udp_thread[0].td_msgport);
 
        inp = so->so_pcb;
index 4d8af10..f6934a9 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netinet/ip_divert.c,v 1.42.2.6 2003/01/23 21:06:45 sam Exp $
- * $DragonFly: src/sys/netinet/ip_divert.c,v 1.31 2007/12/12 13:57:36 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_divert.c,v 1.32 2007/12/19 11:00:22 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -77,6 +77,8 @@
 #define        DIVSNDQ         (65536 + 100)
 #define        DIVRCVQ         (65536 + 100)
 
+#define DIV_IS_OUTPUT(sin)     ((sin) == NULL || (sin)->sin_addr.s_addr == 0)
+
 /*
  * Divert sockets work in conjunction with ipfw, see the divert(4)
  * manpage for features.
@@ -138,6 +140,72 @@ div_input(struct mbuf *m, ...)
        m_freem(m);
 }
 
+struct lwkt_port *
+div_soport(struct socket *so, struct sockaddr *nam,
+          struct mbuf **mptr, int req)
+{
+       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);
+
+       m->m_pkthdr.rcvif = NULL;
+       dir = DIV_IS_OUTPUT(sin) ? IP_MPORT_OUT : IP_MPORT_IN;
+
+       if (sin != NULL) {
+               int i;
+
+               /*
+                * Try locating the interface, if we originally had one.
+                * This is done even for outgoing packets, since for a
+                * forwarded packet, there must be an interface attached.
+                *
+                * Find receive interface with the given name, stuffed
+                * (if it exists) in the sin_zero[] field.
+                * The name is user supplied data so don't trust its size
+                * or that it is zero terminated.
+                */
+               for (i = 0; sin->sin_zero[i] && i < sizeof(sin->sin_zero); i++)
+                       ;
+               if (i > 0 && i < sizeof(sin->sin_zero))
+                       m->m_pkthdr.rcvif = ifunit(sin->sin_zero);
+       }
+
+       if (dir == IP_MPORT_IN && m->m_pkthdr.rcvif == NULL) {
+               /*
+                * No luck with the name, check by IP address.
+                * Clear the port and the ifname to make sure
+                * there are no distractions for ifa_ifwithaddr.
+                *
+                * Be careful not to trash sin->sin_port; it will
+                * be used later in div_output().
+                */
+               struct ifaddr *ifa;
+               u_short sin_port;
+
+               bzero(sin->sin_zero, sizeof(sin->sin_zero));
+               sin_port = sin->sin_port; /* save */
+               sin->sin_port = 0;
+               ifa = ifa_ifwithaddr((struct sockaddr *)sin);
+               if (ifa == NULL) {
+                       m_freem(m);
+                       *mptr = NULL;
+                       return NULL;
+               }
+               sin->sin_port = sin_port; /* restore */
+               m->m_pkthdr.rcvif = ifa->ifa_ifp;
+       }
+
+       return ip_mport(mptr, dir);
+}
+
 /*
  * Divert a packet by passing it up to the divert socket at port 'port'.
  *
@@ -252,6 +320,9 @@ div_output(struct socket *so, struct mbuf *m,
        int error = 0;
        struct m_tag *mtag;
 
+       if (control)
+               m_freem(control);               /* XXX */
+
        /*
         * Prepare the tag for divert info. Note that a packet
         * with a 0 tag in mh_data is effectively untagged,
@@ -263,32 +334,15 @@ div_output(struct socket *so, struct mbuf *m,
                goto cantsend;
        }
        m_tag_prepend(m, mtag);
-       m->m_pkthdr.rcvif = NULL;       /* XXX is it necessary ? */
-
-       if (control)
-               m_freem(control);               /* XXX */
 
        /* Loopback avoidance and state recovery */
-       if (sin) {
-               int i;
-
+       if (sin)
                *(u_int16_t *)m_tag_data(mtag) = sin->sin_port;
-               /*
-                * Find receive interface with the given name, stuffed
-                * (if it exists) in the sin_zero[] field.
-                * The name is user supplied data so don't trust its size
-                * or that it is zero terminated.
-                */
-               for (i = 0; sin->sin_zero[i] && i < sizeof sin->sin_zero; i++)
-                       ;
-               if ( i > 0 && i < sizeof sin->sin_zero)
-                       m->m_pkthdr.rcvif = ifunit(sin->sin_zero);
-       } else {
+       else
                *(u_int16_t *)m_tag_data(mtag) = 0;
-       }
 
        /* Reinject packet into the system as incoming or outgoing */
-       if (!sin || sin->sin_addr.s_addr == 0) {
+       if (DIV_IS_OUTPUT(sin)) {
                struct ip *const ip = mtod(m, struct ip *);
 
                /* Don't allow packet length sizes that will crash */
@@ -308,26 +362,8 @@ div_output(struct socket *so, struct mbuf *m,
                            IP_ALLOWBROADCAST | IP_RAWOUTPUT,
                            NULL, NULL);
        } else {
-               if (m->m_pkthdr.rcvif == NULL) {
-                       /*
-                        * No luck with the name, check by IP address.
-                        * Clear the port and the ifname to make sure
-                        * there are no distractions for ifa_ifwithaddr.
-                        */
-                       struct  ifaddr *ifa;
-
-                       bzero(sin->sin_zero, sizeof sin->sin_zero);
-                       sin->sin_port = 0;
-                       ifa = ifa_ifwithaddr((struct sockaddr *) sin);
-                       if (ifa == NULL) {
-                               error = EADDRNOTAVAIL;
-                               goto cantsend;
-                       }
-                       m->m_pkthdr.rcvif = ifa->ifa_ifp;
-               }
                ip_input(m);
        }
-
        return error;
 
 cantsend:
@@ -430,13 +466,8 @@ static int
 div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
         struct mbuf *control, struct thread *td)
 {
-       /* Packet must have a header (but that's about it) */
-       if (m->m_len < sizeof(struct ip) &&
-           (m = m_pullup(m, sizeof(struct ip))) == NULL) {
-               ipstat.ips_toosmall++;
-               m_freem(m);
-               return EINVAL;
-       }
+       /* Length check already done in ip_mport() */
+       KASSERT(m->m_len >= sizeof(struct ip), ("IP header not in one mbuf"));
 
        /* Send packet */
        return div_output(so, m, (struct sockaddr_in *)nam, control);
index 07c825d..1fac63d 100644 (file)
@@ -65,7 +65,7 @@
  *
  *     @(#)ip_input.c  8.2 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/netinet/ip_input.c,v 1.130.2.52 2003/03/07 07:01:28 silby Exp $
- * $DragonFly: src/sys/netinet/ip_input.c,v 1.74 2007/11/22 19:57:14 dillon Exp $
+ * $DragonFly: src/sys/netinet/ip_input.c,v 1.75 2007/12/19 11:00:22 sephe Exp $
  */
 
 #define        _IP_VHL
@@ -358,7 +358,7 @@ ip_init(void)
        bzero(&ipstat, sizeof(struct ip_stats));
 #endif
 
-       netisr_register(NETISR_IP, ip_mport, ip_input_handler);
+       netisr_register(NETISR_IP, ip_mport_in, ip_input_handler);
 }
 
 /*
@@ -1067,7 +1067,7 @@ DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
 
                ip->ip_off = htons(ip->ip_off);
                ip->ip_len = htons(ip->ip_len);
-               port = ip_mport(&m);
+               port = ip_mport_in(&m);
                if (port == NULL)
                        return;
 
index ba535c8..a3095d7 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ip_var.h    8.2 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/netinet/ip_var.h,v 1.50.2.13 2003/08/24 08:24:38 hsu Exp $
- * $DragonFly: src/sys/netinet/ip_var.h,v 1.21 2007/08/16 20:03:57 dillon Exp $
+ * $DragonFly: src/sys/netinet/ip_var.h,v 1.22 2007/12/19 11:00:22 sephe Exp $
  */
 
 #ifndef _NETINET_IP_VAR_H_
@@ -171,6 +171,10 @@ extern struct ip_stats     ipstats_percpu[MAXCPU];
 #define        IP_ROUTETOIF            SO_DONTROUTE    /* bypass routing tables */
 #define        IP_ALLOWBROADCAST       SO_BROADCAST    /* can send broadcast packets */
 
+/* direction passed to ip_mport as last parameter */
+#define IP_MPORT_IN            0 /* Find lwkt port for incoming packets */
+#define IP_MPORT_OUT           1 /* Find lwkt port for outgoing packets */
+
 struct ip;
 struct inpcb;
 struct route;
@@ -198,7 +202,9 @@ void         ip_init(void);
 extern int      (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
                          struct ip_moptions *);
 struct lwkt_port *
-        ip_mport(struct mbuf **);
+        ip_mport_in(struct mbuf **);
+struct lwkt_port *
+        ip_mport(struct mbuf **, int);
 boolean_t
         ip_lengthcheck(struct mbuf **);
 int     ip_output(struct mbuf *,
@@ -229,6 +235,9 @@ extern void (*rsvp_input_p)(struct mbuf *m, ...);
 #ifdef IPDIVERT
 void   div_init(void);
 void   div_input(struct mbuf *, ...);
+struct lwkt_port *
+       div_soport(struct socket *, struct sockaddr *,
+                  struct mbuf **, int);
 void   divert_packet(struct mbuf *m, int incoming, int port);
 extern struct pr_usrreqs div_usrreqs;
 #endif
index c5c8f58..41b38e0 100644 (file)
@@ -65,7 +65,7 @@
  *
  *     @(#)tcp_var.h   8.4 (Berkeley) 5/24/95
  * $FreeBSD: src/sys/netinet/tcp_var.h,v 1.56.2.13 2003/02/03 02:34:07 hsu Exp $
- * $DragonFly: src/sys/netinet/tcp_var.h,v 1.39 2007/03/04 18:51:59 swildner Exp $
+ * $DragonFly: src/sys/netinet/tcp_var.h,v 1.40 2007/12/19 11:00:22 sephe Exp $
  */
 
 #ifndef _NETINET_TCP_VAR_H_
@@ -626,7 +626,8 @@ struct tcptemp *tcp_maketemplate (struct tcpcb *);
 void    tcp_freetemplate (struct tcptemp *);
 void    tcp_fillheaders (struct tcpcb *, void *, void *);
 struct lwkt_port *
-        tcp_soport(struct socket *, struct sockaddr *nam, int req);
+        tcp_soport(struct socket *, struct sockaddr *,
+                   struct mbuf **, int);
 struct tcpcb *
         tcp_timers (struct tcpcb *, int);
 void    tcp_trace (short, short, struct tcpcb *, void *, struct tcphdr *,
index 395516b..3d1ebb7 100644 (file)
@@ -65,7 +65,7 @@
  *
  *     @(#)udp_var.h   8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netinet/udp_var.h,v 1.22.2.1 2001/02/18 07:12:25 luigi Exp $
- * $DragonFly: src/sys/netinet/udp_var.h,v 1.16 2007/03/04 18:51:59 swildner Exp $
+ * $DragonFly: src/sys/netinet/udp_var.h,v 1.17 2007/12/19 11:00:22 sephe Exp $
  */
 
 #ifndef _NETINET_UDP_VAR_H_
@@ -153,7 +153,8 @@ void                        udp_thread_init (void);
 void                   udp_input (struct mbuf *, ...);
 void                   udp_notify (struct inpcb *inp, int error);
 int                    udp_shutdown (struct socket *so);
-struct lwkt_port       *udp_soport (struct socket *, struct sockaddr *, int);
+struct lwkt_port       *udp_soport (struct socket *, struct sockaddr *,
+                                    struct mbuf **, int);
 
 #endif
 
index 8238f80..3dd224f 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6protosw.h,v 1.2.2.4 2002/04/28 05:40:27 suz Exp $ */
-/*     $DragonFly: src/sys/netinet6/ip6protosw.h,v 1.7 2006/05/20 02:42:12 dillon Exp $        */
+/*     $DragonFly: src/sys/netinet6/ip6protosw.h,v 1.8 2007/12/19 11:00:23 sephe Exp $ */
 /*     $KAME: ip6protosw.h,v 1.25 2001/09/26 06:13:03 keiichi Exp $    */
 
 /*
@@ -142,7 +142,8 @@ struct ip6protosw {
 
 /* user-protocol hook */
        struct lwkt_port *(*pr_soport)
-                       (struct socket *, struct sockaddr *, int);
+                       (struct socket *, struct sockaddr *,
+                        struct mbuf **, int);
 
 /* utility hooks */
        void    (*pr_init)              /* initialization hook */
index 4167ae0..68a7b7d 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)protosw.h   8.1 (Berkeley) 6/2/93
  * $FreeBSD: src/sys/sys/protosw.h,v 1.28.2.2 2001/07/03 11:02:01 ume Exp $
- * $DragonFly: src/sys/sys/protosw.h,v 1.19 2007/04/22 01:13:17 dillon Exp $
+ * $DragonFly: src/sys/sys/protosw.h,v 1.20 2007/12/19 11:00:23 sephe Exp $
  */
 
 #ifndef _SYS_PROTOSW_H_
@@ -92,7 +92,8 @@ struct protosw {
        int     (*pr_ctloutput)(struct socket *, struct sockopt *);
                                        /* control output (from above) */
 /* user-protocol hook */
-       struct lwkt_port *(*pr_mport)(struct socket *, struct sockaddr *, int);
+       struct lwkt_port *(*pr_mport)(struct socket *, struct sockaddr *,
+                                     struct mbuf **, int);
 /* utility hooks */
        void    (*pr_init) (void);      /* initialization hook */
        void    (*pr_fasttimo) (void);
@@ -301,8 +302,10 @@ int        pru_rcvd_notsupp (struct socket *so, int flags);
 int    pru_rcvoob_notsupp (struct socket *so, struct mbuf *m, int flags);
 int    pru_sense_null (struct socket *so, struct stat *sb);
 
-struct lwkt_port *cpu0_soport(struct socket *, struct sockaddr *, int);
-struct lwkt_port *sync_soport(struct socket *, struct sockaddr *, int);
+struct lwkt_port *cpu0_soport(struct socket *, struct sockaddr *,
+                             struct mbuf **, int);
+struct lwkt_port *sync_soport(struct socket *, struct sockaddr *,
+                             struct mbuf **, int);
 
 #endif /* _KERNEL || _KERNEL_STRUCTURES */