summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-05-22 22:23:12 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-05-22 22:23:12 +0000
commitb376c2299161706e6d307dbc5f27b7112fdf0ed4 (patch)
treef3a2a7441124ad8340fb6627011cf2fd75dd7fbb /sys/netinet
parenta8acecaa47b45308f1a5eb46637f58e6fcf6562f (diff)
Move IPsec forward and local policy check functions to ipsec_input.c
and give them better names. input and OK mikeb@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_input.c103
-rw-r--r--sys/netinet/ip_ipsp.h4
-rw-r--r--sys/netinet/ip_var.h4
-rw-r--r--sys/netinet/ipsec_input.c97
4 files changed, 103 insertions, 105 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 194a51ff19b..f378cf3f174 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.303 2017/05/22 20:04:12 bluhm Exp $ */
+/* $OpenBSD: ip_input.c,v 1.304 2017/05/22 22:23:11 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -442,7 +442,7 @@ ipv4_input(struct mbuf *m)
int rv;
KERNEL_LOCK();
- rv = ip_input_ipsec_fwd_check(m, hlen, AF_INET);
+ rv = ipsec_forward_check(m, hlen, AF_INET);
KERNEL_UNLOCK();
if (rv != 0) {
ipstat_inc(ips_cantforward);
@@ -580,7 +580,7 @@ ip_local(struct mbuf *m, int off, int nxt)
#ifdef IPSEC
if (ipsec_in_use) {
- if (ip_input_ipsec_ours_check(m, off, nxt, AF_INET) != 0) {
+ if (ipsec_local_check(m, off, nxt, AF_INET) != 0) {
ipstat_inc(ips_cantforward);
m_freem(m);
return;
@@ -679,103 +679,6 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
return (match);
}
-#ifdef IPSEC
-int
-ip_input_ipsec_fwd_check(struct mbuf *m, int hlen, int af)
-{
- struct tdb *tdb;
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- int error = 0;
-
- /*
- * IPsec policy check for forwarded packets. Look at
- * inner-most IPsec SA used.
- */
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
- } else
- tdb = NULL;
- ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN, tdb, NULL, 0);
-
- return error;
-}
-
-int
-ip_input_ipsec_ours_check(struct mbuf *m, int hlen, int proto, int af)
-{
- struct tdb *tdb;
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- int error = 0;
-
- /*
- * If it's a protected packet for us, skip the policy check.
- * That's because we really only care about the properties of
- * the protected packet, and not the intermediate versions.
- * While this is not the most paranoid setting, it allows
- * some flexibility in handling nested tunnels (in setting up
- * the policies).
- */
- if ((proto == IPPROTO_ESP) || (proto == IPPROTO_AH) ||
- (proto == IPPROTO_IPCOMP))
- return 0;
-
- /*
- * If the protected packet was tunneled, then we need to
- * verify the protected packet's information, not the
- * external headers. Thus, skip the policy lookup for the
- * external packet, and keep the IPsec information linked on
- * the packet header (the encapsulation routines know how
- * to deal with that).
- */
- if ((proto == IPPROTO_IPV4) || (proto == IPPROTO_IPV6))
- return 0;
-
- /*
- * When processing IPv6 header chains, do not look at the
- * outer header. The inner protocol is relevant and will
- * be checked by the local delivery loop later.
- */
- if ((af == AF_INET6) && ((proto == IPPROTO_DSTOPTS) ||
- (proto == IPPROTO_ROUTING) || (proto == IPPROTO_FRAGMENT)))
- return 0;
-
- /*
- * If the protected packet is TCP or UDP, we'll do the
- * policy check in the respective input routine, so we can
- * check for bypass sockets.
- */
- if ((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP))
- return 0;
-
- /*
- * IPsec policy check for local-delivery packets. Look at the
- * inner-most SA that protected the packet. This is in fact
- * a bit too restrictive (it could end up causing packets to
- * be dropped that semantically follow the policy, e.g., in
- * certain SA-bundle configurations); but the alternative is
- * very complicated (and requires keeping track of what
- * kinds of tunneling headers have been seen in-between the
- * IPsec headers), and I don't think we lose much functionality
- * that's needed in the real world (who uses bundles anyway ?).
- */
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- if (mtag) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
- tdbi->proto);
- } else
- tdb = NULL;
- ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN,
- tdb, NULL, 0);
-
- return error;
-}
-#endif /* IPSEC */
-
/*
* Take incoming datagram fragment and try to
* reassemble it into whole datagram. If a chain for
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 44496a53bf4..43bf0f8b66a 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.181 2017/05/18 10:56:45 bluhm Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.182 2017/05/22 22:23:11 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -552,6 +552,8 @@ int ipsec_delete_policy(struct ipsec_policy *);
ssize_t ipsec_hdrsz(struct tdb *);
void ipsec_adjust_mtu(struct mbuf *, u_int32_t);
struct ipsec_acquire *ipsec_get_acquire(u_int32_t);
+int ipsec_forward_check(struct mbuf *, int, int);
+int ipsec_local_check(struct mbuf *, int, int, int);
#endif /* _KERNEL */
#endif /* _NETINET_IPSP_H_ */
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 0bd1152bcde..9653c1de27b 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.74 2017/05/22 20:04:12 bluhm Exp $ */
+/* $OpenBSD: ip_var.h,v 1.75 2017/05/22 22:23:11 bluhm Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -251,8 +251,6 @@ void ipintr(void);
void ipv4_input(struct mbuf *);
void ip_local(struct mbuf *, int, int);
void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int);
-int ip_input_ipsec_fwd_check(struct mbuf *, int, int);
-int ip_input_ipsec_ours_check(struct mbuf *, int, int, int);
int rip_ctloutput(int, struct socket *, int, int, struct mbuf *);
void rip_init(void);
int rip_input(struct mbuf **, int *, int, int);
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index 08efc2d4c60..8c981aa722a 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.152 2017/05/16 12:24:02 mpi Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.153 2017/05/22 22:23:11 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -1013,3 +1013,98 @@ ipcomp6_input(struct mbuf **mp, int *offp, int proto, int af)
return IPPROTO_DONE;
}
#endif /* INET6 */
+
+int
+ipsec_forward_check(struct mbuf *m, int hlen, int af)
+{
+ struct tdb *tdb;
+ struct tdb_ident *tdbi;
+ struct m_tag *mtag;
+ int error = 0;
+
+ /*
+ * IPsec policy check for forwarded packets. Look at
+ * inner-most IPsec SA used.
+ */
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
+ if (mtag != NULL) {
+ tdbi = (struct tdb_ident *)(mtag + 1);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
+ } else
+ tdb = NULL;
+ ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN, tdb, NULL, 0);
+
+ return error;
+}
+
+int
+ipsec_local_check(struct mbuf *m, int hlen, int proto, int af)
+{
+ struct tdb *tdb;
+ struct tdb_ident *tdbi;
+ struct m_tag *mtag;
+ int error = 0;
+
+ /*
+ * If it's a protected packet for us, skip the policy check.
+ * That's because we really only care about the properties of
+ * the protected packet, and not the intermediate versions.
+ * While this is not the most paranoid setting, it allows
+ * some flexibility in handling nested tunnels (in setting up
+ * the policies).
+ */
+ if ((proto == IPPROTO_ESP) || (proto == IPPROTO_AH) ||
+ (proto == IPPROTO_IPCOMP))
+ return 0;
+
+ /*
+ * If the protected packet was tunneled, then we need to
+ * verify the protected packet's information, not the
+ * external headers. Thus, skip the policy lookup for the
+ * external packet, and keep the IPsec information linked on
+ * the packet header (the encapsulation routines know how
+ * to deal with that).
+ */
+ if ((proto == IPPROTO_IPV4) || (proto == IPPROTO_IPV6))
+ return 0;
+
+ /*
+ * When processing IPv6 header chains, do not look at the
+ * outer header. The inner protocol is relevant and will
+ * be checked by the local delivery loop later.
+ */
+ if ((af == AF_INET6) && ((proto == IPPROTO_DSTOPTS) ||
+ (proto == IPPROTO_ROUTING) || (proto == IPPROTO_FRAGMENT)))
+ return 0;
+
+ /*
+ * If the protected packet is TCP or UDP, we'll do the
+ * policy check in the respective input routine, so we can
+ * check for bypass sockets.
+ */
+ if ((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP))
+ return 0;
+
+ /*
+ * IPsec policy check for local-delivery packets. Look at the
+ * inner-most SA that protected the packet. This is in fact
+ * a bit too restrictive (it could end up causing packets to
+ * be dropped that semantically follow the policy, e.g., in
+ * certain SA-bundle configurations); but the alternative is
+ * very complicated (and requires keeping track of what
+ * kinds of tunneling headers have been seen in-between the
+ * IPsec headers), and I don't think we lose much functionality
+ * that's needed in the real world (who uses bundles anyway ?).
+ */
+ mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
+ if (mtag) {
+ tdbi = (struct tdb_ident *)(mtag + 1);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
+ tdbi->proto);
+ } else
+ tdb = NULL;
+ ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN,
+ tdb, NULL, 0);
+
+ return error;
+}