Author: ae
Date: Wed Aug  9 12:24:07 2017
New Revision: 322310
URL: https://svnweb.freebsd.org/changeset/base/322310

Log:
  Add to if_enc(4) ability to capture packets via BPF after pfil processing.
  
  New flag 0x4 can be configured in net.enc.[in|out].ipsec_bpf_mask.
  When it is set, if_enc(4) additionally captures a packet via BPF after
  invoking pfil hook. This may be useful for debugging.
  
  MFC after:    2 weeks
  Sponsored by: Yandex LLC
  Differential Revision:        https://reviews.freebsd.org/D11804

Modified:
  head/share/man/man4/enc.4
  head/sys/net/if_enc.c

Modified: head/share/man/man4/enc.4
==============================================================================
--- head/share/man/man4/enc.4   Wed Aug  9 12:21:17 2017        (r322309)
+++ head/share/man/man4/enc.4   Wed Aug  9 12:24:07 2017        (r322310)
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 28, 2007
+.Dd August 9, 2017
 .Dt ENC 4
 .Os
 .Sh NAME
@@ -44,6 +44,13 @@ kernel configuration file:
 .Bd -ragged -offset indent
 .Cd "device enc"
 .Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+if_enc_load="YES"
+.Ed
 .Sh DESCRIPTION
 The
 .Nm
@@ -115,6 +122,11 @@ outgoing path                                         
 Most people will want to run with the suggested defaults for
 .Cm ipsec_filter_mask
 and rely on the security policy database for the outer headers.
+.Pp
+Note that packets are captured by BPF before firewall processing.
+The special value 0x4 can be configured in the
+.Ar ipsec_bpf_mask
+and packets will be also captured after firewall processing.
 .Sh EXAMPLES
 To see the packets the processed via
 .Xr ipsec 4 ,

Modified: head/sys/net/if_enc.c
==============================================================================
--- head/sys/net/if_enc.c       Wed Aug  9 12:21:17 2017        (r322309)
+++ head/sys/net/if_enc.c       Wed Aug  9 12:24:07 2017        (r322310)
@@ -99,9 +99,15 @@ static void  enc_remove_hhooks(struct enc_softc *);
 
 static const char encname[] = "enc";
 
+#define        IPSEC_ENC_AFTER_PFIL    0x04
 /*
  * Before and after are relative to when we are stripping the
  * outer IP header.
+ *
+ * AFTER_PFIL flag used only for bpf_mask_*. It enables BPF capturing
+ * after PFIL hook execution. It might be useful when PFIL hook does
+ * some changes to the packet, e.g. address translation. If PFIL hook
+ * consumes mbuf, nothing will be captured.
  */
 static VNET_DEFINE(int, filter_mask_in) = IPSEC_ENC_BEFORE;
 static VNET_DEFINE(int, bpf_mask_in) = IPSEC_ENC_BEFORE;
@@ -194,6 +200,30 @@ enc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
        return (0);
 }
 
+static void
+enc_bpftap(struct ifnet *ifp, struct mbuf *m, const struct secasvar *sav,
+    int32_t hhook_type, uint8_t enc, uint8_t af)
+{
+       struct enchdr hdr;
+
+       if (hhook_type == HHOOK_TYPE_IPSEC_IN &&
+           (enc & V_bpf_mask_in) == 0)
+               return;
+       else if (hhook_type == HHOOK_TYPE_IPSEC_OUT &&
+           (enc & V_bpf_mask_out) == 0)
+               return;
+       if (bpf_peers_present(ifp->if_bpf) == 0)
+               return;
+       hdr.af = af;
+       hdr.spi = sav->spi;
+       hdr.flags = 0;
+       if (sav->alg_enc != SADB_EALG_NONE)
+               hdr.flags |= M_CONF;
+       if (sav->alg_auth != SADB_AALG_NONE)
+               hdr.flags |= M_AUTH;
+       bpf_mtap2(ifp->if_bpf, &hdr, sizeof(hdr), m);
+}
+
 /*
  * One helper hook function is used by any hook points.
  * + from hhook_type we can determine the packet direction:
@@ -206,7 +236,6 @@ static int
 enc_hhook(int32_t hhook_type, int32_t hhook_id, void *udata, void *ctx_data,
     void *hdata, struct osd *hosd)
 {
-       struct enchdr hdr;
        struct ipsec_ctx_data *ctx;
        struct enc_softc *sc;
        struct ifnet *ifp, *rcvif;
@@ -223,21 +252,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, void *
        if (ctx->af != hhook_id)
                return (EPFNOSUPPORT);
 
-       if (((hhook_type == HHOOK_TYPE_IPSEC_IN &&
-           (ctx->enc & V_bpf_mask_in) != 0) ||
-           (hhook_type == HHOOK_TYPE_IPSEC_OUT &&
-           (ctx->enc & V_bpf_mask_out) != 0)) &&
-           bpf_peers_present(ifp->if_bpf) != 0) {
-               hdr.af = ctx->af;
-               hdr.spi = ctx->sav->spi;
-               hdr.flags = 0;
-               if (ctx->sav->alg_enc != SADB_EALG_NONE)
-                       hdr.flags |= M_CONF;
-               if (ctx->sav->alg_auth != SADB_AALG_NONE)
-                       hdr.flags |= M_AUTH;
-               bpf_mtap2(ifp->if_bpf, &hdr, sizeof(hdr), *ctx->mp);
-       }
-
+       enc_bpftap(ifp, *ctx->mp, ctx->sav, hhook_type, ctx->enc, ctx->af);
        switch (hhook_type) {
        case HHOOK_TYPE_IPSEC_IN:
                if (ctx->enc == IPSEC_ENC_BEFORE) {
@@ -290,6 +305,8 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, void *
                return (EACCES);
        }
        (*ctx->mp)->m_pkthdr.rcvif = rcvif;
+       enc_bpftap(ifp, *ctx->mp, ctx->sav, hhook_type,
+           IPSEC_ENC_AFTER_PFIL, ctx->af);
        return (0);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to