diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-05-22 20:04:13 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2017-05-22 20:04:13 +0000 |
commit | a8acecaa47b45308f1a5eb46637f58e6fcf6562f (patch) | |
tree | 53364281f461e79560f521718426e4b699dbdd68 | |
parent | f9aecd68600b0d676654ad0b4d88d4099a283873 (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.c | 29 | ||||
-rw-r--r-- | sys/netinet/ip_var.h | 3 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 14 |
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); } |