summaryrefslogtreecommitdiffstats
path: root/sys/netipsec/ipsec_input.c
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2015-11-25 07:31:59 +0000
committerae <ae@FreeBSD.org>2015-11-25 07:31:59 +0000
commitd81208c9488e0efbf99f327d11bbd7bc055c5b1b (patch)
tree180d9bca9c02ba401375a447b28937f28cfb981d /sys/netipsec/ipsec_input.c
parentda001d5bf7a7acfef070a8f605c3ec452d374d09 (diff)
downloadFreeBSD-src-d81208c9488e0efbf99f327d11bbd7bc055c5b1b.zip
FreeBSD-src-d81208c9488e0efbf99f327d11bbd7bc055c5b1b.tar.gz
Overhaul if_enc(4) and make it loadable in run-time.
Use hhook(9) framework to achieve ability of loading and unloading if_enc(4) kernel module. INET and INET6 code on initialization registers two helper hooks points in the kernel. if_enc(4) module uses these helper hook points and registers its hooks. IPSEC code uses these hhook points to call helper hooks implemented in if_enc(4).
Diffstat (limited to 'sys/netipsec/ipsec_input.c')
-rw-r--r--sys/netipsec/ipsec_input.c74
1 files changed, 22 insertions, 52 deletions
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
index 6a41ad9..063096f 100644
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -43,7 +43,6 @@
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
-#include "opt_enc.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -53,11 +52,12 @@
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.h>
+#include <sys/hhook.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/if_var.h>
-#include <net/pfil.h>
+#include <net/if_enc.h>
#include <net/netisr.h>
#include <net/vnet.h>
@@ -94,10 +94,6 @@
#include <machine/in_cksum.h>
#include <machine/stdarg.h>
-#ifdef DEV_ENC
-#include <net/if_enc.h>
-#endif
-
#define IPSEC_ISTAT(proto, name) do { \
if ((proto) == IPPROTO_ESP) \
@@ -314,6 +310,7 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
int protoff)
{
char buf[INET6_ADDRSTRLEN];
+ struct ipsec_ctx_data ctx;
int prot, af, sproto, isr_prot;
struct ip *ip;
struct m_tag *mtag;
@@ -368,16 +365,10 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
}
prot = ip->ip_p;
-#ifdef DEV_ENC
- if_inc_counter(encif, IFCOUNTER_IPACKETS, 1);
- if_inc_counter(encif, IFCOUNTER_IBYTES, m->m_pkthdr.len);
-
- /* Pass the mbuf to enc0 for bpf and pfil. */
- ipsec_bpf(m, sav, AF_INET, ENC_IN|ENC_BEFORE);
- if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_BEFORE)) != 0)
- return (error);
+ IPSEC_INIT_CTX(&ctx, &m, sav, AF_INET, IPSEC_ENC_BEFORE);
+ if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
+ goto bad;
ip = mtod(m, struct ip *);
-#endif /* DEV_ENC */
/* IP-in-IP encapsulation */
if (prot == IPPROTO_IPIP &&
@@ -501,32 +492,18 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
*/
if (saidx->mode == IPSEC_MODE_TRANSPORT)
prot = IPPROTO_IPIP;
-#ifdef DEV_ENC
- /*
- * Pass the mbuf to enc0 for bpf and pfil.
- */
- if (prot == IPPROTO_IPIP)
- ipsec_bpf(m, sav, AF_INET, ENC_IN|ENC_AFTER);
-#ifdef INET6
- if (prot == IPPROTO_IPV6)
- ipsec_bpf(m, sav, AF_INET6, ENC_IN|ENC_AFTER);
-#endif
-
- if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0)
- return (error);
-#endif /* DEV_ENC */
-
/*
* Re-dispatch via software interrupt.
*/
-
switch (prot) {
case IPPROTO_IPIP:
isr_prot = NETISR_IP;
+ af = AF_INET;
break;
#ifdef INET6
case IPPROTO_IPV6:
isr_prot = NETISR_IPV6;
+ af = AF_INET6;
break;
#endif
default:
@@ -537,6 +514,9 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
goto bad;
}
+ IPSEC_INIT_CTX(&ctx, &m, sav, af, IPSEC_ENC_AFTER);
+ if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
+ goto bad;
error = netisr_queue_src(isr_prot, (uintptr_t)sav->spi, m);
if (error) {
IPSEC_ISTAT(sproto, qfull);
@@ -611,6 +591,7 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
int protoff)
{
char buf[INET6_ADDRSTRLEN];
+ struct ipsec_ctx_data ctx;
int prot, af, sproto;
struct ip6_hdr *ip6;
struct m_tag *mtag;
@@ -658,20 +639,13 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
+ IPSEC_INIT_CTX(&ctx, &m, sav, af, IPSEC_ENC_BEFORE);
+ if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
+ goto bad;
/* Save protocol */
m_copydata(m, protoff, 1, &nxt8);
prot = nxt8;
-#ifdef DEV_ENC
- if_inc_counter(encif, IFCOUNTER_IPACKETS, 1);
- if_inc_counter(encif, IFCOUNTER_IBYTES, m->m_pkthdr.len);
-
- /* Pass the mbuf to enc0 for bpf and pfil. */
- ipsec_bpf(m, sav, AF_INET6, ENC_IN|ENC_BEFORE);
- if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_BEFORE)) != 0)
- return (error);
-#endif /* DEV_ENC */
-
/* IPv6-in-IP encapsulation */
if (prot == IPPROTO_IPV6 &&
saidx->mode != IPSEC_MODE_TRANSPORT) {
@@ -778,20 +752,16 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
key_sa_recordxfer(sav, m);
-#ifdef DEV_ENC
- /*
- * Pass the mbuf to enc0 for bpf and pfil.
- */
+
#ifdef INET
if (prot == IPPROTO_IPIP)
- ipsec_bpf(m, sav, AF_INET, ENC_IN|ENC_AFTER);
+ af = AF_INET;
+ else
#endif
- if (prot == IPPROTO_IPV6)
- ipsec_bpf(m, sav, AF_INET6, ENC_IN|ENC_AFTER);
-
- if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0)
- return (error);
-#endif /* DEV_ENC */
+ af = AF_INET6;
+ IPSEC_INIT_CTX(&ctx, &m, sav, af, IPSEC_ENC_AFTER);
+ if ((error = ipsec_run_hhooks(&ctx, HHOOK_TYPE_IPSEC_IN)) != 0)
+ goto bad;
if (skip == 0) {
/*
* We stripped outer IPv6 header.
OpenPOWER on IntegriCloud