Question:
> How does pair(4) interact with pf? If a packet crosses a pair
> does it create a new state or does pf track the original state?
> 

Answer:
It does create a new state, you can filter between pair(4) without
problems and all features including nat work.
But it currently does not clear some of the extended packet settings -
like flags, tags, qid etc. - so you can filter on the tag, eg. 

# Assuming pair1 is patched to pair0
pass out on pair1 tag FOO
pass in on pair0 tagged FOO

The attached diff _removes_ that and resets all pf settings, so the pf
rules above will not work anymore.  I think it is better to assume
crossing barriers and receiving packets with pair(4) works like a
"normal" Ethernet packet.  The following will still work:

# Received packets on pair0 don't carry any existing pf states
pass out on pair1
pass in on pair0

OK?

Reyk

Index: sys/net/if_pair.c
===================================================================
RCS file: /cvs/src/sys/net/if_pair.c,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 if_pair.c
--- sys/net/if_pair.c   25 Oct 2015 12:59:57 -0000      1.4
+++ sys/net/if_pair.c   30 Oct 2015 09:23:44 -0000
@@ -30,6 +30,11 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 
+#include "pf.h"
+#if NPF > 0
+#include <net/pfvar.h>
+#endif
+
 #include "bpfilter.h"
 #if NBPFILTER > 0
 #include <net/bpf.h>
@@ -182,9 +187,12 @@ pairstart(struct ifnet *ifp)
 #endif /* NBPFILTER > 0 */
 
                ifp->if_opackets++;
-               if (pairedifp != NULL)
+               if (pairedifp != NULL) {
+#if NPF > 0
+                       pf_pkt_reset(m);
+#endif
                        ml_enqueue(&ml, m);
-               else
+               } else
                        m_freem(m);
        }
 
Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.948
diff -u -p -u -p -r1.948 pf.c
--- sys/net/pf.c        27 Oct 2015 10:52:17 -0000      1.948
+++ sys/net/pf.c        30 Oct 2015 09:23:46 -0000
@@ -6701,6 +6701,19 @@ pf_pkt_addr_changed(struct mbuf *m)
        m->m_pkthdr.pf.inp = NULL;
 }
 
+/*
+ * should be called when reinjecting the packet with a clean state
+ */
+void
+pf_pkt_reset(struct mbuf *m)
+{
+       if (m->m_flags & M_PKTHDR)
+               m_tag_delete_chain(m);
+
+       /* resets state key, pcb reference, qid, tag, and all flags */
+       memset(&m->m_pkthdr.pf, 0, sizeof(m->m_pkthdr.pf));
+}
+
 #if NPFLOG > 0
 void
 pf_log_matches(struct pf_pdesc *pd, struct pf_rule *rm, struct pf_rule *am,
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.421
diff -u -p -u -p -r1.421 pfvar.h
--- sys/net/pfvar.h     13 Oct 2015 19:32:32 -0000      1.421
+++ sys/net/pfvar.h     30 Oct 2015 09:23:46 -0000
@@ -1756,6 +1756,7 @@ int       pf_rtlabel_match(struct pf_addr *, s
 int    pf_socket_lookup(struct pf_pdesc *);
 struct pf_state_key *pf_alloc_state_key(int);
 void   pf_pkt_addr_changed(struct mbuf *);
+void   pf_pkt_reset(struct mbuf *);
 int    pf_state_key_attach(struct pf_state_key *, struct pf_state *, int);
 int    pf_translate(struct pf_pdesc *, struct pf_addr *, u_int16_t,
            struct pf_addr *, u_int16_t, u_int16_t, int);

Reply via email to