The current divert(4) implementation allocates an mbuf tag in pf_test()
to store the divert port specified by a divert-packet PF rule.

The divert_packet() function then looks up that mbuf tag to retrieve the
divert port number before sending the packet to userspace.

As far as I can tell, this approach of using an mbuf tag was borrowed
from divert-to's implementation.  However, in the case of divert(4) I
think it's overkill because once the packet has reached userspace,
its mbuf and mbuf tag are no longer needed.

I would like to simplify divert(4)'s implementation by passing the
divert port to divert_packet() directly as an argument, which avoids the
allocation of an mbuf tag completely.

ok?


Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.878
diff -u -p -u -p -r1.878 pf.c
--- net/pf.c    20 May 2014 11:03:13 -0000      1.878
+++ net/pf.c    14 Jun 2014 18:12:06 -0000
@@ -6617,14 +6617,8 @@ done:
                }
        }
 
-       if (action == PF_PASS && r->divert_packet.port) {
-               struct pf_divert *divert;
-
-               if ((divert = pf_get_divert(pd.m)))
-                       divert->port = r->divert_packet.port;
-
+       if (action == PF_PASS && r->divert_packet.port)
                action = PF_DIVERT;
-       }
 
        if (pd.pflog) {
                struct pf_rule_item     *ri;
@@ -6651,12 +6645,12 @@ done:
        case PF_DIVERT:
                switch (pd.af) {
                case AF_INET:
-                       if (divert_packet(pd.m, pd.dir) == 0)
+                       if (!divert_packet(pd.m, pd.dir, r->divert_packet.port))
                                *m0 = NULL;
                        break;
 #ifdef INET6
                case AF_INET6:
-                       if (divert6_packet(pd.m, pd.dir) == 0)
+                       if (!divert6_packet(pd.m, pd.dir, 
r->divert_packet.port))
                                *m0 = NULL;
                        break;
 #endif /* INET6 */
Index: netinet/ip_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.22
diff -u -p -u -p -r1.22 ip_divert.c
--- netinet/ip_divert.c 23 Apr 2014 14:43:14 -0000      1.22
+++ netinet/ip_divert.c 14 Jun 2014 17:45:12 -0000
@@ -189,12 +189,11 @@ fail:
 }
 
 int
-divert_packet(struct mbuf *m, int dir)
+divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
 {
        struct inpcb *inp;
        struct socket *sa = NULL;
        struct sockaddr_in addr;
-       struct pf_divert *divert;
 
        inp = NULL;
        divstat.divs_ipackets++;
@@ -205,15 +204,8 @@ divert_packet(struct mbuf *m, int dir)
                return (0);
        }
 
-       divert = pf_find_divert(m);
-       if (divert == NULL) {
-               divstat.divs_errors++;
-               m_freem(m);
-               return (0);
-       }
-
        TAILQ_FOREACH(inp, &divbtable.inpt_queue, inp_queue) {
-               if (inp->inp_lport != divert->port)
+               if (inp->inp_lport != divert_port)
                        continue;
                if (inp->inp_divertfl == 0)
                        break;
Index: netinet/ip_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 ip_divert.h
--- netinet/ip_divert.h 23 Apr 2014 14:43:14 -0000      1.5
+++ netinet/ip_divert.h 14 Jun 2014 17:52:05 -0000
@@ -55,7 +55,7 @@ extern struct divstat         divstat;
 
 void    divert_init(void);
 void    divert_input(struct mbuf *, ...);
-int     divert_packet(struct mbuf *, int);
+int     divert_packet(struct mbuf *, int, u_int16_t);
 int     divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int     divert_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 ip6_divert.c
--- netinet6/ip6_divert.c       28 Apr 2014 15:43:04 -0000      1.23
+++ netinet6/ip6_divert.c       14 Jun 2014 18:13:03 -0000
@@ -188,12 +188,11 @@ fail:
 }
 
 int
-divert6_packet(struct mbuf *m, int dir)
+divert6_packet(struct mbuf *m, int dir, u_int16_t divert_port)
 {
        struct inpcb *inp;
        struct socket *sa = NULL;
        struct sockaddr_in6 addr;
-       struct pf_divert *divert;
 
        inp = NULL;
        div6stat.divs_ipackets++;
@@ -204,15 +203,8 @@ divert6_packet(struct mbuf *m, int dir)
                return (0);
        }
 
-       divert = pf_find_divert(m);
-       if (divert == NULL) {
-               div6stat.divs_errors++;
-               m_freem(m);
-               return (0);
-       }
-
        TAILQ_FOREACH(inp, &divb6table.inpt_queue, inp_queue) {
-               if (inp->inp_lport != divert->port)
+               if (inp->inp_lport != divert_port)
                        continue;
                if (inp->inp_divertfl == 0)
                        break;
Index: netinet6/ip6_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.h,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 ip6_divert.h
--- netinet6/ip6_divert.h       23 Apr 2014 14:43:14 -0000      1.4
+++ netinet6/ip6_divert.h       14 Jun 2014 18:12:21 -0000
@@ -55,7 +55,7 @@ extern struct div6stat                div6stat;
 
 void    divert6_init(void);
 int     divert6_input(struct mbuf **, int *, int);
-int     divert6_packet(struct mbuf *, int);
+int     divert6_packet(struct mbuf *, int, u_int16_t);
 int     divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int     divert6_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);

Reply via email to