Prepare to make IPDIVERT transparent to ip reassemble code:
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 27 Aug 2008 14:00:45 +0000 (14:00 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 27 Aug 2008 14:00:45 +0000 (14:00 +0000)
Include more information in divert mbuf tag

sys/net/ipfw/ip_fw2.c
sys/netinet/ip_divert.c
sys/netinet/ip_divert.h [new file with mode: 0644]
sys/sys/mbuf.h

index bbabe58..17a0c59 100644 (file)
@@ -23,7 +23,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/netinet/ip_fw2.c,v 1.6.2.12 2003/04/08 10:42:32 maxim Exp $
- * $DragonFly: src/sys/net/ipfw/ip_fw2.c,v 1.77 2008/08/26 11:42:40 sephe Exp $
+ * $DragonFly: src/sys/net/ipfw/ip_fw2.c,v 1.78 2008/08/27 14:00:45 sephe Exp $
  */
 
 #define        DEB(x)
@@ -77,6 +77,7 @@
 #include <netinet/tcpip.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
+#include <netinet/ip_divert.h>
 
 #include <netinet/if_ether.h> /* XXX for ETHERTYPE_IP */
 
@@ -1627,6 +1628,7 @@ ipfw_chk(struct ip_fw_args *args)
        struct ip_fw *f = NULL;         /* matching rule */
        int retval = 0;
        struct m_tag *mtag;
+       struct divert_info *divinfo;
 
        /*
         * hlen The length of the IPv4 header.
@@ -1784,10 +1786,12 @@ after_ip_checks:
                int skipto;
 
                mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL);
-               if (mtag != NULL)
-                       skipto = *(uint16_t *)m_tag_data(mtag);
-               else
+               if (mtag != NULL) {
+                       divinfo = m_tag_data(mtag);
+                       skipto = divinfo->skipto;
+               } else {
                        skipto = 0;
+               }
 
                f = ctx->ipfw_layer3_chain;
                if (args->eh == NULL && skipto != 0) {
@@ -2280,13 +2284,18 @@ check_body:
                                        break;
 
                                mtag = m_tag_get(PACKET_TAG_IPFW_DIVERT,
-                                                sizeof(uint16_t), MB_DONTWAIT);
+                                                sizeof(*divinfo), MB_DONTWAIT);
                                if (mtag == NULL) {
                                        retval = IP_FW_PORT_DENY_FLAG;
                                        goto done;
                                }
-                               *(uint16_t *)m_tag_data(mtag) = f->rulenum;
+                               divinfo = m_tag_data(mtag);
+
+                               divinfo->skipto = f->rulenum;
+                               divinfo->port = cmd->arg1;
+                               divinfo->tee = (cmd->opcode == O_TEE);
                                m_tag_prepend(m, mtag);
+
                                retval = (cmd->opcode == O_DIVERT) ?
                                    cmd->arg1 :
                                    cmd->arg1 | IP_FW_PORT_TEE_FLAG;
index 95d0161..65b7906 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.36 2008/03/07 11:34:20 sephe Exp $
+ * $DragonFly: src/sys/netinet/ip_divert.c,v 1.37 2008/08/27 14:00:45 sephe Exp $
  */
 
 #include "opt_inet.h"
@@ -72,6 +72,7 @@
 #include <netinet/in_pcb.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_var.h>
+#include <netinet/ip_divert.h>
 
 /*
  * Divert sockets
@@ -228,11 +229,13 @@ div_packet(struct mbuf *m, int incoming, int port)
        struct inpcb *inp;
        struct socket *sa;
        struct m_tag *mtag;
+       struct divert_info *divinfo;
        u_int16_t nport;
 
-       /* Locate the divert tag */
+       /* Locate the divert info */
        mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL);
-       divsrc.sin_port = *(u_int16_t *)m_tag_data(mtag);
+       divinfo = m_tag_data(mtag);
+       divsrc.sin_port = divinfo->skipto;
 
        /*
         * Record receive interface address, if any.
@@ -377,6 +380,7 @@ div_output(struct socket *so, struct mbuf *m,
 {
        int error = 0;
        struct m_tag *mtag;
+       struct divert_info *divinfo;
 
        if (control)
                m_freem(control);               /* XXX */
@@ -386,7 +390,7 @@ div_output(struct socket *so, struct mbuf *m,
         * with a 0 tag in mh_data is effectively untagged,
         * so we could optimize that case.
         */
-       mtag = m_tag_get(PACKET_TAG_IPFW_DIVERT, sizeof(u_int16_t), MB_DONTWAIT);
+       mtag = m_tag_get(PACKET_TAG_IPFW_DIVERT, sizeof(*divinfo), MB_DONTWAIT);
        if (mtag == NULL) {
                error = ENOBUFS;
                goto cantsend;
@@ -394,10 +398,11 @@ div_output(struct socket *so, struct mbuf *m,
        m_tag_prepend(m, mtag);
 
        /* Loopback avoidance and state recovery */
+       divinfo = m_tag_data(mtag);
        if (sin)
-               *(u_int16_t *)m_tag_data(mtag) = sin->sin_port;
+               divinfo->skipto = sin->sin_port;
        else
-               *(u_int16_t *)m_tag_data(mtag) = 0;
+               divinfo->skipto = 0;
 
        /* Reinject packet into the system as incoming or outgoing */
        if (DIV_IS_OUTPUT(sin)) {
diff --git a/sys/netinet/ip_divert.h b/sys/netinet/ip_divert.h
new file mode 100644 (file)
index 0000000..aabd44a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $DragonFly: src/sys/netinet/ip_divert.h,v 1.1 2008/08/27 14:00:45 sephe Exp $
+ */
+
+#ifndef _NETINET_IP_DIVERT_H_
+#define _NETINET_IP_DIVERT_H_
+
+#ifndef _SYS_TYPES_H_
+#include <sys/types.h>
+#endif
+
+struct divert_info {
+       uint16_t        skipto;
+       uint16_t        port;   /* host byte order */
+       int             tee;
+};
+
+#endif /* !_NETINET_IP_DIVERT_H_ */
index 929f5da..0288dd9 100644 (file)
@@ -34,7 +34,7 @@
  *
  *     @(#)mbuf.h      8.5 (Berkeley) 2/19/95
  * $FreeBSD: src/sys/sys/mbuf.h,v 1.44.2.17 2003/04/15 06:15:02 silby Exp $
- * $DragonFly: src/sys/sys/mbuf.h,v 1.51 2008/08/23 06:56:22 sephe Exp $
+ * $DragonFly: src/sys/sys/mbuf.h,v 1.52 2008/08/27 14:00:45 sephe Exp $
  */
 
 #ifndef _SYS_MBUF_H_
@@ -584,7 +584,7 @@ m_getb(int len, int how, int type, int flags)
 #define        PACKET_TAG_IPV6_INPUT                   8 /* IPV6 input processing */
 /* struct ip6aux */
 #define        PACKET_TAG_IPFW_DIVERT                  9 /* divert info */
-/* uint16_t */
+/* struct divert_info */
 #define        PACKET_TAG_DUMMYNET                     15 /* dummynet info */
 /* struct dn_pkt */
 #define        PACKET_TAG_IPFORWARD                    18 /* ipforward info */