On Fri, 21 Oct 2016, Alexander Bluhm wrote:
> We could put the union pf_headers into a separate header file.
> Henning, I hope you don't mind that I used a current license.template
> with your old pf_headers code.
> 
> Do we want to go this way?

You got me thinking how else this might be done.

Note that union pf_headers is used only to calculate the max size of the 
header pull buffer. Its members are never referenced. 

So it may be enough to #define PF_MAXHDR_SIZE 28 in pfvar.h (== 
sizeof(union pf_headers)), then verify it by a compile-time assert in 
pf.c.

   +ve no new header file to support what amounts to an
       implementation detail.

best, 
Richard. 

---------------- 
[a sketch --- compiled but untested beyond checking the CTASSERT fires 
when PF_MAXHDR_SIZE = 20]

Index: net/pf.c
===================================================================
--- net.orig/pf.c
+++ net/pf.c
@@ -128,7 +128,7 @@ struct pf_anchor_stackframe {
 
 /*
  * Cannot fold into pf_pdesc directly, unknown storage size outside pf.c.
- * Keep in sync with union pf_headers in pflog_bpfcopy() in if_pflog.c.
+ * Cannot be put into pfvar.h as that is included in too many places.
  */
 union pf_headers {
        struct tcphdr           tcp;
@@ -140,7 +140,7 @@ union pf_headers {
        struct nd_neighbor_solicit nd_ns;
 #endif /* INET6 */
 };
-
+CTASSERT(PF_MAXHDR_SIZE >= sizeof(union pf_headers));
 
 struct pool             pf_src_tree_pl, pf_rule_pl, pf_queue_pl;
 struct pool             pf_state_pl, pf_state_key_pl, pf_state_item_pl;
@@ -6613,7 +6613,7 @@ pf_test(sa_family_t af, int fwdir, struc
        struct pf_state         *s = NULL;
        struct pf_ruleset       *ruleset = NULL;
        struct pf_pdesc          pd;
-       union pf_headers         pdhdrs;
+       u_int8_t                 pdhdrs[PF_MAXHDR_SIZE];
        int                      dir = (fwdir == PF_FWD) ? PF_OUT : fwdir;
        u_int32_t                qid, pqid = 0;
 
Index: net/pfvar.h
===================================================================
--- net.orig/pfvar.h
+++ net/pfvar.h
@@ -1156,6 +1156,8 @@ enum pfi_kif_refs {
 #define PFI_IFLAG_SKIP         0x0100  /* skip filtering on interface */
 #define PFI_IFLAG_ANY          0x0200  /* match any non-loopback interface */
 
+#define PF_MAXHDR_SIZE         28      /* max pf pf_pdesc header buffer */
+
 struct pf_pdesc {
        struct {
                int      done;
Index: net/if_pflog.c
===================================================================
--- net.orig/if_pflog.c
+++ net/if_pflog.c
@@ -297,16 +297,7 @@ pflog_bpfcopy(const void *src_arg, void
        u_int                    count;
        u_char                  *dst, *mdst;
        int                      afto, hlen, mlen, off;
-       union pf_headers {
-               struct tcphdr           tcp;
-               struct udphdr           udp;
-               struct icmp             icmp;
-#ifdef INET6
-               struct icmp6_hdr        icmp6;
-               struct mld_hdr          mld;
-               struct nd_neighbor_solicit nd_ns;
-#endif /* INET6 */
-       } pdhdrs;
+       u_int8_t                 pdhdrs[PF_MAXHDR_SIZE];
 
        struct pf_pdesc          pd;
        struct pf_addr           osaddr, odaddr;

Reply via email to