summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-05-22 20:04:13 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-05-22 20:04:13 +0000
commita8acecaa47b45308f1a5eb46637f58e6fcf6562f (patch)
tree53364281f461e79560f521718426e4b699dbdd68
parentf9aecd68600b0d676654ad0b4d88d4099a283873 (diff)
Use the IPsec policy check from IPv4 also when doing local delivery
in ip6_local() to our IPv6 stack. OK mikeb@
-rw-r--r--sys/netinet/ip_input.c29
-rw-r--r--sys/netinet/ip_var.h3
-rw-r--r--sys/netinet6/ip6_input.c14
3 files changed, 32 insertions, 14 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index cb27fcede64..194a51ff19b 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.302 2017/05/16 12:24:01 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.303 2017/05/22 20:04:12 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -129,9 +129,6 @@ static struct mbuf_queue ipsend_mq;
void ip_ours(struct mbuf *);
int ip_dooptions(struct mbuf *, struct ifnet *);
int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
-#ifdef IPSEC
-int ip_input_ipsec_ours_check(struct mbuf *, int);
-#endif /* IPSEC */
static void ip_send_dispatch(void *);
static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, &ipsend_mq);
@@ -583,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) != 0) {
+ if (ip_input_ipsec_ours_check(m, off, nxt, AF_INET) != 0) {
ipstat_inc(ips_cantforward);
m_freem(m);
return;
@@ -707,9 +704,8 @@ ip_input_ipsec_fwd_check(struct mbuf *m, int hlen, int af)
}
int
-ip_input_ipsec_ours_check(struct mbuf *m, int hlen)
+ip_input_ipsec_ours_check(struct mbuf *m, int hlen, int proto, int af)
{
- struct ip *ip = mtod(m, struct ip *);
struct tdb *tdb;
struct tdb_ident *tdbi;
struct m_tag *mtag;
@@ -723,8 +719,8 @@ ip_input_ipsec_ours_check(struct mbuf *m, int hlen)
* some flexibility in handling nested tunnels (in setting up
* the policies).
*/
- if ((ip->ip_p == IPPROTO_ESP) || (ip->ip_p == IPPROTO_AH) ||
- (ip->ip_p == IPPROTO_IPCOMP))
+ if ((proto == IPPROTO_ESP) || (proto == IPPROTO_AH) ||
+ (proto == IPPROTO_IPCOMP))
return 0;
/*
@@ -735,7 +731,16 @@ ip_input_ipsec_ours_check(struct mbuf *m, int hlen)
* the packet header (the encapsulation routines know how
* to deal with that).
*/
- if ((ip->ip_p == IPPROTO_IPIP) || (ip->ip_p == IPPROTO_IPV6))
+ 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;
/*
@@ -743,7 +748,7 @@ ip_input_ipsec_ours_check(struct mbuf *m, int hlen)
* policy check in the respective input routine, so we can
* check for bypass sockets.
*/
- if ((ip->ip_p == IPPROTO_TCP) || (ip->ip_p == IPPROTO_UDP))
+ if ((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP))
return 0;
/*
@@ -764,7 +769,7 @@ ip_input_ipsec_ours_check(struct mbuf *m, int hlen)
tdbi->proto);
} else
tdb = NULL;
- ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN,
+ ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN,
tdb, NULL, 0);
return error;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 4bc5998a08b..0bd1152bcde 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.73 2017/05/12 23:05:58 bluhm Exp $ */
+/* $OpenBSD: ip_var.h,v 1.74 2017/05/22 20:04:12 bluhm Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -252,6 +252,7 @@ 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/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 79371e89813..2170e06fc00 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.186 2017/05/12 14:04:09 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.187 2017/05/22 20:04:12 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -550,6 +550,18 @@ ip6_local(struct mbuf *m, int off, int nxt)
goto bad;
}
+#ifdef IPSEC
+ if (ipsec_in_use) {
+ if (ip_input_ipsec_ours_check(m, off, nxt, AF_INET6)
+ != 0) {
+ ipstat_inc(ip6s_cantforward);
+ m_freem(m);
+ return;
+ }
+ }
+ /* Otherwise, just fall through and deliver the packet */
+#endif /* IPSEC */
+
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt,
AF_INET6);
}