diff options
author | ae <ae@FreeBSD.org> | 2017-08-09 12:24:07 +0000 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2017-08-09 11:06:57 -0500 |
commit | 131ee7d1d786959b69e666a0a342bf5703e05df3 (patch) | |
tree | 3a20b9e4276045003a5894bcf77ed50b5ccec99e | |
parent | dd94b3647551cf7e5d6062fda99cd5b2efd46b9e (diff) | |
download | FreeBSD-src-131ee7d1d786959b69e666a0a342bf5703e05df3.zip FreeBSD-src-131ee7d1d786959b69e666a0a342bf5703e05df3.tar.gz |
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
(cherry picked from commit 6dd69d60f664b5687f5b7eb3a77f079dac3df6c2)
-rw-r--r-- | share/man/man4/enc.4 | 14 | ||||
-rw-r--r-- | sys/net/if_enc.c | 49 |
2 files changed, 46 insertions, 17 deletions
diff --git a/share/man/man4/enc.4 b/share/man/man4/enc.4 index 3205918..42e0143 100644 --- a/share/man/man4/enc.4 +++ b/share/man/man4/enc.4 @@ -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 , diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c index 1d86a08..82a58a8 100644 --- a/sys/net/if_enc.c +++ b/sys/net/if_enc.c @@ -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 *udata, void *ctx_data, 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 *udata, void *ctx_data, 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); } |