Hi,

ipv4_input() checks the IPsec policy for forwarding and local
delivery.  Such code is missing in IPv6, the behavior is different.

Start using the forwarding check also in ip6_input().  While there
avoid an ugly #ifdef in ipv4_input().

ok?

bluhm

Index: netinet/ip_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.298
diff -u -p -r1.298 ip_input.c
--- netinet/ip_input.c  19 Apr 2017 15:21:54 -0000      1.298
+++ netinet/ip_input.c  10 May 2017 23:55:42 -0000
@@ -130,7 +130,6 @@ 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_fwd_check(struct mbuf *, int);
 int    ip_input_ipsec_ours_check(struct mbuf *, int);
 #endif /* IPSEC */
        
@@ -241,9 +240,6 @@ ipv4_input(struct mbuf *m)
        struct rtentry  *rt = NULL;
        struct ip       *ip;
        int hlen, len;
-#if defined(MROUTING) || defined(IPSEC)
-       int rv;
-#endif
        in_addr_t pfrdr = 0;
 
        ifp = if_get(m->m_pkthdr.ph_ifidx);
@@ -377,6 +373,8 @@ ipv4_input(struct mbuf *m)
 
 #ifdef MROUTING
                if (ipmforwarding && ip_mrouter[ifp->if_rdomain]) {
+                       int rv;
+
                        if (m->m_flags & M_EXT) {
                                if ((m = m_pullup(m, hlen)) == NULL) {
                                        ipstat_inc(ips_toosmall);
@@ -444,8 +442,10 @@ ipv4_input(struct mbuf *m)
        }
 #ifdef IPSEC
        if (ipsec_in_use) {
+               int rv;
+
                KERNEL_LOCK();
-               rv = ip_input_ipsec_fwd_check(m, hlen);
+               rv = ip_input_ipsec_fwd_check(m, hlen, AF_INET);
                KERNEL_UNLOCK();
                if (rv != 0) {
                        ipstat_inc(ips_cantforward);
@@ -675,7 +675,7 @@ in_ouraddr(struct mbuf *m, struct ifnet 
 
 #ifdef IPSEC
 int
-ip_input_ipsec_fwd_check(struct mbuf *m, int hlen)
+ip_input_ipsec_fwd_check(struct mbuf *m, int hlen, int af)
 {
        struct tdb *tdb;
        struct tdb_ident *tdbi;
@@ -692,8 +692,7 @@ ip_input_ipsec_fwd_check(struct mbuf *m,
                tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
        } else
                tdb = NULL;
-       ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN, tdb, NULL,
-           0);
+       ipsp_spd_lookup(m, af, hlen, &error, IPSP_DIRECTION_IN, tdb, NULL, 0);
 
        return error;
 }
Index: netinet/ip_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.71
diff -u -p -r1.71 ip_var.h
--- netinet/ip_var.h    14 Apr 2017 20:46:31 -0000      1.71
+++ netinet/ip_var.h    10 May 2017 23:12:25 -0000
@@ -250,6 +250,7 @@ void         ip_savecontrol(struct inpcb *, str
 void    ipintr(void);
 void    ipv4_input(struct mbuf *);
 void    ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int);
+int     ip_input_ipsec_fwd_check(struct mbuf *, int, int);
 int     rip_ctloutput(int, struct socket *, int, int, struct mbuf *);
 void    rip_init(void);
 int     rip_input(struct mbuf **, int *, int, int);
Index: netinet6/ip6_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.184
diff -u -p -r1.184 ip6_input.c
--- netinet6/ip6_input.c        8 May 2017 08:46:39 -0000       1.184
+++ netinet6/ip6_input.c        10 May 2017 23:21:00 -0000
@@ -470,6 +470,24 @@ ip6_input(struct mbuf *m)
                goto out;
        }
 
+#ifdef IPSEC
+       if (ipsec_in_use) {
+               int rv;
+
+               KERNEL_LOCK();
+               rv = ip_input_ipsec_fwd_check(m, off, AF_INET6);
+               KERNEL_UNLOCK();
+               if (rv != 0) {
+                       ipstat_inc(ips_cantforward);
+                       goto bad;
+               }
+               /*
+                * Fall through, forward packet. Outbound IPsec policy
+                * checking will occur in ip6_forward().
+                */
+       }
+#endif /* IPSEC */
+
        ip6_forward(m, rt, srcrt);
        if_put(ifp);
        return;

Reply via email to